aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
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
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')
-rw-r--r--mps/code/action.c12
-rw-r--r--mps/code/amcss.c138
-rw-r--r--mps/code/amcsshe.c72
-rw-r--r--mps/code/amcssth.c98
-rw-r--r--mps/code/amsss.c107
-rw-r--r--mps/code/amssshe.c6
-rw-r--r--mps/code/apss.c40
-rw-r--r--mps/code/arena.c2
-rw-r--r--mps/code/arenacl.c1
-rw-r--r--mps/code/arenavm.c1
-rw-r--r--mps/code/arenavmx.c32
-rw-r--r--mps/code/assert.c71
-rw-r--r--mps/code/bt.c19
-rw-r--r--mps/code/bt.h75
-rw-r--r--mps/code/bttest.c1
-rw-r--r--mps/code/cbs.c1
-rw-r--r--mps/code/check.h88
-rw-r--r--mps/code/comm.gmk41
-rw-r--r--mps/code/commpost.nmk8
-rw-r--r--mps/code/config.h91
-rw-r--r--mps/code/dbgpool.c333
-rw-r--r--mps/code/dbgpool.h12
-rw-r--r--mps/code/dbgpooli.c54
-rw-r--r--mps/code/eventcnv.c1
-rw-r--r--mps/code/eventgen.h1
-rw-r--r--mps/code/finalcv.c70
-rw-r--r--mps/code/fmtdy.c40
-rw-r--r--mps/code/fmthe.c16
-rw-r--r--mps/code/fmthe.h1
-rw-r--r--mps/code/format.c19
-rw-r--r--mps/code/gathconf.bat37
-rw-r--r--mps/code/global.c37
-rw-r--r--mps/code/hqbuild/data/cv_alpha.txt1
-rw-r--r--mps/code/hqbuild/data/cv_x86.txt3
-rw-r--r--mps/code/hqbuild/tools/hqbuild20
-rw-r--r--mps/code/hqbuild/tools/hqbuild.bat12
-rw-r--r--mps/code/lo.h3
-rw-r--r--mps/code/locbwcss.c206
-rw-r--r--mps/code/locus.c12
-rw-r--r--mps/code/locusss.c248
-rw-r--r--mps/code/makefile.jam291
-rw-r--r--mps/code/message.c1
-rw-r--r--mps/code/misc.h28
-rw-r--r--mps/code/mpm.c19
-rw-r--r--mps/code/mpm.h61
-rw-r--r--mps/code/mpmss.c54
-rw-r--r--mps/code/mpmst.h2
-rw-r--r--mps/code/mpmtypes.h21
-rw-r--r--mps/code/mps.h54
-rw-r--r--mps/code/mpscams.h2
-rw-r--r--mps/code/mpsi.c72
-rw-r--r--mps/code/mpsicv.c43
-rw-r--r--mps/code/mpsiw3.c7
-rw-r--r--mps/code/mpslib.h4
-rw-r--r--mps/code/mpsliban.c6
-rw-r--r--mps/code/mpstd.h72
-rw-r--r--mps/code/mpsw3.h4
-rw-r--r--mps/code/pool.c24
-rw-r--r--mps/code/poolabs.c14
-rw-r--r--mps/code/poolamc.c18
-rw-r--r--mps/code/poolams.c484
-rw-r--r--mps/code/poolams.h94
-rw-r--r--mps/code/poolamsi.c28
-rw-r--r--mps/code/poolawl.c1
-rw-r--r--mps/code/poolmfs.h4
-rw-r--r--mps/code/poolmrg.c94
-rw-r--r--mps/code/poolmrg.h11
-rw-r--r--mps/code/poolmv.c37
-rw-r--r--mps/code/poolmv.h6
-rw-r--r--mps/code/poolmvff.c75
-rw-r--r--mps/code/poolncv.c4
-rw-r--r--mps/code/poolsnc.c1
-rw-r--r--mps/code/proddw.bat41
-rw-r--r--mps/code/protli.c1
-rw-r--r--mps/code/protocol.c1
-rw-r--r--mps/code/protso.c1
-rw-r--r--mps/code/reserv.c4
-rw-r--r--mps/code/ring.c1
-rw-r--r--mps/code/ring.h3
-rw-r--r--mps/code/sacss.c25
-rw-r--r--mps/code/seg.c6
-rw-r--r--mps/code/segsmss.c11
-rw-r--r--mps/code/spi3.asm27
-rw-r--r--mps/code/spi3.c24
-rw-r--r--mps/code/splay.c160
-rw-r--r--mps/code/ss.h3
-rw-r--r--mps/code/sslii3.c1
-rw-r--r--mps/code/sssos8.s3
-rw-r--r--mps/code/sssus8.c63
-rw-r--r--mps/code/sssus8.s4
-rw-r--r--mps/code/sus8lc.gmk14
-rw-r--r--mps/code/teletest.c1
-rw-r--r--mps/code/testlib.c31
-rw-r--r--mps/code/testlib.h20
-rw-r--r--mps/code/trace.c7
-rw-r--r--mps/code/tract.c1
-rw-r--r--mps/code/tract.h9
-rw-r--r--mps/code/version.c12
-rw-r--r--mps/code/vman.c2
-rw-r--r--mps/code/vmso.c54
-rw-r--r--mps/code/w3almv.nmk14
-rw-r--r--mps/code/w3i3mv.nmk16
-rw-r--r--mps/code/w3ppmv.nmk12
103 files changed, 2818 insertions, 1420 deletions
diff --git a/mps/code/action.c b/mps/code/action.c
deleted file mode 100644
index 32c3a933f27..00000000000
--- a/mps/code/action.c
+++ /dev/null
@@ -1,12 +0,0 @@
1/* impl.c.action: STRATEGIC ACTION
2 *
3 * Copyright (c) 2001 Ravenbrook Limited.
4 * $Id$
5 */
6
7#include "mpm.h"
8
9SRCID(action, "$Id$");
10
11
12/* All contents obsolete. */
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);
diff --git a/mps/code/amcsshe.c b/mps/code/amcsshe.c
index bc5de2f184c..6486f416252 100644
--- a/mps/code/amcsshe.c
+++ b/mps/code/amcsshe.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 "fmthe.h" 8#include "fmthe.h"
@@ -18,8 +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)1400*1024) 23#define headerFACTOR ((float)(20 + headerSIZE) / 20)
24/* headerFACTOR measures how much larger objects are compared to fmtdy. */
25#define testArenaSIZE ((size_t)(1000*headerFACTOR)*1024)
26#define gen1SIZE ((size_t)150*headerFACTOR)
27#define gen2SIZE ((size_t)170*headerFACTOR)
23#define avLEN 3 28#define avLEN 3
24#define exactRootsCOUNT 200 29#define exactRootsCOUNT 200
25#define ambigRootsCOUNT 50 30#define ambigRootsCOUNT 50
@@ -32,7 +37,7 @@
32/* testChain -- generation parameters for the test */ 37/* testChain -- generation parameters for the test */
33 38
34static mps_gen_param_s testChain[genCOUNT] = { 39static mps_gen_param_s testChain[genCOUNT] = {
35 { 210, 0.85 }, { 248, 0.45 } }; 40 { gen1SIZE, 0.85 }, { gen2SIZE, 0.45 } };
36 41
37 42
38/* objNULL needs to be odd so that it's ignored in exactRoots. */ 43/* objNULL needs to be odd so that it's ignored in exactRoots. */
@@ -68,6 +73,36 @@ static mps_addr_t make(void)
68} 73}
69 74
70 75
76/* report - report statistics from any terminated GCs */
77
78static void report(mps_arena_t arena)
79{
80 mps_message_t message;
81 static int nCollections = 0;
82
83 while (mps_message_get(&message, arena, mps_message_type_gc())) {
84 size_t live, condemned, not_condemned;
85
86 live = mps_message_gc_live_size(arena, message);
87 condemned = mps_message_gc_condemned_size(arena, message);
88 not_condemned = mps_message_gc_not_condemned_size(arena, message);
89
90 printf("\nCollection %d finished:\n", ++nCollections);
91 printf("live %lu\n", (unsigned long)live);
92 printf("condemned %lu\n", (unsigned long)condemned);
93 printf("not_condemned %lu\n", (unsigned long)not_condemned);
94
95 mps_message_discard(arena, message);
96
97 if (condemned > (gen1SIZE + gen2SIZE + (size_t)128) * 1024)
98 /* When condemned size is larger than could happen in a gen 2
99 * collection (discounting ramps, natch), guess that was a dynamic
100 * collection, and reset the commit limit, so it doesn't run out. */
101 die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "set limit");
102 }
103}
104
105
71/* test -- the body of the test */ 106/* test -- the body of the test */
72 107
73static void *test(void *arg, size_t s) 108static void *test(void *arg, size_t s)
@@ -98,7 +133,7 @@ static void *test(void *arg, size_t s)
98 for(i = 0; i < exactRootsCOUNT; ++i) 133 for(i = 0; i < exactRootsCOUNT; ++i)
99 exactRoots[i] = objNULL; 134 exactRoots[i] = objNULL;
100 for(i = 0; i < ambigRootsCOUNT; ++i) 135 for(i = 0; i < ambigRootsCOUNT; ++i)
101 ambigRoots[i] = (mps_addr_t)rnd(); 136 ambigRoots[i] = rnd_addr();
102 137
103 die(mps_root_create_table_masked(&exactRoot, arena, 138 die(mps_root_create_table_masked(&exactRoot, arena,
104 MPS_RANK_EXACT, (mps_rm_t)0, 139 MPS_RANK_EXACT, (mps_rm_t)0,
@@ -119,11 +154,11 @@ static void *test(void *arg, size_t s)
119 154
120 collections = 0; 155 collections = 0;
121 rampSwitch = rampSIZE; 156 rampSwitch = rampSIZE;
122 mps_ap_alloc_pattern_begin(ap, ramp); 157 die(mps_ap_alloc_pattern_begin(ap, ramp), "pattern begin (ap)");
123 mps_ap_alloc_pattern_begin(busy_ap, ramp); 158 die(mps_ap_alloc_pattern_begin(busy_ap, ramp), "pattern begin (busy_ap)");
124 ramping = 1; 159 ramping = 1;
125 objs = 0; 160 objs = 0;
126 while(collections < collectionsCOUNT) { 161 while (collections < collectionsCOUNT) {
127 unsigned long c; 162 unsigned long c;
128 size_t r; 163 size_t r;
129 164
@@ -132,15 +167,20 @@ static void *test(void *arg, size_t s)
132 if (collections != c) { 167 if (collections != c) {
133 collections = c; 168 collections = c;
134 printf("\nCollection %lu, %lu objects.\n", c, objs); 169 printf("\nCollection %lu, %lu objects.\n", c, objs);
135 for(r = 0; r < exactRootsCOUNT; ++r) { 170 report(arena);
171 for (r = 0; r < exactRootsCOUNT; ++r) {
136 if (exactRoots[r] != objNULL) 172 if (exactRoots[r] != objNULL)
137 die(HeaderFormatCheck(exactRoots[r]), "wrapper check"); 173 die(HeaderFormatCheck(exactRoots[r]), "wrapper check");
138 } 174 }
139 if (collections == rampSwitch) { 175 if (collections == rampSwitch) {
176 int begin_ramp = !ramping
177 || /* Every other time, switch back immediately. */ (collections & 1);
178
140 rampSwitch += rampSIZE; 179 rampSwitch += rampSIZE;
141 if (ramping) { 180 if (ramping) {
142 mps_ap_alloc_pattern_end(ap, ramp); 181 die(mps_ap_alloc_pattern_end(ap, ramp), "pattern end (ap)");
143 mps_ap_alloc_pattern_end(busy_ap, ramp); 182 die(mps_ap_alloc_pattern_end(busy_ap, ramp), "pattern end (busy_ap)");
183 ramping = 0;
144 /* kill half of the roots */ 184 /* kill half of the roots */
145 for(i = 0; i < exactRootsCOUNT; i += 2) { 185 for(i = 0; i < exactRootsCOUNT; i += 2) {
146 if (exactRoots[i] != objNULL) { 186 if (exactRoots[i] != objNULL) {
@@ -148,12 +188,12 @@ static void *test(void *arg, size_t s)
148 exactRoots[i] = objNULL; 188 exactRoots[i] = objNULL;
149 } 189 }
150 } 190 }
151 /* Every other time, switch back immediately. */
152 if (collections & 1) ramping = 0;
153 } 191 }
154 if (!ramping) { 192 if (begin_ramp) {
155 mps_ap_alloc_pattern_begin(ap, ramp); 193 die(mps_ap_alloc_pattern_begin(ap, ramp),
156 mps_ap_alloc_pattern_begin(busy_ap, ramp); 194 "pattern rebegin (ap)");
195 die(mps_ap_alloc_pattern_begin(busy_ap, ramp),
196 "pattern rebegin (busy_ap)");
157 ramping = 1; 197 ramping = 1;
158 } 198 }
159 } 199 }
@@ -187,6 +227,7 @@ static void *test(void *arg, size_t s)
187 *(int*)busy_init = -1; /* check that the buffer is still there */ 227 *(int*)busy_init = -1; /* check that the buffer is still there */
188 228
189 if (objs % 1024 == 0) { 229 if (objs % 1024 == 0) {
230 report(arena);
190 putchar('.'); 231 putchar('.');
191 fflush(stdout); 232 fflush(stdout);
192 } 233 }
@@ -218,6 +259,7 @@ int main(int argc, char **argv)
218 259
219 die(mps_arena_create(&arena, mps_arena_class_vm(), 3*testArenaSIZE), 260 die(mps_arena_create(&arena, mps_arena_class_vm(), 3*testArenaSIZE),
220 "arena_create\n"); 261 "arena_create\n");
262 mps_message_type_enable(arena, mps_message_type_gc());
221 die(mps_arena_commit_limit_set(arena, testArenaSIZE), "set limit"); 263 die(mps_arena_commit_limit_set(arena, testArenaSIZE), "set limit");
222 die(mps_thread_reg(&thread, arena), "thread_reg"); 264 die(mps_thread_reg(&thread, arena), "thread_reg");
223 mps_tramp(&r, test, arena, 0); 265 mps_tramp(&r, test, arena, 0);
diff --git a/mps/code/amcssth.c b/mps/code/amcssth.c
index 1ace33d35c7..96913c9c2ee 100644
--- a/mps/code/amcssth.c
+++ b/mps/code/amcssth.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 * .posix: This is Posix only. 7 * .posix: This is Posix only.
7 */ 8 */
@@ -12,21 +13,18 @@
12#include "testlib.h" 13#include "testlib.h"
13#include "mpscamc.h" 14#include "mpscamc.h"
14#include "mpsavm.h" 15#include "mpsavm.h"
15#include "mpstd.h"
16#ifdef MPS_OS_W3
17#include "mpsw3.h"
18#endif
19#include "mps.h"
20#include <stdlib.h> 16#include <stdlib.h>
21#include <string.h> 17#include <string.h>
22#include <pthread.h> 18#include <pthread.h>
23#include <time.h> 19#include <time.h>
24 20
25 21
26/* 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. */
27#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)
28#define avLEN 3 26#define avLEN 3
29#define exactRootsCOUNT 200 27#define exactRootsCOUNT 180
30#define ambigRootsCOUNT 50 28#define ambigRootsCOUNT 50
31#define genCOUNT 2 29#define genCOUNT 2
32#define collectionsCOUNT 37 30#define collectionsCOUNT 37
@@ -36,7 +34,7 @@
36/* testChain -- generation parameters for the test */ 34/* testChain -- generation parameters for the test */
37 35
38static mps_gen_param_s testChain[genCOUNT] = { 36static mps_gen_param_s testChain[genCOUNT] = {
39 { 150, 0.85 }, { 170, 0.45 } }; 37 { gen1SIZE, 0.85 }, { gen2SIZE, 0.45 } };
40 38
41 39
42/* 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. */
@@ -54,6 +52,38 @@ mps_root_t exactRoot, ambigRoot;
54unsigned long objs = 0; 52unsigned long objs = 0;
55 53
56 54
55/* report - report statistics from any terminated GCs */
56
57static void report(mps_arena_t arena)
58{
59 mps_message_t message;
60 static int nCollections = 0;
61
62 while (mps_message_get(&message, arena, mps_message_type_gc())) {
63 size_t live, condemned, not_condemned;
64
65 live = mps_message_gc_live_size(arena, message);
66 condemned = mps_message_gc_condemned_size(arena, message);
67 not_condemned = mps_message_gc_not_condemned_size(arena, message);
68
69 printf("\nCollection %d finished:\n", ++nCollections);
70 printf("live %lu\n", (unsigned long)live);
71 printf("condemned %lu\n", (unsigned long)condemned);
72 printf("not_condemned %lu\n", (unsigned long)not_condemned);
73
74 mps_message_discard(arena, message);
75
76 if (condemned > (gen1SIZE + gen2SIZE + (size_t)128) * 1024)
77 /* When condemned size is larger than could happen in a gen 2
78 * collection (discounting ramps, natch), guess that was a dynamic
79 * collection, and reset the commit limit, so it doesn't run out. */
80 die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "set limit");
81 }
82}
83
84
85/* make -- create one new object */
86
57static mps_addr_t make(mps_ap_t ap) 87static mps_addr_t make(mps_ap_t ap)
58{ 88{
59 size_t length = rnd() % (2*avLEN); 89 size_t length = rnd() % (2*avLEN);
@@ -74,11 +104,14 @@ static mps_addr_t make(mps_ap_t ap)
74} 104}
75 105
76 106
77static void test_stepper(mps_addr_t object, void *p, size_t s) 107/* test_stepper -- stepping function for walk */
108
109static void test_stepper(mps_addr_t object, mps_fmt_t fmt, mps_pool_t pol,
110 void *p, size_t s)
78{ 111{
79 (*(unsigned long *)p)++; 112 testlib_unused(object); testlib_unused(fmt); testlib_unused(pol);
80 testlib_unused(s); 113 testlib_unused(s);
81 testlib_unused(object); 114 (*(unsigned long *)p)++;
82} 115}
83 116
84 117
@@ -97,7 +130,7 @@ static void init(void)
97 for(i = 0; i < exactRootsCOUNT; ++i) 130 for(i = 0; i < exactRootsCOUNT; ++i)
98 exactRoots[i] = objNULL; 131 exactRoots[i] = objNULL;
99 for(i = 0; i < ambigRootsCOUNT; ++i) 132 for(i = 0; i < ambigRootsCOUNT; ++i)
100 ambigRoots[i] = (mps_addr_t)rnd(); 133 ambigRoots[i] = rnd_addr();
101 134
102 die(mps_root_create_table_masked(&exactRoot, arena, 135 die(mps_root_create_table_masked(&exactRoot, arena,
103 MPS_RANK_EXACT, (mps_rm_t)0, 136 MPS_RANK_EXACT, (mps_rm_t)0,
@@ -171,10 +204,10 @@ static void *test(void *arg, size_t s)
171 204
172 collections = 0; 205 collections = 0;
173 rampSwitch = rampSIZE; 206 rampSwitch = rampSIZE;
174 mps_ap_alloc_pattern_begin(ap, ramp); 207 die(mps_ap_alloc_pattern_begin(ap, ramp), "pattern begin (ap)");
175 mps_ap_alloc_pattern_begin(busy_ap, ramp); 208 die(mps_ap_alloc_pattern_begin(busy_ap, ramp), "pattern begin (busy_ap)");
176 ramping = 1; 209 ramping = 1;
177 while(collections < collectionsCOUNT) { 210 while (collections < collectionsCOUNT) {
178 unsigned long c; 211 unsigned long c;
179 size_t r; 212 size_t r;
180 213
@@ -182,23 +215,29 @@ static void *test(void *arg, size_t s)
182 215
183 if (collections != c) { 216 if (collections != c) {
184 collections = c; 217 collections = c;
185 printf("\nCollection %lu, %lu objects.\n", 218 printf("\nCollection %lu started, %lu objects.\n", c, objs);
186 c, objs); 219 report(arena);
187 for(r = 0; r < exactRootsCOUNT; ++r) 220
188 cdie(exactRoots[r] == objNULL || dylan_check(exactRoots[r]), 221 for (i = 0; i < exactRootsCOUNT; ++i)
222 cdie(exactRoots[i] == objNULL || dylan_check(exactRoots[i]),
189 "all roots check"); 223 "all roots check");
224
190 if (collections == collectionsCOUNT / 2) { 225 if (collections == collectionsCOUNT / 2) {
191 unsigned long object_count = 0; 226 unsigned long object_count = 0;
192 mps_arena_park(arena); 227 mps_arena_park(arena);
193 mps_amc_apply(pool, test_stepper, &object_count, 0); 228 mps_arena_formatted_objects_walk(arena, test_stepper, &object_count, 0);
194 mps_arena_release(arena); 229 mps_arena_release(arena);
195 printf("mps_amc_apply stepped on %lu objects.\n", object_count); 230 printf("stepped on %lu objects.\n", object_count);
196 } 231 }
197 if (collections == rampSwitch) { 232 if (collections == rampSwitch) {
233 int begin_ramp = !ramping
234 || /* Every other time, switch back immediately. */ (collections & 1);
235
198 rampSwitch += rampSIZE; 236 rampSwitch += rampSIZE;
199 if (ramping) { 237 if (ramping) {
200 mps_ap_alloc_pattern_end(ap, ramp); 238 die(mps_ap_alloc_pattern_end(ap, ramp), "pattern end (ap)");
201 mps_ap_alloc_pattern_end(busy_ap, ramp); 239 die(mps_ap_alloc_pattern_end(busy_ap, ramp), "pattern end (busy_ap)");
240 ramping = 0;
202 /* kill half of the roots */ 241 /* kill half of the roots */
203 for(i = 0; i < exactRootsCOUNT; i += 2) { 242 for(i = 0; i < exactRootsCOUNT; i += 2) {
204 if (exactRoots[i] != objNULL) { 243 if (exactRoots[i] != objNULL) {
@@ -206,12 +245,12 @@ static void *test(void *arg, size_t s)
206 exactRoots[i] = objNULL; 245 exactRoots[i] = objNULL;
207 } 246 }
208 } 247 }
209 /* Every other time, switch back immediately. */
210 if (collections & 1) ramping = 0;
211 } 248 }
212 if (!ramping) { 249 if (begin_ramp) {
213 mps_ap_alloc_pattern_begin(ap, ramp); 250 die(mps_ap_alloc_pattern_begin(ap, ramp),
214 mps_ap_alloc_pattern_begin(busy_ap, ramp); 251 "pattern rebegin (ap)");
252 die(mps_ap_alloc_pattern_begin(busy_ap, ramp),
253 "pattern rebegin (busy_ap)");
215 ramping = 1; 254 ramping = 1;
216 } 255 }
217 } 256 }
@@ -223,6 +262,7 @@ static void *test(void *arg, size_t s)
223 *(int*)busy_init = -1; /* check that the buffer is still there */ 262 *(int*)busy_init = -1; /* check that the buffer is still there */
224 263
225 if (objs % 1024 == 0) { 264 if (objs % 1024 == 0) {
265 report(arena);
226 putchar('.'); 266 putchar('.');
227 fflush(stdout); 267 fflush(stdout);
228 } 268 }
@@ -278,6 +318,7 @@ int main(int argc, char **argv)
278 318
279 die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), 319 die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE),
280 "arena_create"); 320 "arena_create");
321 mps_message_type_enable(arena, mps_message_type_gc());
281 init(); 322 init();
282 die(mps_thread_reg(&thread, arena), "thread_reg"); 323 die(mps_thread_reg(&thread, arena), "thread_reg");
283 pthread_create(&pthread1, NULL, fooey, (void *)&childIsFinished); 324 pthread_create(&pthread1, NULL, fooey, (void *)&childIsFinished);
@@ -290,6 +331,7 @@ int main(int argc, char **argv)
290 } 331 }
291 332
292 finish(); 333 finish();
334 report(arena);
293 mps_arena_destroy(arena); 335 mps_arena_destroy(arena);
294 336
295 fflush(stdout); /* synchronize */ 337 fflush(stdout); /* synchronize */
diff --git a/mps/code/amsss.c b/mps/code/amsss.c
index 2008334248e..a650c65264e 100644
--- a/mps/code/amsss.c
+++ b/mps/code/amsss.c
@@ -2,11 +2,11 @@
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 * .design: Adapted from amcss.c, but not counting collections, just 7 * .design: Adapted from amcss.c, but not counting collections, just
7 * total size of objects allocated (because epoch doesn't increment 8 * total size of objects allocated (because epoch doesn't increment when
8 * when AMS is collected). 9 * AMS is collected). */
9 */
10 10
11#include "fmtdy.h" 11#include "fmtdy.h"
12#include "fmtdytst.h" 12#include "fmtdytst.h"
@@ -32,17 +32,20 @@
32/* objNULL needs to be odd so that it's ignored in exactRoots. */ 32/* objNULL needs to be odd so that it's ignored in exactRoots. */
33#define objNULL ((mps_addr_t)0xDECEA5ED) 33#define objNULL ((mps_addr_t)0xDECEA5ED)
34#define testArenaSIZE ((size_t)16<<20) 34#define testArenaSIZE ((size_t)16<<20)
35#define initTestFREQ 6000 35#define initTestFREQ 3000
36#define splatTestFREQ 6000
36static mps_gen_param_s testChain[1] = { { 160, 0.90 } }; 37static mps_gen_param_s testChain[1] = { { 160, 0.90 } };
37 38
38 39
39static mps_pool_t pool; 40static mps_arena_t arena;
40static mps_ap_t ap; 41static mps_ap_t ap;
41static mps_addr_t exactRoots[exactRootsCOUNT]; 42static mps_addr_t exactRoots[exactRootsCOUNT];
42static mps_addr_t ambigRoots[ambigRootsCOUNT]; 43static mps_addr_t ambigRoots[ambigRootsCOUNT];
43static size_t totalSize = 0; 44static size_t totalSize = 0;
44 45
45 46
47/* make -- object allocation and init */
48
46static mps_addr_t make(void) 49static mps_addr_t make(void)
47{ 50{
48 size_t length = rnd() % 20, size = (length+2) * sizeof(mps_word_t); 51 size_t length = rnd() % 20, size = (length+2) * sizeof(mps_word_t);
@@ -51,10 +54,10 @@ static mps_addr_t make(void)
51 54
52 do { 55 do {
53 MPS_RESERVE_BLOCK(res, p, ap, size); 56 MPS_RESERVE_BLOCK(res, p, ap, size);
54 if(res) 57 if (res)
55 die(res, "MPS_RESERVE_BLOCK"); 58 die(res, "MPS_RESERVE_BLOCK");
56 res = dylan_init(p, size, exactRoots, exactRootsCOUNT); 59 res = dylan_init(p, size, exactRoots, exactRootsCOUNT);
57 if(res) 60 if (res)
58 die(res, "dylan_init"); 61 die(res, "dylan_init");
59 } while(!mps_commit(ap, p, size)); 62 } while(!mps_commit(ap, p, size));
60 63
@@ -63,49 +66,48 @@ static mps_addr_t make(void)
63} 66}
64 67
65 68
66static void *test(void *arg, size_t s) 69/* test -- the actual stress test */
70
71static mps_pool_debug_option_s freecheckOptions =
72 { NULL, 0, (void *)"Dead", 4 };
73
74static void *test(void *arg, size_t haveAmbigous)
67{ 75{
68 mps_arena_t arena; 76 mps_pool_t pool;
69 mps_fmt_t format;
70 mps_chain_t chain;
71 mps_root_t exactRoot, ambigRoot; 77 mps_root_t exactRoot, ambigRoot;
72 size_t lastStep = 0, i, r; 78 size_t lastStep = 0, i, r;
73 unsigned long objs; 79 unsigned long objs;
74 mps_ap_t busy_ap; 80 mps_ap_t busy_ap;
75 mps_addr_t busy_init; 81 mps_addr_t busy_init;
76 82
77 arena = (mps_arena_t)arg; 83 pool = (mps_pool_t)arg;
78 (void)s; /* unused */
79
80 die(mps_fmt_create_A(&format, arena, dylan_fmt_A()), "fmt_create");
81 die(mps_chain_create(&chain, arena, 1, testChain), "chain_create");
82 die(mps_pool_create(&pool, arena, mps_class_ams(), format, chain),
83 "pool_create(ams)");
84 84
85 die(mps_ap_create(&ap, pool, MPS_RANK_EXACT), "BufferCreate"); 85 die(mps_ap_create(&ap, pool, MPS_RANK_EXACT), "BufferCreate");
86 die(mps_ap_create(&busy_ap, pool, MPS_RANK_EXACT), "BufferCreate 2"); 86 die(mps_ap_create(&busy_ap, pool, MPS_RANK_EXACT), "BufferCreate 2");
87 87
88 for(i = 0; i < exactRootsCOUNT; ++i) 88 for(i = 0; i < exactRootsCOUNT; ++i)
89 exactRoots[i] = objNULL; 89 exactRoots[i] = objNULL;
90 for(i = 0; i < ambigRootsCOUNT; ++i) 90 if (haveAmbigous)
91 ambigRoots[i] = (mps_addr_t)rnd(); 91 for(i = 0; i < ambigRootsCOUNT; ++i)
92 ambigRoots[i] = rnd_addr();
92 93
93 die(mps_root_create_table_masked(&exactRoot, arena, 94 die(mps_root_create_table_masked(&exactRoot, arena,
94 MPS_RANK_EXACT, (mps_rm_t)0, 95 MPS_RANK_EXACT, (mps_rm_t)0,
95 &exactRoots[0], exactRootsCOUNT, 96 &exactRoots[0], exactRootsCOUNT,
96 (mps_word_t)1), 97 (mps_word_t)1),
97 "root_create_table(exact)"); 98 "root_create_table(exact)");
98 die(mps_root_create_table(&ambigRoot, arena, 99 if (haveAmbigous)
99 MPS_RANK_AMBIG, (mps_rm_t)0, 100 die(mps_root_create_table(&ambigRoot, arena,
100 &ambigRoots[0], ambigRootsCOUNT), 101 MPS_RANK_AMBIG, (mps_rm_t)0,
101 "root_create_table(ambig)"); 102 &ambigRoots[0], ambigRootsCOUNT),
103 "root_create_table(ambig)");
102 104
103 /* create an ap, and leave it busy */ 105 /* create an ap, and leave it busy */
104 die(mps_reserve(&busy_init, busy_ap, 64), "mps_reserve busy"); 106 die(mps_reserve(&busy_init, busy_ap, 64), "mps_reserve busy");
105 107
106 objs = 0; 108 objs = 0; totalSize = 0;
107 while(totalSize < totalSizeMAX) { 109 while(totalSize < totalSizeMAX) {
108 if(totalSize > lastStep + totalSizeSTEP) { 110 if (totalSize > lastStep + totalSizeSTEP) {
109 lastStep = totalSize; 111 lastStep = totalSize;
110 printf("\nSize %lu bytes, %lu objects.\n", 112 printf("\nSize %lu bytes, %lu objects.\n",
111 (unsigned long)totalSize, objs); 113 (unsigned long)totalSize, objs);
@@ -116,12 +118,12 @@ static void *test(void *arg, size_t s)
116 } 118 }
117 119
118 r = (size_t)rnd(); 120 r = (size_t)rnd();
119 if(r & 1) { 121 if (!haveAmbigous || (r & 1)) {
120 i = (r >> 1) % exactRootsCOUNT; 122 i = (r >> 1) % exactRootsCOUNT;
121 if(exactRoots[i] != objNULL) 123 if (exactRoots[i] != objNULL)
122 cdie(dylan_check(exactRoots[i]), "dying root check"); 124 cdie(dylan_check(exactRoots[i]), "dying root check");
123 exactRoots[i] = make(); 125 exactRoots[i] = make();
124 if(exactRoots[(exactRootsCOUNT-1) - i] != objNULL) 126 if (exactRoots[(exactRootsCOUNT-1) - i] != objNULL)
125 dylan_write(exactRoots[(exactRootsCOUNT-1) - i], 127 dylan_write(exactRoots[(exactRootsCOUNT-1) - i],
126 exactRoots, exactRootsCOUNT); 128 exactRoots, exactRootsCOUNT);
127 } else { 129 } else {
@@ -131,9 +133,12 @@ static void *test(void *arg, size_t s)
131 ambigRoots[i] = (mps_addr_t)((char *)(ambigRoots[i/2]) + 1); 133 ambigRoots[i] = (mps_addr_t)((char *)(ambigRoots[i/2]) + 1);
132 } 134 }
133 135
134 if(rnd() % initTestFREQ == 0) 136 if (rnd() % initTestFREQ == 0)
135 *(int*)busy_init = -1; /* check that the buffer is still there */ 137 *(int*)busy_init = -1; /* check that the buffer is still there */
136 138
139 if (rnd() % splatTestFREQ == 0)
140 mps_pool_check_free_space(pool);
141
137 ++objs; 142 ++objs;
138 if (objs % 256 == 0) { 143 if (objs % 256 == 0) {
139 printf("."); 144 printf(".");
@@ -145,10 +150,8 @@ static void *test(void *arg, size_t s)
145 mps_ap_destroy(busy_ap); 150 mps_ap_destroy(busy_ap);
146 mps_ap_destroy(ap); 151 mps_ap_destroy(ap);
147 mps_root_destroy(exactRoot); 152 mps_root_destroy(exactRoot);
148 mps_root_destroy(ambigRoot); 153 if (haveAmbigous)
149 mps_pool_destroy(pool); 154 mps_root_destroy(ambigRoot);
150 mps_chain_destroy(chain);
151 mps_fmt_destroy(format);
152 155
153 return NULL; 156 return NULL;
154} 157}
@@ -156,8 +159,10 @@ static void *test(void *arg, size_t s)
156 159
157int main(int argc, char **argv) 160int main(int argc, char **argv)
158{ 161{
159 mps_arena_t arena;
160 mps_thr_t thread; 162 mps_thr_t thread;
163 mps_fmt_t format;
164 mps_chain_t chain;
165 mps_pool_t pool;
161 void *r; 166 void *r;
162 167
163 randomize(argc, argv); 168 randomize(argc, argv);
@@ -165,7 +170,37 @@ int main(int argc, char **argv)
165 die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), 170 die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE),
166 "arena_create"); 171 "arena_create");
167 die(mps_thread_reg(&thread, arena), "thread_reg"); 172 die(mps_thread_reg(&thread, arena), "thread_reg");
168 mps_tramp(&r, test, arena, 0); 173 die(mps_fmt_create_A(&format, arena, dylan_fmt_A()), "fmt_create");
174 die(mps_chain_create(&chain, arena, 1, testChain), "chain_create");
175
176 printf("\nAMS Debug\n");
177 die(mps_pool_create(&pool, arena, mps_class_ams_debug(), &freecheckOptions,
178 format, chain, FALSE),
179 "pool_create(ams_debug,share)");
180 mps_tramp(&r, test, pool, 0);
181 mps_pool_destroy(pool);
182
183 printf("\nAMS Debug\n");
184 die(mps_pool_create(&pool, arena, mps_class_ams_debug(), &freecheckOptions,
185 format, chain, TRUE),
186 "pool_create(ams_debug,ambig)");
187 mps_tramp(&r, test, pool, 1);
188 mps_pool_destroy(pool);
189
190 printf("\nAMS\n");
191 die(mps_pool_create(&pool, arena, mps_class_ams(), format, chain, TRUE),
192 "pool_create(ams,ambig)");
193 mps_tramp(&r, test, pool, 1);
194 mps_pool_destroy(pool);
195
196 printf("\nAMS\n");
197 die(mps_pool_create(&pool, arena, mps_class_ams(), format, chain, FALSE),
198 "pool_create(ams,share)");
199 mps_tramp(&r, test, pool, 0);
200 mps_pool_destroy(pool);
201
202 mps_chain_destroy(chain);
203 mps_fmt_destroy(format);
169 mps_thread_dereg(thread); 204 mps_thread_dereg(thread);
170 mps_arena_destroy(arena); 205 mps_arena_destroy(arena);
171 206
diff --git a/mps/code/amssshe.c b/mps/code/amssshe.c
index b1e0a0435e8..33197a6a281 100644
--- a/mps/code/amssshe.c
+++ b/mps/code/amssshe.c
@@ -55,7 +55,7 @@ static mps_addr_t make(void)
55 res = dylan_init(userP, size, exactRoots, exactRootsCOUNT); 55 res = dylan_init(userP, size, exactRoots, exactRootsCOUNT);
56 if(res) 56 if(res)
57 die(res, "dylan_init"); 57 die(res, "dylan_init");
58 ((int*)p)[0] = realTYPE; 58 ((int*)p)[0] = realHeader;
59 ((int*)p)[1] = 0xED0ED; 59 ((int*)p)[1] = 0xED0ED;
60 } while(!mps_commit(ap, p, size + headerSIZE)); 60 } while(!mps_commit(ap, p, size + headerSIZE));
61 61
@@ -80,8 +80,8 @@ static void *test(void *arg, size_t s)
80 80
81 die(EnsureHeaderFormat(&format, arena), "make header format"); 81 die(EnsureHeaderFormat(&format, arena), "make header format");
82 die(mps_chain_create(&chain, arena, 1, testChain), "chain_create"); 82 die(mps_chain_create(&chain, arena, 1, testChain), "chain_create");
83 die(mps_pool_create(&pool, arena, mps_class_ams(), format, chain), 83 die(mps_pool_create(&pool, arena, mps_class_ams(), format, chain,
84 "pool_create(ams)"); 84 TRUE), "pool_create(ams)");
85 85
86 die(mps_ap_create(&ap, pool, MPS_RANK_EXACT), "BufferCreate"); 86 die(mps_ap_create(&ap, pool, MPS_RANK_EXACT), "BufferCreate");
87 die(mps_ap_create(&busy_ap, pool, MPS_RANK_EXACT), "BufferCreate 2"); 87 die(mps_ap_create(&busy_ap, pool, MPS_RANK_EXACT), "BufferCreate 2");
diff --git a/mps/code/apss.c b/mps/code/apss.c
index f95123fbae2..9744a82368b 100644
--- a/mps/code/apss.c
+++ b/mps/code/apss.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 8
@@ -21,6 +22,8 @@
21#define testLOOPS 10 22#define testLOOPS 10
22 23
23 24
25/* make -- allocate one object */
26
24static mps_res_t make(mps_addr_t *p, mps_ap_t ap, size_t size) 27static mps_res_t make(mps_addr_t *p, mps_ap_t ap, size_t size)
25{ 28{
26 mps_res_t res; 29 mps_res_t res;
@@ -35,8 +38,10 @@ static mps_res_t make(mps_addr_t *p, mps_ap_t ap, size_t size)
35} 38}
36 39
37 40
38static mps_res_t stress(mps_class_t class, mps_arena_t arena, 41/* stress -- create a pool of the requested type and allocate in it */
39 size_t (*size)(int i), ...) 42
43static mps_res_t stress(mps_class_t class, size_t (*size)(int i),
44 mps_arena_t arena, ...)
40{ 45{
41 mps_res_t res = MPS_RES_OK; 46 mps_res_t res = MPS_RES_OK;
42 mps_pool_t pool; 47 mps_pool_t pool;
@@ -46,7 +51,7 @@ static mps_res_t stress(mps_class_t class, mps_arena_t arena,
46 int *ps[testSetSIZE]; 51 int *ps[testSetSIZE];
47 size_t ss[testSetSIZE]; 52 size_t ss[testSetSIZE];
48 53
49 va_start(arg, size); 54 va_start(arg, arena);
50 res = mps_pool_create_v(&pool, arena, class, arg); 55 res = mps_pool_create_v(&pool, arena, class, arg);
51 va_end(arg); 56 va_end(arg);
52 if (res != MPS_RES_OK) 57 if (res != MPS_RES_OK)
@@ -107,6 +112,9 @@ allocFail:
107 112
108#define alignUp(w, a) (((w) + (a) - 1) & ~((size_t)(a) - 1)) 113#define alignUp(w, a) (((w) + (a) - 1) & ~((size_t)(a) - 1))
109 114
115
116/* randomSize8 -- produce sizes both latge and small, 8-byte aligned */
117
110static size_t randomSize8(int i) 118static size_t randomSize8(int i)
111{ 119{
112 size_t maxSize = 2 * 160 * 0x2000; 120 size_t maxSize = 2 * 160 * 0x2000;
@@ -115,24 +123,32 @@ static size_t randomSize8(int i)
115} 123}
116 124
117 125
118static mps_pool_debug_option_s debugOptions = { (void *)"postpost", 8 }; 126/* testInArena -- test all the pool classes in the given arena */
127
128static mps_pool_debug_option_s bothOptions =
129 { (void *)"postpost", 8, (void *)"DEAD", 4 };
130
131static mps_pool_debug_option_s fenceOptions =
132 { (void *)"\0XXX ''\"\"'' XXX\0", 16, NULL, 0 };
119 133
120static void testInArena(mps_arena_t arena) 134static void testInArena(mps_arena_t arena, mps_pool_debug_option_s *options)
121{ 135{
122 mps_res_t res; 136 mps_res_t res;
123 137
138 /* IWBN to test MVFFDebug, but the MPS doesn't support debugging APs, */
139 /* yet (MV Debug works here, because it fakes it through PoolAlloc). */
124 printf("MVFF\n\n"); 140 printf("MVFF\n\n");
125 res = stress(mps_class_mvff(), arena, randomSize8, 141 res = stress(mps_class_mvff(), randomSize8, arena,
126 (size_t)65536, (size_t)32, (size_t)4, TRUE, TRUE, TRUE); 142 (size_t)65536, (size_t)32, (size_t)4, TRUE, TRUE, TRUE);
127 if (res == MPS_RES_COMMIT_LIMIT) return; 143 if (res == MPS_RES_COMMIT_LIMIT) return;
128 die(res, "stress MVFF"); 144 die(res, "stress MVFF");
129 printf("MV debug\n\n"); 145 printf("MV debug\n\n");
130 res = stress(mps_class_mv_debug(), arena, randomSize8, 146 res = stress(mps_class_mv_debug(), randomSize8, arena,
131 &debugOptions, (size_t)65536, (size_t)32, (size_t)65536); 147 options, (size_t)65536, (size_t)32, (size_t)65536);
132 if (res == MPS_RES_COMMIT_LIMIT) return; 148 if (res == MPS_RES_COMMIT_LIMIT) return;
133 die(res, "stress MV debug"); 149 die(res, "stress MV debug");
134 printf("MV\n\n"); 150 printf("MV\n\n");
135 res = stress(mps_class_mv(), arena, randomSize8, 151 res = stress(mps_class_mv(), randomSize8, arena,
136 (size_t)65536, (size_t)32, (size_t)65536); 152 (size_t)65536, (size_t)32, (size_t)65536);
137 if (res == MPS_RES_COMMIT_LIMIT) return; 153 if (res == MPS_RES_COMMIT_LIMIT) return;
138 die(res, "stress MV"); 154 die(res, "stress MV");
@@ -147,13 +163,13 @@ int main(int argc, char **argv)
147 163
148 die(mps_arena_create(&arena, mps_arena_class_vm(), 2*testArenaSIZE), 164 die(mps_arena_create(&arena, mps_arena_class_vm(), 2*testArenaSIZE),
149 "mps_arena_create"); 165 "mps_arena_create");
150 mps_arena_commit_limit_set(arena, testArenaSIZE); 166 die(mps_arena_commit_limit_set(arena, testArenaSIZE), "commit limit");
151 testInArena(arena); 167 testInArena(arena, &fenceOptions);
152 mps_arena_destroy(arena); 168 mps_arena_destroy(arena);
153 169
154 die(mps_arena_create(&arena, mps_arena_class_vmnz(), 2*testArenaSIZE), 170 die(mps_arena_create(&arena, mps_arena_class_vmnz(), 2*testArenaSIZE),
155 "mps_arena_create"); 171 "mps_arena_create");
156 testInArena(arena); 172 testInArena(arena, &bothOptions);
157 mps_arena_destroy(arena); 173 mps_arena_destroy(arena);
158 174
159 fflush(stdout); /* synchronize */ 175 fflush(stdout); /* synchronize */
diff --git a/mps/code/arena.c b/mps/code/arena.c
index 5fd42184566..a1699fa38e3 100644
--- a/mps/code/arena.c
+++ b/mps/code/arena.c
@@ -14,7 +14,7 @@ SRCID(arena, "$Id$");
14 14
15/* ArenaControlPool -- get the control pool */ 15/* ArenaControlPool -- get the control pool */
16 16
17#define ArenaControlPool(arena) MVPool(&(arena)->controlPoolStruct) 17#define ArenaControlPool(arena) MV2Pool(&(arena)->controlPoolStruct)
18 18
19 19
20/* ArenaTrivDescribe -- produce trivial description of an arena */ 20/* ArenaTrivDescribe -- produce trivial description of an arena */
diff --git a/mps/code/arenacl.c b/mps/code/arenacl.c
index cc38de55ae9..196d4275823 100644
--- a/mps/code/arenacl.c
+++ b/mps/code/arenacl.c
@@ -13,6 +13,7 @@
13 13
14#include "boot.h" 14#include "boot.h"
15#include "tract.h" 15#include "tract.h"
16#include "bt.h"
16#include "mpm.h" 17#include "mpm.h"
17#include "mpsacl.h" 18#include "mpsacl.h"
18 19
diff --git a/mps/code/arenavm.c b/mps/code/arenavm.c
index 0599a71637f..5cac14e74d9 100644
--- a/mps/code/arenavm.c
+++ b/mps/code/arenavm.c
@@ -23,6 +23,7 @@
23 23
24#include "boot.h" 24#include "boot.h"
25#include "tract.h" 25#include "tract.h"
26#include "bt.h"
26#include "mpm.h" 27#include "mpm.h"
27#include "mpsavm.h" 28#include "mpsavm.h"
28 29
diff --git a/mps/code/arenavmx.c b/mps/code/arenavmx.c
deleted file mode 100644
index 0a08218a74f..00000000000
--- a/mps/code/arenavmx.c
+++ /dev/null
@@ -1,32 +0,0 @@
1/* impl.c.arenavmx: STUBS FOR ARENAVM
2 *
3 * $Id$
4 * Copyright (c) 2001 Ravenbrook Limited.
5 *
6 * .purpose: This file is not properly part of the MPS. It is a
7 * convenience file for EP-Core who do _not_ wish to get a link error,
8 * when they link to a VM arena function on a platform where it isn't
9 * supported (see req.epcore.link.no-error).
10 *
11 * .stub: This file provides stub functions for the VM arena class
12 * functions. Calling any of them causes a run-time assertion.
13 */
14
15
16#include "mpm.h"
17#include "mpsavm.h"
18
19SRCID(arenavmx, "$Id$");
20
21
22mps_arena_class_t mps_arena_class_vm(void)
23{
24 NOTREACHED;
25 return (mps_arena_class_t)NULL;
26}
27
28mps_arena_class_t mps_arena_class_vmnz(void)
29{
30 NOTREACHED;
31 return (mps_arena_class_t)NULL;
32}
diff --git a/mps/code/assert.c b/mps/code/assert.c
deleted file mode 100644
index 52b0071c9f7..00000000000
--- a/mps/code/assert.c
+++ /dev/null
@@ -1,71 +0,0 @@
1/* impl.c.assert: ASSERTION IMPLEMENTATION
2 *
3 * $Id$
4 * Copyright (c) 2001 Ravenbrook Limited.
5 *
6 * This source provides the AssertFail function which is
7 * invoked by the assertion macros (see impl.h.assert).
8 * It also provides for user-installed assertion failure handlers.
9 */
10
11#include "check.h"
12#include "mpm.h"
13
14SRCID(assert, "$Id$");
15
16
17/* CheckLevel -- Control check level
18 *
19 * This controls the behaviour of Check methods unless MPS_HOT_RED
20 * is defined, when it is effectively stuck at "CheckNONE".
21 */
22
23unsigned CheckLevel = CheckSHALLOW;
24
25
26static void AssertLib(const char *cond, const char *id,
27 const char *file, unsigned line)
28{
29 WriteF(mps_lib_stderr,
30 "\n"
31 "MPS ASSERTION FAILURE\n"
32 "\n"
33 "Id: $S\n", id,
34 "File: $S\n", file,
35 "Line: $U\n", (WriteFU)line,
36 "Condition: $S\n", cond,
37 "\n",
38 NULL);
39
40 mps_lib_abort();
41}
42
43
44static AssertHandler handler = &AssertLib;
45
46
47AssertHandler AssertDefault(void)
48{
49 return &AssertLib;
50}
51
52
53AssertHandler AssertInstall(AssertHandler new)
54{
55 AssertHandler prev = handler;
56 handler = new;
57 return prev;
58}
59
60
61/* AssertFail -- fail an assertion
62 *
63 * This function is called when an ASSERT macro fails a test. It
64 * calls the installed assertion handler, if it is not NULL. If
65 * handler returns the progam continues.
66 */
67void AssertFail1(const char *s)
68{
69 if (handler != NULL)
70 (*handler)(s, "", "", 0);
71}
diff --git a/mps/code/bt.c b/mps/code/bt.c
index 2d76ea806e1..8853ee582d9 100644
--- a/mps/code/bt.c
+++ b/mps/code/bt.c
@@ -12,9 +12,11 @@
12 * .design: see design.mps.bt 12 * .design: see design.mps.bt
13 */ 13 */
14 14
15#include "bt.h"
16#include "config.h"
17#include "check.h"
15#include "mpm.h" 18#include "mpm.h"
16 19
17
18SRCID(bt, "$Id$"); 20SRCID(bt, "$Id$");
19 21
20 22
@@ -999,3 +1001,18 @@ void BTCopyOffsetRange(BT fromBT, BT toBT,
999 } 1001 }
1000} 1002}
1001 1003
1004
1005/* BTCountResRange -- count number of reset bits in a range */
1006
1007Count BTCountResRange(BT bt, Index base, Index limit)
1008{
1009 Count c = 0;
1010 Index bit;
1011
1012 AVER(BTCheck(bt));
1013 AVER(base < limit);
1014
1015 for (bit = base; bit < limit; ++bit)
1016 if (!BTGet(bt, bit)) ++c;
1017 return c;
1018}
diff --git a/mps/code/bt.h b/mps/code/bt.h
new file mode 100644
index 00000000000..9d5c7edd9bc
--- /dev/null
+++ b/mps/code/bt.h
@@ -0,0 +1,75 @@
1/* impl.h.bt: Bit Table Interface
2 *
3 * $Id: bt.h,v 1.2 2002/02/01 13:52:04 pekka Exp $
4 * $HopeName: MMsrc!bt.h(trunk.2) $
5 * Copyright (C) 2002 Global Graphics Software.
6 *
7 * .source: design.mps.bt. */
8
9#ifndef bt_h
10#define bt_h
11
12#include "mpmtypes.h"
13
14
15/* design.mps.bt.if.size */
16extern size_t (BTSize)(unsigned long length);
17#define BTSize(n) (((n) + MPS_WORD_WIDTH-1) / MPS_WORD_WIDTH * sizeof(Word))
18
19
20/* design.mps.bt.if.get */
21extern Bool (BTGet)(BT bt, Index index);
22#define BTGet(a, i) \
23 ((Bool)(((a)[((i) >> MPS_WORD_SHIFT)] \
24 >> ((i) & ~((Word)-1 << MPS_WORD_SHIFT))) \
25 & (Word)1))
26
27/* design.mps.bt.if.set */
28extern void (BTSet)(BT bt, Index index);
29#define BTSet(a, i) \
30 BEGIN \
31 (a)[((i)>>MPS_WORD_SHIFT)] |= (Word)1<<((i)&~((Word)-1<<MPS_WORD_SHIFT)); \
32 END
33
34/* design.mps.bt.if.res */
35extern void (BTRes)(BT bt, Index index);
36#define BTRes(a, i) \
37 BEGIN \
38 (a)[((i)>>MPS_WORD_SHIFT)] &= \
39 ~((Word)1 << ((i) & ~((Word)-1<<MPS_WORD_SHIFT))); \
40 END
41
42
43extern Res BTCreate(BT *btReturn, Arena arena, Count length);
44extern void BTDestroy(BT bt, Arena arena, Count length);
45
46extern void BTSetRange(BT bt, Index base, Index limit);
47extern Bool BTIsSetRange(BT bt, Index base, Index limit);
48extern void BTResRange(BT bt, Index base, Index limit);
49extern Bool BTIsResRange(BT bt, Index base, Index limit);
50
51extern Bool BTFindShortResRange(Index *baseReturn, Index *limitReturn,
52 BT bt, Index searchBase, Index searchLimit,
53 unsigned long length);
54extern Bool BTFindShortResRangeHigh(Index *baseReturn, Index *limitReturn,
55 BT bt, Index searchBase, Index searchLimit,
56 unsigned long length);
57extern Bool BTFindLongResRange(Index *baseReturn, Index *limitReturn,
58 BT bt, Index searchBase, Index searchLimit,
59 unsigned long length);
60extern Bool BTFindLongResRangeHigh(Index *baseReturn, Index *limitReturn,
61 BT bt, Index searchBase, Index searchLimit,
62 unsigned long length);
63
64extern Bool BTRangesSame(BT BTx, BT BTy, Index base, Index limit);
65
66extern void BTCopyInvertRange(BT fromBT, BT toBT, Index base, Index limit);
67extern void BTCopyRange(BT fromBT, BT toBT, Index base, Index limit);
68extern void BTCopyOffsetRange(BT fromBT, BT toBT,
69 Index fromBase, Index fromLimit,
70 Index toBase, Index toLimit);
71
72extern Count BTCountResRange(BT bt, Index base, Index limit);
73
74
75#endif /* bt_h */
diff --git a/mps/code/bttest.c b/mps/code/bttest.c
index 8d02b7ce6c7..a5fb1d66706 100644
--- a/mps/code/bttest.c
+++ b/mps/code/bttest.c
@@ -18,7 +18,6 @@ struct itimerspec; /* stop complaints from time.h */
18#endif 18#endif
19#include <time.h> 19#include <time.h>
20 20
21
22SRCID(bttest, "$Id$"); 21SRCID(bttest, "$Id$");
23 22
24 23
diff --git a/mps/code/cbs.c b/mps/code/cbs.c
index 5d07d9bc233..d08542f3cd9 100644
--- a/mps/code/cbs.c
+++ b/mps/code/cbs.c
@@ -18,7 +18,6 @@
18#include "poolmfs.h" 18#include "poolmfs.h"
19#include "mpm.h" 19#include "mpm.h"
20 20
21
22SRCID(cbs, "$Id$"); 21SRCID(cbs, "$Id$");
23 22
24 23
diff --git a/mps/code/check.h b/mps/code/check.h
index 3a541164213..cd69b551b67 100644
--- a/mps/code/check.h
+++ b/mps/code/check.h
@@ -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 * .aver: This header defines a family of AVER and NOTREACHED macros. 7 * .aver: This header defines a family of AVER and NOTREACHED macros.
7 * These macros should be used to instrument and annotate code with 8 * These macros should be used to instrument and annotate code with
@@ -12,7 +13,7 @@
12 * a comment. 13 * a comment.
13 * 14 *
14 * .disable: When assertions are disabled, AVER expands to something 15 * .disable: When assertions are disabled, AVER expands to something
15 * which evaluates the condition but discards the result. Compilers 16 * which contains the condition but discards the result. Compilers
16 * will throw the code away, but check its syntax. 17 * will throw the code away, but check its syntax.
17 * 18 *
18 * .trans.level-check: CheckLevel itself is not checked anywhere. 19 * .trans.level-check: CheckLevel itself is not checked anywhere.
@@ -26,7 +27,7 @@
26#include "mpslib.h" 27#include "mpslib.h"
27 28
28 29
29/* CheckLevel -- Control check method behaviour; see impl.c.assert */ 30/* CheckLevel -- Control check method behaviour */
30 31
31extern unsigned CheckLevel; 32extern unsigned CheckLevel;
32 33
@@ -39,86 +40,73 @@ enum {
39 40
40/* AVER, AVERT -- MPM assertions 41/* AVER, AVERT -- MPM assertions
41 * 42 *
42 * AVER and AVERT are used to assert conditions within the MPM. 43 * AVER and AVERT are used to assert conditions in the code.
43 * In white-hot varieties, all assertions compile away to nothing.
44 */ 44 */
45 45
46#if defined(MPS_HOT_WHITE) 46#if defined(CHECK_NONE)
47 47
48#define AVER(cond) DISCARD(cond) 48#define AVER(cond) DISCARD(cond)
49#define AVERT(type, val) DISCARD(type ## Check(val)) 49#define AVERT(type, val) DISCARD(type ## Check(val))
50#define AVER_CRITICAL(cond) DISCARD(cond) 50#define AVER_CRITICAL(cond) DISCARD(cond)
51#define AVERT_CRITICAL(type, val) DISCARD(type ## Check(val)) 51#define AVERT_CRITICAL(type, val) DISCARD(type ## Check(val))
52 52
53#elif defined(MPS_HOT_RED) 53#elif defined(CHECK)
54 54
55#define AVER(cond) ASSERT(cond, #cond) 55#define AVER(cond) ASSERT(cond, #cond)
56#define AVERT(type, val) ASSERT(type ## Check(val), \ 56#define AVERT(type, val) ASSERT(type ## Check(val), \
57 "TypeCheck " #type ": " #val) 57 "TypeCheck " #type ": " #val)
58#define AVER_CRITICAL(cond) DISCARD(cond) 58#define AVER_CRITICAL(cond) \
59#define AVERT_CRITICAL(type, val) DISCARD(type ## Check(val)) 59 BEGIN \
60 60 if (CheckLevel != CheckNONE) ASSERT(cond, #cond); \
61#elif defined(MPS_COOL) 61 END
62 62#define AVERT_CRITICAL(type, val) \
63#define AVER(cond) ASSERT(cond, #cond) 63 BEGIN \
64#define AVERT(type, val) ASSERT(type ## Check(val), \ 64 if (CheckLevel != CheckNONE) \
65 "TypeCheck " #type ": " #val) 65 ASSERT(type ## Check(val), "TypeCheck " #type ": " #val); \
66#define AVER_CRITICAL(cond) ASSERT(cond, #cond) 66 END
67#define AVERT_CRITICAL(type, val) ASSERT(type ## Check(val), \
68 "TypeCheck " #type ": " #val)
69 67
70#else 68#else
71 69
72#error "No heat defined." 70#error "No checking defined."
73 71
74#endif 72#endif
75 73
76 74
77/* AssertHandler -- the assert handler */
78
79typedef void (*AssertHandler)(const char *cond, const char *id,
80 const char *file, unsigned line);
81extern AssertHandler AssertInstall(AssertHandler handler);
82extern AssertHandler AssertDefault(void);
83
84
85/* internals for actually asserting */ 75/* internals for actually asserting */
86 76
87extern void AssertFail1(const char *s);
88
89#define ASSERT(cond, condstring) \ 77#define ASSERT(cond, condstring) \
90 BEGIN \ 78 BEGIN \
91 if(cond) NOOP; else \ 79 if (cond) NOOP; else \
92 AssertFail1(condstring "\n" __FILE__ "\n" STR(__LINE__)); \ 80 mps_lib_assert_fail(condstring "\n" __FILE__ "\n" STR(__LINE__)); \
93 END 81 END
94 82
95 83
96/* NOTREACHED -- control should never reach this statement */ 84/* NOTREACHED -- control should never reach this statement */
97 85
98#if defined(MPS_HOT_WHITE) 86#if defined(CHECK)
99
100#define NOTREACHED NOOP
101
102#else
103 87
104#define NOTREACHED \ 88#define NOTREACHED \
105 BEGIN \ 89 BEGIN \
106 AssertFail1("unreachable statement" "\n" __FILE__ "\n" STR(__LINE__)); \ 90 mps_lib_assert_fail("unreachable code" "\n" __FILE__ "\n" STR(__LINE__)); \
107 END 91 END
108 92
93#else
94
95#define NOTREACHED NOOP
96
109#endif 97#endif
110 98
111 99
112/* CHECKT -- check type simply 100/* CHECKT -- check type simply
113 * 101 *
114 * Must be thread safe. See design.mps.interface.c.thread-safety 102 * Must be thread-safe. See design.mps.interface.c.thread-safety
115 * and design.mps.interface.c.check.space. 103 * and design.mps.interface.c.check.space.
116 */ 104 */
117 105
118#define CHECKT(type, val) ((val) != NULL && (val)->sig == type ## Sig) 106#define CHECKT(type, val) ((val) != NULL && (val)->sig == type ## Sig)
119 107
120 108
121#if defined(MPS_HOT_WHITE) 109#if defined(CHECK_NONE)
122 110
123 111
124#define CHECKS(type, val) DISCARD(CHECKT(type, val)) 112#define CHECKS(type, val) DISCARD(CHECKT(type, val))
@@ -129,26 +117,14 @@ extern void AssertFail1(const char *s);
129#define CHECKU_NOSIG(type, val) DISCARD((val) != NULL) 117#define CHECKU_NOSIG(type, val) DISCARD((val) != NULL)
130 118
131 119
132#elif defined(MPS_HOT_RED) 120#else
133
134
135#define CHECKS(type, val) ASSERT(CHECKT(type, val), \
136 "SigCheck " #type ": " #val)
137
138#define CHECKL(cond) DISCARD(cond)
139#define CHECKD(type, val) DISCARD(CHECKT(type, val))
140#define CHECKD_NOSIG(type, val) DISCARD((val) != NULL)
141#define CHECKU(type, val) DISCARD(CHECKT(type, val))
142#define CHECKU_NOSIG(type, val) DISCARD((val) != NULL)
143
144
145#elif defined(MPS_COOL)
146 121
147 122
148/* CHECKS -- Check Signature */ 123/* CHECKS -- Check Signature */
149 124
150#define CHECKS(type, val) ASSERT(CHECKT(type, val), \ 125#define CHECKS(type, val) ASSERT(CHECKT(type, val), \
151 "SigCheck " #type ": " #val) 126 "SigCheck " #type ": " #val)
127
152 128
153/* CHECKL -- Check Local Invariant 129/* CHECKL -- Check Local Invariant
154 * 130 *
@@ -243,10 +219,6 @@ extern void AssertFail1(const char *s);
243 END 219 END
244 220
245 221
246#else
247
248#error "No heat defined."
249
250#endif 222#endif
251 223
252 224
diff --git a/mps/code/comm.gmk b/mps/code/comm.gmk
index 9085317bd21..734586be6a7 100644
--- a/mps/code/comm.gmk
+++ b/mps/code/comm.gmk
@@ -99,15 +99,9 @@ ifdef TARGET
99ifeq ($(TARGET),mmsw.a) 99ifeq ($(TARGET),mmsw.a)
100CFLAGSTARGET = -DCONFIG_PROD_EPCORE 100CFLAGSTARGET = -DCONFIG_PROD_EPCORE
101else 101else
102ifeq ($(TARGET),epvmss)
103CFLAGSTARGET = -DCONFIG_PROD_EPCORE
104else
105ifeq ($(TARGET),replaysw) 102ifeq ($(TARGET),replaysw)
106CFLAGSTARGET = -DCONFIG_PROD_EPCORE 103CFLAGSTARGET = -DCONFIG_PROD_EPCORE
107else 104else
108ifeq ($(TARGET),epdss)
109CFLAGSTARGET = -DCONFIG_PROD_EPCORE
110else
111ifeq ($(TARGET),mmdw.a) 105ifeq ($(TARGET),mmdw.a)
112CFLAGSTARGET = -DCONFIG_PROD_DYLAN 106CFLAGSTARGET = -DCONFIG_PROD_DYLAN
113else 107else
@@ -120,8 +114,6 @@ endif
120endif 114endif
121endif 115endif
122endif 116endif
123endif
124endif
125 117
126# These flags are included in all compilations. 118# These flags are included in all compilations.
127CFLAGSCOMMON = $(PFMDEFS) $(CFLAGSTARGET) $(CFLAGSCOMPILER) 119CFLAGSCOMMON = $(PFMDEFS) $(CFLAGSTARGET) $(CFLAGSCOMPILER)
@@ -184,7 +176,7 @@ ARFLAGS=rc$(ARFLAGSPFM)
184# platforms. 176# platforms.
185 177
186AMC = poolamc.c 178AMC = poolamc.c
187AMS = poolams.c 179AMS = poolams.c poolamsi.c
188AWL = poolawl.c 180AWL = poolawl.c
189LO = poollo.c 181LO = poollo.c
190SNC = poolsnc.c 182SNC = poolsnc.c
@@ -200,16 +192,16 @@ EVENTPROC = eventcnv.c eventpro.c table.c
200MPMCOMMON = mpsi.c mpm.c arenavm.c arenacl.c arena.c global.c locus.c \ 192MPMCOMMON = mpsi.c mpm.c arenavm.c arenacl.c arena.c global.c locus.c \
201 tract.c walk.c reserv.c protocol.c pool.c poolabs.c \ 193 tract.c walk.c reserv.c protocol.c pool.c poolabs.c \
202 trace.c root.c seg.c format.c buffer.c ref.c bt.c ring.c \ 194 trace.c root.c seg.c format.c buffer.c ref.c bt.c ring.c \
203 shield.c ld.c event.c action.c sac.c message.c assert.c \ 195 shield.c ld.c event.c sac.c message.c \
204 poolmrg.c poolmfs.c poolmv.c dbgpool.c \ 196 poolmrg.c poolmfs.c poolmv.c dbgpool.c dbgpooli.c \
205 boot.c meter.c splay.c cbs.c version.c 197 boot.c meter.c splay.c cbs.c version.c
206MPM = $(MPMCOMMON) $(MPMPF) 198MPM = $(MPMCOMMON) $(MPMPF)
207SWCOMMON = mpsi.c mpm.c arenavm.c arenacl.c arena.c global.c locus.c \ 199SWCOMMON = mpsi.c mpm.c arenavm.c arenacl.c arena.c global.c locus.c \
208 tract.c walk.c reserv.c protocol.c pool.c poolabs.c \ 200 tract.c walk.c reserv.c protocol.c pool.c poolabs.c \
209 trace.c root.c seg.c format.c buffer.c ref.c bt.c ring.c \ 201 trace.c root.c seg.c format.c buffer.c ref.c bt.c ring.c \
210 shield.c ld.c event.c action.c sac.c message.c assert.c \ 202 shield.c ld.c event.c sac.c message.c \
211 poolmrg.c poolmfs.c poolmv.c dbgpool.c \ 203 poolmrg.c poolmfs.c poolmv.c dbgpool.c dbgpooli \
212 poolepdl.c poolepvm.c poolams.c poolmvff.c \ 204 poolams.c poolamsi.c poolmvff.c \
213 boot.c meter.c splay.c cbs.c version.c mpsioan.c 205 boot.c meter.c splay.c cbs.c version.c mpsioan.c
214SW = $(SWCOMMON) $(SWPF) 206SW = $(SWCOMMON) $(SWPF)
215 207
@@ -246,9 +238,6 @@ ifdef TARGET
246ifeq ($(TARGET),mmsw.a) 238ifeq ($(TARGET),mmsw.a)
247SWDEP = $(SW:%.c=$(PFM)/$(VARIETY)/%.d) 239SWDEP = $(SW:%.c=$(PFM)/$(VARIETY)/%.d)
248else 240else
249ifeq ($(TARGET),epvmss)
250SWDEP = $(SW:%.c=$(PFM)/$(VARIETY)/%.d)
251else
252ifeq ($(TARGET),depend) 241ifeq ($(TARGET),depend)
253SWDEP = $(SW:%.c=$(PFM)/$(VARIETY)/%.d) 242SWDEP = $(SW:%.c=$(PFM)/$(VARIETY)/%.d)
254else 243else
@@ -256,7 +245,6 @@ SWDEP =
256endif 245endif
257endif 246endif
258endif 247endif
259endif
260 248
261TESTLIBOBJ = $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.o) 249TESTLIBOBJ = $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.o)
262TESTLIBDEP = $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.d) 250TESTLIBDEP = $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.d)
@@ -284,7 +272,7 @@ all: mpmss sacss amcss amcsshe amsss amssshe segsmss awlut awluthe \
284 abqtest cbstest btcv mv2test messtest steptest \ 272 abqtest cbstest btcv mv2test messtest steptest \
285 eventcnv mps.a 273 eventcnv mps.a
286 274
287swall: mmsw.a epvmss replaysw epdss 275swall: mmsw.a replaysw
288 276
289# Runs the automatic tests that are built with CONFIG_PROD_MPS 277# Runs the automatic tests that are built with CONFIG_PROD_MPS
290# These tests are run overnight (see design.buildsys.overnight). 278# These tests are run overnight (see design.buildsys.overnight).
@@ -295,11 +283,6 @@ testrun: mpmss apss sacss amcss amcsshe amsss amssshe segsmss awlut awluthe \
295 abqtest cbstest btcv messtest steptest 283 abqtest cbstest btcv messtest steptest
296 $(^:%=date && $(PFM)/$(VARIETY)/% &&) true 284 $(^:%=date && $(PFM)/$(VARIETY)/% &&) true
297 285
298# Runs the automatic tests that are built with CONFIG_PROD_EPCORE
299testrunep: epvmss epdss
300 $(^:%=date && $(PFM)/$(VARIETY)/% &&) true
301
302
303# These convenience targets allow one to type "make foo" to build target 286# These convenience targets allow one to type "make foo" to build target
304# foo in selected varieties (or none, for the latter rule). 287# foo in selected varieties (or none, for the latter rule).
305# 288#
@@ -307,7 +290,7 @@ testrunep: epvmss epdss
307 290
308mpmss sacss amcss amcssth amcsshe amsss amssshe segsmss awlut awlutth \ 291mpmss sacss amcss amcssth amcsshe amsss amssshe segsmss awlut awlutth \
309 awluthe mpsicv lockcov poolncv locv qs apss \ 292 awluthe mpsicv lockcov poolncv locv qs apss \
310 finalcv arenacv bttest teletest epvmss epdss \ 293 finalcv arenacv bttest teletest \
311 abqtest cbstest btcv mv2test \ 294 abqtest cbstest btcv mv2test \
312 messtest steptest \ 295 messtest steptest \
313 eventcnv replay replaysw \ 296 eventcnv replay replaysw \
@@ -367,7 +350,7 @@ $(PFM)/$(VARIETY)/locv: $(PFM)/$(VARIETY)/locv.o \
367 $(MPMOBJ) $(LOOBJ) $(TESTLIBOBJ) 350 $(MPMOBJ) $(LOOBJ) $(TESTLIBOBJ)
368 351
369$(PFM)/$(VARIETY)/mpmss: $(PFM)/$(VARIETY)/mpmss.o \ 352$(PFM)/$(VARIETY)/mpmss: $(PFM)/$(VARIETY)/mpmss.o \
370 $(MPMOBJ) $(TESTLIBOBJ) 353 $(MPMOBJ) $(MVFFOBJ) $(TESTLIBOBJ)
371 354
372$(PFM)/$(VARIETY)/apss: $(PFM)/$(VARIETY)/apss.o \ 355$(PFM)/$(VARIETY)/apss: $(PFM)/$(VARIETY)/apss.o \
373 $(MPMOBJ) $(MVFFOBJ) $(TESTLIBOBJ) 356 $(MPMOBJ) $(MVFFOBJ) $(TESTLIBOBJ)
@@ -405,12 +388,6 @@ $(PFM)/$(VARIETY)/amssshe: $(PFM)/$(VARIETY)/amssshe.o \
405$(PFM)/$(VARIETY)/segsmss: $(PFM)/$(VARIETY)/segsmss.o \ 388$(PFM)/$(VARIETY)/segsmss: $(PFM)/$(VARIETY)/segsmss.o \
406 $(FMTDYTSTOBJ) $(MPMOBJ) $(AMSOBJ) $(TESTLIBOBJ) 389 $(FMTDYTSTOBJ) $(MPMOBJ) $(AMSOBJ) $(TESTLIBOBJ)
407 390
408$(PFM)/$(VARIETY)/epvmss: $(PFM)/$(VARIETY)/epvmss.o \
409 $(FMTPSOBJ) $(SWOBJ) $(TESTLIBOBJ) $(PLINTHOBJ)
410
411$(PFM)/$(VARIETY)/epdss: $(PFM)/$(VARIETY)/epdss.o \
412 $(SWOBJ) $(TESTLIBOBJ) $(PLINTHOBJ)
413
414$(PFM)/$(VARIETY)/awlut: $(PFM)/$(VARIETY)/awlut.o \ 391$(PFM)/$(VARIETY)/awlut: $(PFM)/$(VARIETY)/awlut.o \
415 $(FMTDYTSTOBJ) $(MPMOBJ) $(LOOBJ) $(AWLOBJ) $(TESTLIBOBJ) 392 $(FMTDYTSTOBJ) $(MPMOBJ) $(LOOBJ) $(AWLOBJ) $(TESTLIBOBJ)
416 393
diff --git a/mps/code/commpost.nmk b/mps/code/commpost.nmk
index 2cd7a14299e..37bed946003 100644
--- a/mps/code/commpost.nmk
+++ b/mps/code/commpost.nmk
@@ -21,7 +21,7 @@ all: mpmss.exe amcss.exe amsss.exe amssshe.exe segsmss.exe awlut.exe awluthe.exe
21 locbwcss.exe locusss.exe \ 21 locbwcss.exe locusss.exe \
22 eventcnv.exe 22 eventcnv.exe
23 23
24swall: mmsw.lib epvmss.exe replaysw.exe 24swall: mmsw.lib replaysw.exe
25 25
26 26
27# Convenience targets 27# Convenience targets
@@ -31,7 +31,7 @@ swall: mmsw.lib epvmss.exe replaysw.exe
31 31
32mpmss.exe amcss.exe amcsshe.exe amsss.exe amssshe.exe segsmss.exe awlut.exe awluthe.exe dwstress.exe \ 32mpmss.exe amcss.exe amcsshe.exe amsss.exe amssshe.exe segsmss.exe awlut.exe awluthe.exe dwstress.exe \
33 mpsicv.exe lockutw3.exe lockcov.exe poolncv.exe locv.exe qs.exe apss.exe \ 33 mpsicv.exe lockutw3.exe lockcov.exe poolncv.exe locv.exe qs.exe apss.exe \
34 finalcv.exe arenacv.exe bttest.exe teletest.exe protcv.exe epvmss.exe \ 34 finalcv.exe arenacv.exe bttest.exe teletest.exe protcv.exe \
35 abqtest.exe cbstest.exe btcv.exe mv2test.exe messtest.exe steptest.exe \ 35 abqtest.exe cbstest.exe btcv.exe mv2test.exe messtest.exe steptest.exe \
36 locbwcss.exe locusss.exe \ 36 locbwcss.exe locusss.exe \
37 replay.exe replaysw.exe eventcnv.exe \ 37 replay.exe replaysw.exe eventcnv.exe \
@@ -162,10 +162,6 @@ $(PFM)\$(VARIETY)\locbwcss.exe: $(PFM)\$(VARIETY)\locbwcss.obj \
162$(PFM)\$(VARIETY)\dwstress.exe: $(PFM)\$(VARIETY)\dwstress.obj \ 162$(PFM)\$(VARIETY)\dwstress.exe: $(PFM)\$(VARIETY)\dwstress.obj \
163 $(DWOBJ) $(MPMOBJ) $(PLINTHOBJ) $(AMCOBJ) 163 $(DWOBJ) $(MPMOBJ) $(PLINTHOBJ) $(AMCOBJ)
164 164
165$(PFM)\$(VARIETY)\epvmss.exe: $(PFM)\$(VARIETY)\epvmss.obj \
166 $(PFM)\$(VARIETY)\fmtpstst.obj \
167 $(SWOBJ) $(TESTLIBOBJ) $(PLINTHOBJ) $(EVENTOBJ)
168
169$(PFM)\$(VARIETY)\awlut.exe: $(PFM)\$(VARIETY)\awlut.obj \ 165$(PFM)\$(VARIETY)\awlut.exe: $(PFM)\$(VARIETY)\awlut.obj \
170 $(DWTESTOBJ) \ 166 $(DWTESTOBJ) \
171 $(MPMOBJ) $(PLINTHOBJ) $(TESTLIBOBJ) $(LOOBJ) $(AWLOBJ) 167 $(MPMOBJ) $(PLINTHOBJ) $(TESTLIBOBJ) $(LOOBJ) $(AWLOBJ)
diff --git a/mps/code/config.h b/mps/code/config.h
index ad8ec6f5246..0062aa99a69 100644
--- a/mps/code/config.h
+++ b/mps/code/config.h
@@ -2,15 +2,13 @@
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 * PURPOSE 7 * PURPOSE
7 * 8 *
8 * This module translates from high-level symbols defined by the 9 * This module translates from high-level symbols defined by the
9 * external build system (gnumake, nmake, etc.) into specific sets 10 * external build system (gnumake, nmake, etc.) into specific sets
10 * of features used by MPS modules. For example, the build system 11 * of features used by MPS modules.
11 * will defined one of the CONFIG_VAR_* symbols to indicate which
12 * variety it is building, this file translates that into a certain
13 * level of checking, and a certain level of telemetry.
14 * 12 *
15 * DESIGN 13 * DESIGN
16 * 14 *
@@ -21,65 +19,38 @@
21#define config_h 19#define config_h
22 20
23 21
24/* Variety Configuration 22/* Variety Configuration */
25 *
26 * Convert CONFIG_VAR_* defined on compiler command line into
27 * internal configuration parameters. See design.mps.config.var
28 * and design.mps.variety.macro. Note that MPS_HOT is subclassed
29 * into MPS_HOT_RED and MPS_HOT_WHITE; this distinction should
30 * be rarely used.
31 */
32 23
33#if defined(CONFIG_VAR_HI) /* Hot, Internal; variety.hi */ 24
34#define MPS_VARIETY_STRING "hi" 25#if defined(CONFIG_ASSERT)
35#define MPS_HOT 26#define CHECK
36#define MPS_HOT_RED 27#define MPS_ASSERT_STRING "asserted"
37#define EVENT_NONE 28#else
38#elif defined(CONFIG_VAR_CI) /* Cool, Internal; variety.ci */ 29#define CHECK_NONE
39#define MPS_VARIETY_STRING "ci" 30#define MPS_ASSERT_STRING "nonasserted"
40#define MPS_COOL 31#endif
41#define EVENT_NONE 32
42#elif defined(CONFIG_VAR_TI) /* Telemetry, Internal; variety.ti */ 33
43#define MPS_VARIETY_STRING "ti" 34#if defined(CONFIG_LOG)
44#define MPS_COOL
45#define EVENT
46#elif defined(CONFIG_VAR_HE) /* Hot, External; variety.he */
47#define MPS_VARIETY_STRING "he"
48#define MPS_HOT
49#define MPS_HOT_RED
50#define EVENT_NONE
51#elif defined(CONFIG_VAR_CE) /* Cool, External; variety.ce */
52#define MPS_VARIETY_STRING "ce"
53#define MPS_COOL
54#define EVENT_NONE
55#elif defined(CONFIG_VAR_WI) /* White hot, Internal; variety.wi */
56#define MPS_VARIETY_STRING "wi"
57#define MPS_HOT
58#define MPS_HOT_WHITE
59#define EVENT_NONE
60#elif defined(CONFIG_VAR_WE) /* White hot, External; variety.we */
61#define MPS_VARIETY_STRING "we"
62#define MPS_HOT
63#define MPS_HOT_WHITE
64#define EVENT_NONE
65#elif defined(CONFIG_VAR_II) /* Ice, Internal; variety.ii */
66#define MPS_VARIETY_STRING "ii"
67#define MPS_HOT
68#define MPS_HOT_RED
69#define EVENT 35#define EVENT
36#define MPS_LOG_STRING "logging"
70#else 37#else
71#error "No target variety configured." 38#define EVENT_NONE
39#define MPS_LOG_STRING "nonlogging"
72#endif 40#endif
73 41
74 42
75#if defined(EVENT) 43#if defined(CONFIG_DEBUG)
76#define DIAGNOSTICS 44#define DIAGNOSTICS
77#elif defined(EVENT_NONE) 45#define MPS_DEBUG_STRING "debug"
78#define DIAGNOSTICS_NONE
79#else 46#else
80#error "Events not configured." 47#define DIAGNOSTICS_NONE
48#define MPS_DEBUG_STRING "nondebug"
81#endif 49#endif
82 50
51#define MPS_VARIETY_STRING \
52 MPS_ASSERT_STRING "." MPS_LOG_STRING "." MPS_DEBUG_STRING
53
83 54
84/* Platform Configuration */ 55/* Platform Configuration */
85 56
@@ -125,12 +96,11 @@
125#endif /* MPS_ARCH_PP */ 96#endif /* MPS_ARCH_PP */
126 97
127 98
128/* In white-hot versions, absolutely no checking is done. This leads to 99/* Non-checking varieties give many spurious warnings because parameters
129 * many spurious warnings because parameters are suddenly unused, etc. 100 * are suddenly unused, etc. We aren't interested in these
130 * We aren't interested in these.
131 */ 101 */
132 102
133#if defined(MPS_HOT_WHITE) 103#if defined(CHECK_NONE)
134 104
135/* "unreferenced formal parameter" */ 105/* "unreferenced formal parameter" */
136#pragma warning(disable: 4100) 106#pragma warning(disable: 4100)
@@ -138,7 +108,7 @@
138/* "unreferenced local function has been removed" */ 108/* "unreferenced local function has been removed" */
139#pragma warning(disable: 4505) 109#pragma warning(disable: 4505)
140 110
141#endif /* MPS_HOT_WHITE */ 111#endif /* CHECK_NONE */
142 112
143#endif /* MPS_BUILD_MV */ 113#endif /* MPS_BUILD_MV */
144 114
@@ -240,7 +210,7 @@
240 * create a dependence on an external library. 210 * create a dependence on an external library.
241 */ 211 */
242 212
243#if defined(MPS_PF_W3I3MV) && defined(MPS_HOT) 213#if defined(MPS_PF_W3I3MV)
244/* MSVC on Intel inlines mem* when optimizing */ 214/* MSVC on Intel inlines mem* when optimizing */
245#define mps_lib_memset memset 215#define mps_lib_memset memset
246#define mps_lib_memcpy memcpy 216#define mps_lib_memcpy memcpy
@@ -264,6 +234,7 @@
264#define THREAD_SINGLE 234#define THREAD_SINGLE
265#define PROTECTION_NONE 235#define PROTECTION_NONE
266#define DONGLE_NONE 236#define DONGLE_NONE
237#define CHECK_DEFAULT CheckNONE /* CheckSHALLOW is too slow for SW */
267 238
268#elif defined(CONFIG_PROD_DYLAN) 239#elif defined(CONFIG_PROD_DYLAN)
269#define MPS_PROD_STRING "dylan" 240#define MPS_PROD_STRING "dylan"
@@ -277,6 +248,7 @@
277#define THREAD_MULTI 248#define THREAD_MULTI
278#define PROTECTION 249#define PROTECTION
279#define DONGLE_NONE 250#define DONGLE_NONE
251#define CHECK_DEFAULT CheckSHALLOW
280 252
281#elif defined(CONFIG_PROD_CONFIGURA) 253#elif defined(CONFIG_PROD_CONFIGURA)
282#define MPS_PROD_STRING "configura" 254#define MPS_PROD_STRING "configura"
@@ -293,6 +265,7 @@
293#define THREAD_MULTI 265#define THREAD_MULTI
294#define PROTECTION 266#define PROTECTION
295#define DONGLE_NONE 267#define DONGLE_NONE
268#define CHECK_DEFAULT CheckSHALLOW
296 269
297#else 270#else
298#error "No target product configured." 271#error "No target product configured."
diff --git a/mps/code/dbgpool.c b/mps/code/dbgpool.c
index bbd4bd23e56..62672d6810f 100644
--- a/mps/code/dbgpool.c
+++ b/mps/code/dbgpool.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 * .source: design.mps.object-debug 7 * .source: design.mps.object-debug
7 */ 8 */
@@ -9,9 +10,7 @@
9#include "dbgpool.h" 10#include "dbgpool.h"
10#include "poolmfs.h" 11#include "poolmfs.h"
11#include "splay.h" 12#include "splay.h"
12#include "mpslib.h"
13#include "mpm.h" 13#include "mpm.h"
14#include "mps.h"
15#include <stdarg.h> 14#include <stdarg.h>
16 15
17SRCID(dbgpool, "$Id$"); 16SRCID(dbgpool, "$Id$");
@@ -34,8 +33,7 @@ typedef tagStruct *Tag;
34 33
35/* tag init methods: copying the user-supplied data into the tag */ 34/* tag init methods: copying the user-supplied data into the tag */
36 35
37#define TagInitMethodCheck(f) \ 36#define TagInitMethodCheck(f) FUNCHECK(f)
38 ((f) != NULL) /* that's the best we can do */
39 37
40static void TagTrivInit(void* tag, va_list args) 38static void TagTrivInit(void* tag, va_list args)
41{ 39{
@@ -68,12 +66,16 @@ Bool PoolDebugMixinCheck(PoolDebugMixin debug)
68{ 66{
69 /* Nothing to check about fenceTemplate */ 67 /* Nothing to check about fenceTemplate */
70 /* Nothing to check about fenceSize */ 68 /* Nothing to check about fenceSize */
71 CHECKL(TagInitMethodCheck(debug->tagInit)); 69 /* Nothing to check about freeTemplate */
72 /* Nothing to check about tagSize */ 70 /* Nothing to check about freeSize */
73 CHECKD(Pool, debug->tagPool); 71 if (debug->tagInit != NULL) {
74 CHECKL(CHECKTYPE(Addr, void*)); /* tagPool relies on this */ 72 CHECKL(TagInitMethodCheck(debug->tagInit));
75 /* Nothing to check about missingTags */ 73 /* Nothing to check about tagSize */
76 CHECKL(SplayTreeCheck(&debug->index)); 74 CHECKD(Pool, debug->tagPool);
75 CHECKL(CHECKTYPE(Addr, void*)); /* tagPool relies on this */
76 /* Nothing to check about missingTags */
77 CHECKL(SplayTreeCheck(&debug->index));
78 }
77 UNUSED(debug); /* see impl.c.mpm.check.unused */ 79 UNUSED(debug); /* see impl.c.mpm.check.unused */
78 return TRUE; 80 return TRUE;
79} 81}
@@ -102,6 +104,10 @@ static Bool PoolDebugOptionsCheck(PoolDebugOptions opt)
102 CHECKL(opt->fenceTemplate != NULL); 104 CHECKL(opt->fenceTemplate != NULL);
103 /* Nothing to check about fenceSize */ 105 /* Nothing to check about fenceSize */
104 } 106 }
107 if (opt->freeSize != 0) {
108 CHECKL(opt->freeTemplate != NULL);
109 /* Nothing to check about freeSize */
110 }
105 return TRUE; 111 return TRUE;
106} 112}
107 113
@@ -150,7 +156,20 @@ static Res DebugPoolInit(Pool pool, va_list args)
150 } 156 }
151 debug->fenceTemplate = options->fenceTemplate; 157 debug->fenceTemplate = options->fenceTemplate;
152 } 158 }
153 159
160 /* free-checking init */
161 /* @@@@ This parses a user argument, options, so it should really */
162 /* go through the MPS interface. The template needs to be copied */
163 /* into Addr memory, to avoid breaking design.mps.type.addr.use. */
164 debug->freeSize = options->freeSize;
165 if (debug->freeSize != 0) {
166 if (PoolAlignment(pool) % debug->freeSize != 0) {
167 res = ResPARAM;
168 goto alignFail;
169 }
170 debug->freeTemplate = options->freeTemplate;
171 }
172
154 /* tag init */ 173 /* tag init */
155 debug->tagInit = tagInit; 174 debug->tagInit = tagInit;
156 if (debug->tagInit != NULL) { 175 if (debug->tagInit != NULL) {
@@ -195,7 +214,119 @@ static void DebugPoolFinish(Pool pool)
195} 214}
196 215
197 216
198/* FenceAlloc -- allocation wrapper for fenceposts 217/* freeSplat -- splat free block with splat pattern
218 *
219 * If base is in a segment, the whole block has to be in it.
220 */
221
222static void freeSplat(PoolDebugMixin debug, Pool pool, Addr base, Addr limit)
223{
224 Addr p, next;
225 Size freeSize = debug->freeSize;
226 Arena arena;
227 Seg seg;
228 Bool inSeg;
229
230 AVER(base < limit);
231
232 /* If the block is in a segment, make sure any shield is up. */
233 arena = PoolArena(pool);
234 inSeg = SegOfAddr(&seg, arena, base);
235 if (inSeg) {
236 AVER(limit <= SegLimit(seg));
237 ShieldExpose(arena, seg);
238 }
239 /* Write as many copies of the template as fit in the block. */
240 for (p = base, next = AddrAdd(p, freeSize);
241 next <= limit && p < next /* watch out for overflow in next */;
242 p = next, next = AddrAdd(next, freeSize))
243 (void)AddrCopy(p, debug->freeTemplate, freeSize);
244 /* Fill the tail of the block with a partial copy of the template. */
245 if (next > limit || next < p)
246 (void)AddrCopy(p, debug->freeTemplate, AddrOffset(p, limit));
247 if (inSeg) {
248 ShieldCover(arena, seg);
249 }
250}
251
252
253/* freeCheck -- check free block for splat pattern */
254
255static Bool freeCheck(PoolDebugMixin debug, Pool pool, Addr base, Addr limit)
256{
257 Addr p, next;
258 Size freeSize = debug->freeSize;
259 Res res;
260 Arena arena;
261 Seg seg;
262 Bool inSeg;
263
264 AVER(base < limit);
265
266 /* If the block is in a segment, make sure any shield is up. */
267 arena = PoolArena(pool);
268 inSeg = SegOfAddr(&seg, arena, base);
269 if (inSeg) {
270 AVER(limit <= SegLimit(seg));
271 ShieldExpose(arena, seg);
272 }
273 /* Compare this to the AddrCopys in freeSplat. */
274 /* Check the complete copies of the template in the block. */
275 for (p = base, next = AddrAdd(p, freeSize);
276 next <= limit && p < next /* watch out for overflow in next */;
277 p = next, next = AddrAdd(next, freeSize))
278 if (AddrComp(p, debug->freeTemplate, freeSize) != 0) {
279 res = FALSE; goto done;
280 }
281 /* Check the partial copy of the template at the tail of the block. */
282 if (next > limit || next < p)
283 if (AddrComp(p, debug->freeTemplate, AddrOffset(p, limit)) != 0) {
284 res = FALSE; goto done;
285 }
286 res = TRUE;
287
288done:
289 if (inSeg) {
290 ShieldCover(arena, seg);
291 }
292 return res;
293}
294
295
296/* freeCheckAlloc -- allocation wrapper for free-checking */
297
298static Res freeCheckAlloc(Addr *aReturn, PoolDebugMixin debug, Pool pool,
299 Size size, Bool withReservoir)
300{
301 Res res;
302 Addr new;
303
304 AVER(aReturn != NULL);
305
306 res = SuperclassOfPool(pool)->alloc(&new, pool, size, withReservoir);
307 if (res != ResOK)
308 return res;
309 if (debug->freeSize != 0)
310 ASSERT(freeCheck(debug, pool, new, AddrAdd(new, size)),
311 "free space corrupted on alloc");
312
313 *aReturn = new;
314 return res;
315}
316
317
318/* freeCheckFree -- freeing wrapper for free-checking */
319
320static void freeCheckFree(PoolDebugMixin debug,
321 Pool pool, Addr old, Size size)
322{
323 if (debug->freeSize != 0)
324 freeSplat(debug, pool, old, AddrAdd(old, size));
325 SuperclassOfPool(pool)->free(pool, old, size);
326}
327
328
329/* fenceAlloc -- allocation wrapper for fenceposts
199 * 330 *
200 * Allocates an object, adding fenceposts on both sides. Layout: 331 * Allocates an object, adding fenceposts on both sides. Layout:
201 * 332 *
@@ -211,7 +342,7 @@ static void DebugPoolFinish(Pool pool)
211 * the template is larger). 342 * the template is larger).
212 */ 343 */
213 344
214static Res FenceAlloc(Addr *aReturn, PoolDebugMixin debug, Pool pool, 345static Res fenceAlloc(Addr *aReturn, PoolDebugMixin debug, Pool pool,
215 Size size, Bool withReservoir) 346 Size size, Bool withReservoir)
216{ 347{
217 Res res; 348 Res res;
@@ -219,37 +350,31 @@ static Res FenceAlloc(Addr *aReturn, PoolDebugMixin debug, Pool pool,
219 Size alignedSize; 350 Size alignedSize;
220 351
221 AVER(aReturn != NULL); 352 AVER(aReturn != NULL);
222 AVERT(PoolDebugMixin, debug);
223 AVERT(Pool, pool);
224 AVER(size > 0);
225 AVERT(Bool, withReservoir);
226 353
227 alignedSize = SizeAlignUp(size, PoolAlignment(pool)); 354 alignedSize = SizeAlignUp(size, PoolAlignment(pool));
228 res = SuperclassOfPool(pool)->alloc(&new, pool, 355 res = freeCheckAlloc(&new, debug, pool, alignedSize + 2*debug->fenceSize,
229 alignedSize + 2*debug->fenceSize, 356 withReservoir);
230 withReservoir);
231 if (res != ResOK) 357 if (res != ResOK)
232 return res; 358 return res;
233 clientNew = AddrAdd(new, debug->fenceSize); 359 clientNew = AddrAdd(new, debug->fenceSize);
234 /* @@@@ shields? */ 360 /* @@@@ shields? */
235 /* start fencepost */ 361 /* start fencepost */
236 AddrCopy(new, debug->fenceTemplate, debug->fenceSize); 362 (void)AddrCopy(new, debug->fenceTemplate, debug->fenceSize);
237 /* alignment slop */ 363 /* alignment slop */
238 AddrCopy(AddrAdd(clientNew, size), 364 (void)AddrCopy(AddrAdd(clientNew, size),
239 debug->fenceTemplate, alignedSize - size); 365 debug->fenceTemplate, alignedSize - size);
240 /* end fencepost */ 366 /* end fencepost */
241 AddrCopy(AddrAdd(clientNew, alignedSize), 367 (void)AddrCopy(AddrAdd(clientNew, alignedSize),
242 debug->fenceTemplate, debug->fenceSize); 368 debug->fenceTemplate, debug->fenceSize);
243 369
244 *aReturn = clientNew; 370 *aReturn = clientNew;
245 return res; 371 return res;
246} 372}
247 373
248 374
249/* FenceCheck -- check fences of an object */ 375/* fenceCheck -- check fences of an object */
250 376
251static Bool FenceCheck(PoolDebugMixin debug, Pool pool, 377static Bool fenceCheck(PoolDebugMixin debug, Pool pool, Addr obj, Size size)
252 Addr obj, Size size)
253{ 378{
254 Size alignedSize; 379 Size alignedSize;
255 380
@@ -258,7 +383,8 @@ static Bool FenceCheck(PoolDebugMixin debug, Pool pool,
258 /* Can't check obj */ 383 /* Can't check obj */
259 384
260 alignedSize = SizeAlignUp(size, PoolAlignment(pool)); 385 alignedSize = SizeAlignUp(size, PoolAlignment(pool));
261 /* Compare this to the memcpy's in FenceAlloc */ 386 /* @@@@ shields? */
387 /* Compare this to the AddrCopys in fenceAlloc */
262 return (AddrComp(AddrSub(obj, debug->fenceSize), debug->fenceTemplate, 388 return (AddrComp(AddrSub(obj, debug->fenceSize), debug->fenceTemplate,
263 debug->fenceSize) == 0 389 debug->fenceSize) == 0
264 && AddrComp(AddrAdd(obj, size), debug->fenceTemplate, 390 && AddrComp(AddrAdd(obj, size), debug->fenceTemplate,
@@ -268,38 +394,30 @@ static Bool FenceCheck(PoolDebugMixin debug, Pool pool,
268} 394}
269 395
270 396
271/* FenceFree -- freeing wrapper for fenceposts */ 397/* fenceFree -- freeing wrapper for fenceposts */
272 398
273static void FenceFree(PoolDebugMixin debug, 399static void fenceFree(PoolDebugMixin debug,
274 Pool pool, Addr old, Size size) 400 Pool pool, Addr old, Size size)
275{ 401{
276 Size alignedSize; 402 Size alignedSize;
277 403
278 AVERT(PoolDebugMixin, debug); 404 ASSERT(fenceCheck(debug, pool, old, size), "fencepost check on free");
279 AVERT(Pool, pool);
280 /* Can't check old */
281 AVER(size > 0);
282
283 ASSERT(FenceCheck(debug, pool, old, size), "fencepost check on free");
284 405
285 alignedSize = SizeAlignUp(size, PoolAlignment(pool)); 406 alignedSize = SizeAlignUp(size, PoolAlignment(pool));
286 SuperclassOfPool(pool)->free(pool, AddrSub(old, debug->fenceSize), 407 freeCheckFree(debug, pool, AddrSub(old, debug->fenceSize),
287 alignedSize + 2*debug->fenceSize); 408 alignedSize + 2*debug->fenceSize);
288} 409}
289 410
290 411
291/* TagAlloc -- allocation wrapper for tagged pools */ 412/* tagAlloc -- allocation wrapper for tagged pools */
292 413
293static Res TagAlloc(PoolDebugMixin debug, 414static Res tagAlloc(PoolDebugMixin debug,
294 Pool pool, Addr new, Size size, Bool withReservoir) 415 Pool pool, Addr new, Size size, Bool withReservoir)
295{ 416{
296 Tag tag; 417 Tag tag;
297 Res res; 418 Res res;
298 419
299 AVERT(PoolDebugMixin, debug); 420 UNUSED(pool);
300 AVERT(Pool, pool);
301 AVER(size > 0);
302
303 res = PoolAlloc((Addr*)&tag, debug->tagPool, debug->tagSize, FALSE); 421 res = PoolAlloc((Addr*)&tag, debug->tagPool, debug->tagSize, FALSE);
304 if (res != ResOK) { 422 if (res != ResOK) {
305 if (withReservoir) { /* design.mps.object-debug.out-of-space */ 423 if (withReservoir) { /* design.mps.object-debug.out-of-space */
@@ -318,9 +436,9 @@ static Res TagAlloc(PoolDebugMixin debug,
318} 436}
319 437
320 438
321/* TagFree -- deallocation wrapper for tagged pools */ 439/* tagFree -- deallocation wrapper for tagged pools */
322 440
323static void TagFree(PoolDebugMixin debug, Pool pool, Addr old, Size size) 441static void tagFree(PoolDebugMixin debug, Pool pool, Addr old, Size size)
324{ 442{
325 SplayNode node; 443 SplayNode node;
326 Tag tag; 444 Tag tag;
@@ -351,7 +469,7 @@ static void TagFree(PoolDebugMixin debug, Pool pool, Addr old, Size size)
351 */ 469 */
352 470
353static Res DebugPoolAlloc(Addr *aReturn, 471static Res DebugPoolAlloc(Addr *aReturn,
354 Pool pool, Size size, Bool withReservoir) 472 Pool pool, Size size, Bool withReservoir)
355{ 473{
356 Res res; 474 Res res;
357 Addr new; 475 Addr new;
@@ -365,19 +483,24 @@ static Res DebugPoolAlloc(Addr *aReturn,
365 debug = DebugPoolDebugMixin(pool); 483 debug = DebugPoolDebugMixin(pool);
366 AVER(debug != NULL); 484 AVER(debug != NULL);
367 AVERT(PoolDebugMixin, debug); 485 AVERT(PoolDebugMixin, debug);
368 res = FenceAlloc(&new, debug, pool, size, withReservoir); 486 if (debug->fenceSize != 0)
487 res = fenceAlloc(&new, debug, pool, size, withReservoir);
488 else
489 res = freeCheckAlloc(&new, debug, pool, size, withReservoir);
369 if (res != ResOK) 490 if (res != ResOK)
370 return res; 491 return res;
371 /* Allocate object first, so it fits even when the tag doesn't. */ 492 /* Allocate object first, so it fits even when the tag doesn't. */
372 res = TagAlloc(debug, pool, new, size, withReservoir); 493 if (debug->tagInit != NULL) {
373 if (res != ResOK) 494 res = tagAlloc(debug, pool, new, size, withReservoir);
374 goto tagFail; 495 if (res != ResOK)
496 goto tagFail;
497 }
375 498
376 *aReturn = new; 499 *aReturn = new;
377 return res; 500 return res;
378 501
379tagFail: 502tagFail:
380 FenceFree(debug, pool, new, size); 503 fenceFree(debug, pool, new, size);
381 return res; 504 return res;
382} 505}
383 506
@@ -395,13 +518,18 @@ static void DebugPoolFree(Pool pool, Addr old, Size size)
395 debug = DebugPoolDebugMixin(pool); 518 debug = DebugPoolDebugMixin(pool);
396 AVER(debug != NULL); 519 AVER(debug != NULL);
397 AVERT(PoolDebugMixin, debug); 520 AVERT(PoolDebugMixin, debug);
398 FenceFree(debug, pool, old, size); 521
522 if (debug->fenceSize != 0)
523 fenceFree(debug, pool, old, size);
524 else
525 freeCheckFree(debug, pool, old, size);
399 /* Free the object first, to get fences checked before tag. */ 526 /* Free the object first, to get fences checked before tag. */
400 TagFree(debug, pool, old, size); 527 if (debug->tagInit != NULL)
528 tagFree(debug, pool, old, size);
401} 529}
402 530
403 531
404/* TagWalk -- walk all object in the pool using tags */ 532/* TagWalk -- walk all objects in the pool using tags */
405 533
406typedef void (*ObjectsStepMethod)(Addr addr, Size size, Format fmt, 534typedef void (*ObjectsStepMethod)(Addr addr, Size size, Format fmt,
407 Pool pool, void *tagData, void *p); 535 Pool pool, void *tagData, void *p);
@@ -434,21 +562,21 @@ static void TagWalk(Pool pool, ObjectsStepMethod step, void *p)
434} 562}
435 563
436 564
437/* FenceCheckingStep -- step function for DebugPoolCheckFences */ 565/* fenceCheckingStep -- step function for DebugPoolCheckFences */
438 566
439static void FenceCheckingStep(Addr addr, Size size, Format fmt, 567static void fenceCheckingStep(Addr addr, Size size, Format fmt,
440 Pool pool, void *tagData, void *p) 568 Pool pool, void *tagData, void *p)
441{ 569{
442 /* no need to check arguments checked in the caller */ 570 /* no need to check arguments checked in the caller */
443 UNUSED(fmt); UNUSED(tagData); 571 UNUSED(fmt); UNUSED(tagData);
444 ASSERT(FenceCheck((PoolDebugMixin)p, pool, addr, size), 572 ASSERT(fenceCheck((PoolDebugMixin)p, pool, addr, size),
445 "fencepost check requested by client"); 573 "fencepost check requested by client");
446} 574}
447 575
448 576
449/* DebugPoolCheckFences -- check all the fenceposts in the pool */ 577/* DebugPoolCheckFences -- check all the fenceposts in the pool */
450 578
451static void DebugPoolCheckFences(Pool pool) 579void DebugPoolCheckFences(Pool pool)
452{ 580{
453 PoolDebugMixin debug; 581 PoolDebugMixin debug;
454 582
@@ -458,37 +586,84 @@ static void DebugPoolCheckFences(Pool pool)
458 return; 586 return;
459 AVERT(PoolDebugMixin, debug); 587 AVERT(PoolDebugMixin, debug);
460 588
461 TagWalk(pool, FenceCheckingStep, (void *)debug); 589 if (debug->fenceSize != 0)
590 TagWalk(pool, fenceCheckingStep, (void *)debug);
462} 591}
463 592
464 593
465/* PoolClassMixInDebug -- mix in the debug support for class init */ 594/* DebugPoolFreeSplat -- if in a free-checking debug pool, splat free block */
466 595
467void PoolClassMixInDebug(PoolClass class) 596void DebugPoolFreeSplat(Pool pool, Addr base, Addr limit)
468{ 597{
469 /* Can't check class because it's not initialized yet */ 598 PoolDebugMixin debug;
470 class->init = DebugPoolInit; 599
471 class->finish = DebugPoolFinish; 600 AVERT(Pool, pool);
472 class->alloc = DebugPoolAlloc; 601 AVER(PoolHasAddr(pool, base));
473 class->free = DebugPoolFree; 602 AVER(PoolHasAddr(pool, AddrSub(limit, 1)));
603
604 debug = DebugPoolDebugMixin(pool);
605 if (debug != NULL) {
606 AVERT(PoolDebugMixin, debug);
607 if (debug->freeSize != 0)
608 freeSplat(debug, pool, base, limit);
609 }
474} 610}
475 611
476 612
477/* mps_pool_check_fenceposts -- check all the fenceposts in the pool */ 613/* DebugPoolFreeCheck -- if in a free-checking debug pool, check free block */
478 614
479void mps_pool_check_fenceposts(mps_pool_t mps_pool) 615void DebugPoolFreeCheck(Pool pool, Addr base, Addr limit)
480{ 616{
481 Pool pool = (Pool)mps_pool; 617 PoolDebugMixin debug;
482 Arena arena;
483
484 /* CHECKT not AVERT, see design.mps.interface.c.check.space */
485 AVER(CHECKT(Pool, pool));
486 arena = PoolArena(pool);
487 618
488 ArenaEnter(arena); 619 AVERT(Pool, pool);
620 AVER(PoolHasAddr(pool, base));
621 AVER(PoolHasAddr(pool, AddrSub(limit, 1)));
622
623 debug = DebugPoolDebugMixin(pool);
624 if (debug != NULL) {
625 AVERT(PoolDebugMixin, debug);
626 if (debug->freeSize != 0)
627 ASSERT(freeCheck(debug, pool, base, limit),
628 "free space corrupted on release");
629 }
630}
631
632
633/* freeCheckingStep -- step function for DebugPoolCheckFreeSpace */
634
635static void freeCheckingStep(Addr base, Addr limit, Pool pool, void *p)
636{
637 /* no need to check arguments checked in the caller */
638 ASSERT(freeCheck((PoolDebugMixin)p, pool, base, limit),
639 "free space corrupted on client check");
640}
641
642
643/* DebugPoolCheckFreeSpace -- check free space in the pool for overwrites */
644
645void DebugPoolCheckFreeSpace(Pool pool)
646{
647 PoolDebugMixin debug;
489 648
490 AVERT(Pool, pool); 649 AVERT(Pool, pool);
491 DebugPoolCheckFences(pool); 650 debug = DebugPoolDebugMixin(pool);
651 if (debug == NULL)
652 return;
653 AVERT(PoolDebugMixin, debug);
654
655 if (debug->freeSize != 0)
656 PoolFreeWalk(pool, freeCheckingStep, (void *)debug);
657}
658
659
660/* PoolClassMixInDebug -- mix in the debug support for class init */
492 661
493 ArenaLeave(arena); 662void PoolClassMixInDebug(PoolClass class)
663{
664 /* Can't check class because it's not initialized yet */
665 class->init = DebugPoolInit;
666 class->finish = DebugPoolFinish;
667 class->alloc = DebugPoolAlloc;
668 class->free = DebugPoolFree;
494} 669}
diff --git a/mps/code/dbgpool.h b/mps/code/dbgpool.h
index 6632606787d..d78610504fb 100644
--- a/mps/code/dbgpool.h
+++ b/mps/code/dbgpool.h
@@ -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#ifndef dbgpool_h 8#ifndef dbgpool_h
@@ -25,6 +26,8 @@ typedef void (*TagInitMethod)(void* tag, va_list args);
25typedef struct PoolDebugOptionsStruct { 26typedef struct PoolDebugOptionsStruct {
26 void* fenceTemplate; 27 void* fenceTemplate;
27 Size fenceSize; 28 Size fenceSize;
29 void* freeTemplate;
30 Size freeSize;
28 /* TagInitMethod tagInit; */ 31 /* TagInitMethod tagInit; */
29 /* Size tagSize; */ 32 /* Size tagSize; */
30} PoolDebugOptionsStruct; 33} PoolDebugOptionsStruct;
@@ -40,6 +43,8 @@ typedef struct PoolDebugMixinStruct {
40 Sig sig; 43 Sig sig;
41 Addr fenceTemplate; 44 Addr fenceTemplate;
42 Size fenceSize; 45 Size fenceSize;
46 Addr freeTemplate;
47 Size freeSize;
43 TagInitMethod tagInit; 48 TagInitMethod tagInit;
44 Size tagSize; 49 Size tagSize;
45 Pool tagPool; 50 Pool tagPool;
@@ -50,8 +55,13 @@ typedef struct PoolDebugMixinStruct {
50 55
51extern Bool PoolDebugMixinCheck(PoolDebugMixin dbg); 56extern Bool PoolDebugMixinCheck(PoolDebugMixin dbg);
52 57
53
54extern void PoolClassMixInDebug(PoolClass class); 58extern void PoolClassMixInDebug(PoolClass class);
55 59
60extern void DebugPoolCheckFences(Pool pool);
61extern void DebugPoolCheckFreeSpace(Pool pool);
62
63extern void DebugPoolFreeSplat(Pool pool, Addr base, Addr limit);
64extern void DebugPoolFreeCheck(Pool pool, Addr base, Addr limit);
65
56 66
57#endif /* dbgpool_h */ 67#endif /* dbgpool_h */
diff --git a/mps/code/dbgpooli.c b/mps/code/dbgpooli.c
new file mode 100644
index 00000000000..b38a0ee837d
--- /dev/null
+++ b/mps/code/dbgpooli.c
@@ -0,0 +1,54 @@
1/* impl.c.dbgpooli: POOL DEBUG MIXIN C INTERFACE
2 *
3 * $Id: dbgpooli.c,v 1.3 2002/02/01 14:27:26 pekka Exp $
4 * $HopeName: MMsrc!dbgpooli.c(trunk.3) $
5 * Copyright (C) 2002 Global Graphics Software.
6 *
7 * .source: design.mps.object-debug
8 */
9
10#include "dbgpool.h"
11#include "mps.h"
12#include "mpm.h"
13
14SRCID(dbgpooli, "$Id: dbgpooli.c,v 1.3 2002/02/01 14:27:26 pekka Exp $");
15
16
17/* mps_pool_check_fenceposts -- check all the fenceposts in the pool */
18
19void mps_pool_check_fenceposts(mps_pool_t mps_pool)
20{
21 Pool pool = (Pool)mps_pool;
22 Arena arena;
23
24 /* CHECKT not AVERT, see design.mps.interface.c.check.space */
25 AVER(CHECKT(Pool, pool));
26 arena = PoolArena(pool);
27
28 ArenaEnter(arena);
29
30 AVERT(Pool, pool);
31 DebugPoolCheckFences(pool);
32
33 ArenaLeave(arena);
34}
35
36
37/* mps_pool_check_free_space -- check free space in the pool for overwrites */
38
39void mps_pool_check_free_space(mps_pool_t mps_pool)
40{
41 Pool pool = (Pool)mps_pool;
42 Arena arena;
43
44 /* CHECKT not AVERT, see design.mps.interface.c.check.space */
45 AVER(CHECKT(Pool, pool));
46 arena = PoolArena(pool);
47
48 ArenaEnter(arena);
49
50 AVERT(Pool, pool);
51 DebugPoolCheckFreeSpace(pool);
52
53 ArenaLeave(arena);
54}
diff --git a/mps/code/eventcnv.c b/mps/code/eventcnv.c
index e93030b2055..c7e6ffaa515 100644
--- a/mps/code/eventcnv.c
+++ b/mps/code/eventcnv.c
@@ -1,5 +1,4 @@
1/* impl.c.eventcnv: Simple event log converter 1/* impl.c.eventcnv: Simple event log converter
2 * Copyright (c) 2001 Ravenbrook Limited.
3 * 2 *
4 * $Id$ 3 * $Id$
5 */ 4 */
diff --git a/mps/code/eventgen.h b/mps/code/eventgen.h
index 3071a9efe43..ecfc946aabc 100644
--- a/mps/code/eventgen.h
+++ b/mps/code/eventgen.h
@@ -1,7 +1,6 @@
1/* impl.h.eventgen -- Automatic event header 1/* impl.h.eventgen -- Automatic event header
2 * 2 *
3 * $Id$ 3 * $Id$
4 * $HopeName$
5 * Copyright (c) 2001 Ravenbrook Limited. 4 * Copyright (c) 2001 Ravenbrook Limited.
6 * 5 *
7 * DO NOT EDIT THIS FILE! 6 * DO NOT EDIT THIS FILE!
diff --git a/mps/code/finalcv.c b/mps/code/finalcv.c
index 1fa1a5cfd94..bc7537ec542 100644
--- a/mps/code/finalcv.c
+++ b/mps/code/finalcv.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 * DESIGN 7 * DESIGN
7 * 8 *
@@ -32,7 +33,10 @@
32 33
33#define testArenaSIZE ((size_t)16<<20) 34#define testArenaSIZE ((size_t)16<<20)
34#define rootCOUNT 20 35#define rootCOUNT 20
35#define churnFACTOR 30 36#define churnFACTOR 10
37#define finalizationRATE 6
38#define gcINTERVAL ((size_t)150 * 1024)
39#define collectionCOUNT 3
36#define slotSIZE (3*sizeof(mps_word_t)) 40#define slotSIZE (3*sizeof(mps_word_t))
37#define genCOUNT 2 41#define genCOUNT 2
38 42
@@ -65,17 +69,25 @@ static void churn(mps_ap_t ap)
65 mps_addr_t p; 69 mps_addr_t p;
66 mps_res_t e; 70 mps_res_t e;
67 71
68 for(i = 0; i < churnFACTOR; ++i) { 72 for (i = 0; i < churnFACTOR; ++i) {
69 do { 73 do {
70 MPS_RESERVE_BLOCK(e, p, ap, 4096); 74 MPS_RESERVE_BLOCK(e, p, ap, 4096);
71 die(e, "MPS_RESERVE_BLOCK"); 75 die(e, "MPS_RESERVE_BLOCK");
72 die(dylan_init(p, 4096, root, 1), "dylan_init"); 76 die(dylan_init(p, 4096, root, 1), "dylan_init");
73 } while(!mps_commit(ap, p, 4096)); 77 } while (!mps_commit(ap, p, 4096));
74 } 78 }
75 p = NULL; 79 p = NULL;
76} 80}
77 81
78 82
83enum {
84 rootSTATE,
85 deadSTATE,
86 finalizableSTATE,
87 finalizedSTATE
88};
89
90
79static void *test(void *arg, size_t s) 91static void *test(void *arg, size_t s)
80{ 92{
81 int i; /* index */ 93 int i; /* index */
@@ -85,8 +97,12 @@ static void *test(void *arg, size_t s)
85 mps_pool_t amc; 97 mps_pool_t amc;
86 mps_res_t e; 98 mps_res_t e;
87 mps_root_t mps_root[2]; 99 mps_root_t mps_root[2];
100 int state[rootCOUNT];
88 mps_arena_t arena; 101 mps_arena_t arena;
89 void *p = NULL; 102 void *p = NULL;
103#ifdef CONFIG_PROD_EPCORE
104 size_t gcThreshold;
105#endif
90 mps_message_t message; 106 mps_message_t message;
91 107
92 arena = (mps_arena_t)arg; 108 arena = (mps_arena_t)arg;
@@ -105,30 +121,48 @@ static void *test(void *arg, size_t s)
105 die(mps_ap_create(&ap, amc, MPS_RANK_EXACT), "ap_create\n"); 121 die(mps_ap_create(&ap, amc, MPS_RANK_EXACT), "ap_create\n");
106 122
107 /* design.mps.poolmrg.test.promise.ut.alloc */ 123 /* design.mps.poolmrg.test.promise.ut.alloc */
108 for(i = 0; i < rootCOUNT; ++i) { 124 for (i = 0; i < rootCOUNT; ++i) {
109 do { 125 do {
110 MPS_RESERVE_BLOCK(e, p, ap, slotSIZE); 126 MPS_RESERVE_BLOCK(e, p, ap, slotSIZE);
111 die(e, "MPS_RES_OK"); 127 die(e, "MPS_RES_OK");
112 die(dylan_init(p, slotSIZE, root, 1), "dylan_init"); 128 die(dylan_init(p, slotSIZE, root, 1), "dylan_init");
113 } while(!mps_commit(ap, p, slotSIZE)); 129 } while (!mps_commit(ap, p, slotSIZE));
114 ((mps_word_t *)p)[2] = dylan_int(i); 130 ((mps_word_t *)p)[2] = dylan_int(i);
115 die(mps_finalize(arena, &p), "finalize\n"); 131 die(mps_finalize(arena, &p), "finalize\n");
116 root[i] = p; 132 root[i] = p; state[i] = rootSTATE;
117 } 133 }
118 p = NULL; 134 p = NULL;
119 135
120 /* design.mps.poolmrg.test.promise.ut.drop */
121 for(i = 0; i < rootCOUNT; ++i) {
122 if (rnd() % 2 == 0)
123 root[i] = NULL;
124 }
125
126 mps_message_type_enable(arena, mps_message_type_finalization()); 136 mps_message_type_enable(arena, mps_message_type_finalization());
127 137
138#ifdef CONFIG_PROD_EPCORE
139 gcThreshold = mps_arena_committed(arena) + gcINTERVAL;
140#endif
128 /* design.mps.poolmrg.test.promise.ut.churn */ 141 /* design.mps.poolmrg.test.promise.ut.churn */
129 while(mps_collections(arena) < 3) { 142 while (mps_collections(arena) < collectionCOUNT) {
130 churn(ap); 143 churn(ap);
131 while(mps_message_poll(arena)) { 144 /* design.mps.poolmrg.test.promise.ut.drop */
145 for (i = 0; i < rootCOUNT; ++i) {
146 if (root[i] != NULL && state[i] == rootSTATE) {
147 if (rnd() % finalizationRATE == 0) {
148 /* definalize some of them */
149 if (rnd() % 2 == 0) {
150 die(mps_definalize(arena, &root[i]), "definalize\n");
151 state[i] = deadSTATE;
152 } else {
153 state[i] = finalizableSTATE;
154 }
155 root[i] = NULL;
156 }
157 }
158 }
159#ifdef CONFIG_PROD_EPCORE
160 if (mps_arena_committed(arena) > gcThreshold) {
161 die(mps_arena_collect(arena), "collect");
162 gcThreshold = mps_arena_committed(arena) + gcINTERVAL;
163 }
164#endif
165 while (mps_message_poll(arena)) {
132 mps_word_t *obj; 166 mps_word_t *obj;
133 mps_word_t objind; 167 mps_word_t objind;
134 mps_addr_t objaddr; 168 mps_addr_t objaddr;
@@ -141,8 +175,12 @@ static void *test(void *arg, size_t s)
141 objind = dylan_int_int(obj[2]); 175 objind = dylan_int_int(obj[2]);
142 printf("Finalizing: object %lu at %p\n", objind, objaddr); 176 printf("Finalizing: object %lu at %p\n", objind, objaddr);
143 /* design.mps.poolmrg.test.promise.ut.final.check */ 177 /* design.mps.poolmrg.test.promise.ut.final.check */
144 cdie(root[objind] == NULL, "died"); 178 cdie(root[objind] == NULL, "finalized live");
145 root[objind] = objaddr; 179 cdie(state[objind] == finalizableSTATE, "finalized dead");
180 state[objind] = finalizedSTATE;
181 /* sometimes resurrect */
182 if (rnd() % 2 == 0)
183 root[objind] = objaddr;
146 mps_message_discard(arena, message); 184 mps_message_discard(arena, message);
147 } 185 }
148 } 186 }
diff --git a/mps/code/fmtdy.c b/mps/code/fmtdy.c
index 52d9d871f98..ce517aa24fd 100644
--- a/mps/code/fmtdy.c
+++ b/mps/code/fmtdy.c
@@ -1,7 +1,8 @@
1/* impl.c.fmtdy: DYLAN OBJECT FORMAT IMPLEMENTATION 1/* impl.c.fmtdy: DYLAN OBJECT FORMAT IMPLEMENTATION
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 * .readership: MPS developers, Dylan developers 7 * .readership: MPS developers, Dylan developers
7 * 8 *
@@ -56,29 +57,14 @@
56#include <assert.h> 57#include <assert.h>
57#include <string.h> 58#include <string.h>
58#include <stdlib.h> 59#include <stdlib.h>
59 60#include <limits.h>
60#ifdef MPS_PF_SUS8LC
61/* .hack.stderr: builder.lc (LCC) uses Sun's header files. Sun's
62 * assert.h is broken, as it assumes it can use stderr. We have to
63 * fix it by supplying stderr.
64 */
65#include <stdio.h>
66#endif
67 61
68 62
69#define notreached() assert(0) 63#define notreached() assert(0)
70#define unused(param) ((void)param) 64#define unused(param) ((void)param)
71 65
72#ifdef MPS_BUILD_MV
73 66
74/* MSVC 2.0 generates a warning for unused(). */
75#ifdef _MSC_VER 67#ifdef _MSC_VER
76#if _MSC_VER < 1000
77#pragma warning(disable: 4705)
78#endif
79#else /* _MSC_VER */
80#error "Expected _MSC_VER to be defined for builder.mv"
81#endif /* _MSC_VER */
82 68
83/* MPS_END causes "constant conditional" warnings. */ 69/* MPS_END causes "constant conditional" warnings. */
84#pragma warning(disable: 4127) 70#pragma warning(disable: 4127)
@@ -87,11 +73,15 @@
87/* has been removed". */ 73/* has been removed". */
88#pragma warning(disable: 4514) 74#pragma warning(disable: 4514)
89 75
90#endif /* MPS_BUILD_MV */ 76#endif /* _MSC_VER */
91 77
92 78
93#define ALIGN sizeof(mps_word_t) 79#define ALIGN sizeof(mps_word_t)
94 80
81#define MPS_WORD_WIDTH (sizeof(mps_word_t) * CHAR_BIT)
82#define MPS_WORD_SHIFT (MPS_WORD_WIDTH == 64 ? 6 : 5)
83/* MPS_WORD_SHIFT is a bit hacky, but good enough for tests. */
84
95#ifdef FMTDY_COUNTING 85#ifdef FMTDY_COUNTING
96#define FMTDY_COUNT(x) x 86#define FMTDY_COUNT(x) x
97#define FMTDY_FL_LIMIT 16 87#define FMTDY_FL_LIMIT 16
@@ -198,7 +188,7 @@ int dylan_wrapper_check(mps_word_t *w)
198 assert(ff == 2 || t == 0); 188 assert(ff == 2 || t == 0);
199 189
200 /* The number of patterns is (fixed fields+31)/32. */ 190 /* The number of patterns is (fixed fields+31)/32. */
201 assert(ff != 2 || t == ((fl + MPS_WORD_WIDTH - 1) >> MPS_WORD_SHIFT)); 191 assert(ff != 2 || t == ((fl + MPS_WORD_WIDTH - 1) / MPS_WORD_WIDTH));
202 192
203 /* The patterns are random bits, so we can't check them. However, */ 193 /* The patterns are random bits, so we can't check them. However, */
204 /* the left-over bits in the last pattern should be zero. */ 194 /* the left-over bits in the last pattern should be zero. */
@@ -361,12 +351,14 @@ static mps_res_t dylan_scan_pat(mps_ss_t mps_ss,
361 return MPS_RES_OK; 351 return MPS_RES_OK;
362} 352}
363 353
354
364#define NONWORD_LENGTH(_vt, _es) \ 355#define NONWORD_LENGTH(_vt, _es) \
365 ((_es) < MPS_WORD_SHIFT ? \ 356 ((_es) < MPS_WORD_SHIFT ? \
366 ((_vt) + (1 << (MPS_WORD_SHIFT - (_es))) - 1) >> \ 357 ((_vt) + (1 << (MPS_WORD_SHIFT - (_es))) - 1) >> \
367 (MPS_WORD_SHIFT - (_es)) : \ 358 (MPS_WORD_SHIFT - (_es)) : \
368 (_vt) << ((_es) - MPS_WORD_SHIFT)) 359 (_vt) << ((_es) - MPS_WORD_SHIFT))
369 360
361
370extern mps_res_t dylan_scan1(mps_ss_t mps_ss, mps_addr_t *object_io) 362extern mps_res_t dylan_scan1(mps_ss_t mps_ss, mps_addr_t *object_io)
371{ 363{
372 mps_addr_t *p; /* cursor in object */ 364 mps_addr_t *p; /* cursor in object */
@@ -408,7 +400,8 @@ extern mps_res_t dylan_scan1(mps_ss_t mps_ss, mps_addr_t *object_io)
408 return MPS_RES_OK; 400 return MPS_RES_OK;
409 } 401 }
410 402
411 mps_fix(mps_ss, p); /* fix the wrapper */ 403 res = mps_fix(mps_ss, p); /* fix the wrapper */
404 if ( res != MPS_RES_OK ) return res;
412 w = (mps_word_t *)p[0]; /* wrapper is header word */ 405 w = (mps_word_t *)p[0]; /* wrapper is header word */
413 assert(dylan_wrapper_check(w)); 406 assert(dylan_wrapper_check(w));
414 407
@@ -563,7 +556,8 @@ extern mps_res_t dylan_scan1_weak(mps_ss_t mps_ss, mps_addr_t *object_io)
563 /* object should not be forwarded (as there is no forwarding method) */ 556 /* object should not be forwarded (as there is no forwarding method) */
564 assert((h & 3) == 0); 557 assert((h & 3) == 0);
565 558
566 mps_fix(mps_ss, p); 559 res = mps_fix(mps_ss, p);
560 if ( res != MPS_RES_OK ) return res;
567 561
568 /* w points to wrapper */ 562 /* w points to wrapper */
569 w = (mps_word_t *)p[0]; 563 w = (mps_word_t *)p[0];
@@ -688,7 +682,7 @@ static void dylan_copy(mps_addr_t old, mps_addr_t new)
688 assert(dylan_wrapper_check(*(mps_word_t **)old)); 682 assert(dylan_wrapper_check(*(mps_word_t **)old));
689 /* .improve.memcpy: Can do better here as we know that new and old 683 /* .improve.memcpy: Can do better here as we know that new and old
690 * will be aligned (to MPS_PF_ALIGN) */ 684 * will be aligned (to MPS_PF_ALIGN) */
691 memcpy(new, old, length); 685 (void)memcpy(new, old, length);
692} 686}
693 687
694static mps_addr_t dylan_isfwd(mps_addr_t object) 688static mps_addr_t dylan_isfwd(mps_addr_t object)
diff --git a/mps/code/fmthe.c b/mps/code/fmthe.c
index 69a1220dbab..ff4b787b60e 100644
--- a/mps/code/fmthe.c
+++ b/mps/code/fmthe.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 * Uses impl.c.fmtdy for the actual Dylan format, and just adds 7 * Uses impl.c.fmtdy for the actual Dylan format, and just adds
7 * a thin layer to handle the object headers themselves. 8 * a thin layer to handle the object headers themselves.
@@ -15,17 +16,6 @@
15#include <string.h> 16#include <string.h>
16#include <stdlib.h> 17#include <stdlib.h>
17 18
18#include "mpstd.h"
19#ifdef MPS_PF_SUS8LC
20/* .hack.stderr: builder.lc (LCC) uses Sun's header files. Sun's
21 * assert.h is broken, as it assumes it can use stderr. We have to
22 * fix it by supplying stderr.
23 */
24#include <stdio.h>
25/* Better include ossu.h as well, in case we use other stuff from stdio.h. */
26#include "ossu.h"
27#endif
28
29#include "testlib.h" 19#include "testlib.h"
30 20
31 21
@@ -99,10 +89,6 @@ static mps_addr_t dylan_header_skip(mps_addr_t object)
99{ 89{
100 mps_addr_t *p; /* cursor in object */ 90 mps_addr_t *p; /* cursor in object */
101 int header; 91 int header;
102
103 p = (mps_addr_t *)object;
104 assert(p != NULL);
105
106 header = *(int*)((char*)object - headerSIZE); 92 header = *(int*)((char*)object - headerSIZE);
107 switch(headerType(header)) { 93 switch(headerType(header)) {
108 case realTYPE: 94 case realTYPE:
diff --git a/mps/code/fmthe.h b/mps/code/fmthe.h
index f4b5121a17d..f46e2444b5e 100644
--- a/mps/code/fmthe.h
+++ b/mps/code/fmthe.h
@@ -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#ifndef fmthe_h 8#ifndef fmthe_h
diff --git a/mps/code/format.c b/mps/code/format.c
index 3fbf0972a9b..d2235300288 100644
--- a/mps/code/format.c
+++ b/mps/code/format.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 * DESIGN 7 * DESIGN
7 * 8 *
@@ -27,7 +28,8 @@ Bool FormatCheck(Format format)
27 CHECKL(AlignCheck(format->alignment)); 28 CHECKL(AlignCheck(format->alignment));
28 /* @@@@ alignment should be less than maximum allowed */ 29 /* @@@@ alignment should be less than maximum allowed */
29 CHECKL(FUNCHECK(format->scan)); 30 CHECKL(FUNCHECK(format->scan));
30 CHECKL(FUNCHECK(format->skip)); 31 CHECKL(format->variety == FormatVarietyFixed
32 ? format->skip == NULL : FUNCHECK(format->skip));
31 CHECKL(FUNCHECK(format->move)); 33 CHECKL(FUNCHECK(format->move));
32 CHECKL(FUNCHECK(format->isMoved)); 34 CHECKL(FUNCHECK(format->isMoved));
33 /* Ignore unused copy field. */ 35 /* Ignore unused copy field. */
@@ -82,13 +84,13 @@ Res FormatCreate(Format *formatReturn, Arena arena,
82 format->isMoved = isMoved; 84 format->isMoved = isMoved;
83 format->copy = copy; 85 format->copy = copy;
84 format->pad = pad; 86 format->pad = pad;
85 if(class == NULL) { 87 if (class == NULL) {
86 format->class = &FormatDefaultClass; 88 format->class = &FormatDefaultClass;
87 } else { 89 } else {
88 AVER(variety == FormatVarietyB); 90 AVER(variety == FormatVarietyB);
89 format->class = class; 91 format->class = class;
90 } 92 }
91 if(headerSize != 0) { 93 if (headerSize != 0) {
92 AVER(variety == FormatVarietyAutoHeader); 94 AVER(variety == FormatVarietyAutoHeader);
93 format->headerSize = headerSize; 95 format->headerSize = headerSize;
94 } else { 96 } else {
@@ -108,6 +110,8 @@ Res FormatCreate(Format *formatReturn, Arena arena,
108} 110}
109 111
110 112
113/* FormatDestroy -- destroy a format */
114
111void FormatDestroy(Format format) 115void FormatDestroy(Format format)
112{ 116{
113 AVERT(Format, format); 117 AVERT(Format, format);
@@ -122,7 +126,10 @@ void FormatDestroy(Format format)
122} 126}
123 127
124 128
125/* Must be thread safe. See design.mps.interface.c.thread-safety. */ 129/* FormatArena -- find the arena of a format
130 *
131 * Must be thread-safe. See design.mps.interface.c.thread-safety. */
132
126Arena FormatArena(Format format) 133Arena FormatArena(Format format)
127{ 134{
128 /* Can't AVER format as that would not be thread-safe */ 135 /* Can't AVER format as that would not be thread-safe */
@@ -131,6 +138,8 @@ Arena FormatArena(Format format)
131} 138}
132 139
133 140
141/* FormatDescribe -- describe a format */
142
134Res FormatDescribe(Format format, mps_lib_FILE *stream) 143Res FormatDescribe(Format format, mps_lib_FILE *stream)
135{ 144{
136 Res res; 145 Res res;
@@ -148,7 +157,7 @@ Res FormatDescribe(Format format, mps_lib_FILE *stream)
148 " pad $F\n", (WriteFF)format->pad, 157 " pad $F\n", (WriteFF)format->pad,
149 "} Format $P ($U)\n", (WriteFP)format, (WriteFU)format->serial, 158 "} Format $P ($U)\n", (WriteFP)format, (WriteFU)format->serial,
150 NULL); 159 NULL);
151 if(res != ResOK) return res; 160 if (res != ResOK) return res;
152 161
153 return ResOK; 162 return ResOK;
154} 163}
diff --git a/mps/code/gathconf.bat b/mps/code/gathconf.bat
deleted file mode 100644
index ceee789d71d..00000000000
--- a/mps/code/gathconf.bat
+++ /dev/null
@@ -1,37 +0,0 @@
1@rem impl.bat.gathconf: GATHERING A RELEASE FOR CONFIGURA
2@rem
3@rem $Id$
4@rem Copyright (c) 2001 Ravenbrook Limited.
5
6rmdir /s w3i3mv
7nmake /f w3i3mv.nmk VARIETY=we mps_conf.lib mpsplan.lib
8nmake /f w3i3mv.nmk VARIETY=wi mps_conf.lib mpsplan.lib
9nmake /f w3i3mv.nmk VARIETY=ce mps_conf.lib mpsplan.lib
10nmake /f w3i3mv.nmk VARIETY=ci mps_conf.lib mpsplan.lib
11mkdir release
12mkdir release\include
13mkdir release\lib
14mkdir release\lib\w3i3
15mkdir release\lib\w3i3\release
16mkdir release\lib\w3i3\debug
17mkdir release\src
18copy mps.h release\include
19copy mpsavm.h release\include
20copy mpsacl.h release\include
21copy mpscamc.h release\include
22copy mpscams.h release\include
23copy mpsclo.h release\include
24copy mpscmv.h release\include
25copy mpscmvff.h release\include
26copy mpscsnc.h release\include
27copy mpsio.h release\include
28copy mpslib.h release\include
29copy mpstd.h release\include
30copy mpsw3.h release\include
31copy mpswin.h release\include
32copy w3i3mv\we\mps_conf.lib release\lib\w3i3\release
33copy w3i3mv\ce\mps_conf.lib release\lib\w3i3\debug
34copy w3i3mv\we\mpsplan.lib release\lib\w3i3\release
35copy w3i3mv\ce\mpsplan.lib release\lib\w3i3\debug
36copy mpsliban.c release\src
37copy mpsioan.c release\src
diff --git a/mps/code/global.c b/mps/code/global.c
index 1cda9b58d71..38a27080e84 100644
--- a/mps/code/global.c
+++ b/mps/code/global.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 * .sources: See design.mps.arena. design.mps.thread-safety is relevant 7 * .sources: See design.mps.arena. design.mps.thread-safety is relevant
7 * to the functions ArenaEnter and ArenaLeave in this file. 8 * to the functions ArenaEnter and ArenaLeave in this file.
@@ -20,13 +21,12 @@
20 * functions should be in some other module, they just ended up here by 21 * functions should be in some other module, they just ended up here by
21 * confusion over naming. */ 22 * confusion over naming. */
22 23
23#include "dongle.h" 24#include "bt.h"
24#include "poolmrg.h" 25#include "poolmrg.h"
25#include "mps.h" /* finalization */ 26#include "mps.h" /* finalization */
26#include "poolmv.h" 27#include "poolmv.h"
27#include "mpm.h" 28#include "mpm.h"
28 29
29
30SRCID(global, "$Id$"); 30SRCID(global, "$Id$");
31 31
32 32
@@ -217,9 +217,6 @@ Res GlobalsInit(Globals arenaGlobals)
217 /* so check static consistency here. */ 217 /* so check static consistency here. */
218 AVER(MPMCheck()); 218 AVER(MPMCheck());
219 219
220 if (!DongleTestFull())
221 return ResFAIL;
222
223 arenaClaimRingLock(); 220 arenaClaimRingLock();
224 /* Ensure static things are initialized. */ 221 /* Ensure static things are initialized. */
225 if (!arenaRingInit) { 222 if (!arenaRingInit) {
@@ -542,12 +539,6 @@ void ArenaPoll(Globals globals)
542 539
543 AVERT(Globals, globals); 540 AVERT(Globals, globals);
544 541
545 if (!DONGLE_TEST_QUICK()) {
546 /* Cripple it by deleting the control pool. */
547 GlobalsArena(globals)->poolReady = FALSE; /* suppress check */
548 PoolFinish(ArenaControlPool(GlobalsArena(globals)));
549 return;
550 }
551 if (globals->clamped) 542 if (globals->clamped)
552 return; 543 return;
553 size = globals->fillMutatorSize; 544 size = globals->fillMutatorSize;
@@ -589,7 +580,7 @@ Res ArenaFinalize(Arena arena, Ref obj)
589 Res res; 580 Res res;
590 581
591 AVERT(Arena, arena); 582 AVERT(Arena, arena);
592 /* Could consider checking that Ref is valid. */ 583 AVER(ArenaHasAddr(arena, (Addr)obj));
593 584
594 if (!arena->isFinalPool) { 585 if (!arena->isFinalPool) {
595 Pool pool; 586 Pool pool;
@@ -600,9 +591,27 @@ Res ArenaFinalize(Arena arena, Ref obj)
600 arena->finalPool = pool; 591 arena->finalPool = pool;
601 arena->isFinalPool = TRUE; 592 arena->isFinalPool = TRUE;
602 } 593 }
603 AVER(arena->isFinalPool);
604 594
605 res = MRGRegister(arena->finalPool, (Ref)obj); 595 res = MRGRegister(arena->finalPool, obj);
596 return res;
597}
598
599
600/* ArenaDefinalize -- removes one finalization registration of an object
601 *
602 * See design.mps.finalize. */
603
604Res ArenaDefinalize(Arena arena, Ref obj)
605{
606 Res res;
607
608 AVERT(Arena, arena);
609 AVER(ArenaHasAddr(arena, (Addr)obj));
610
611 if (!arena->isFinalPool) {
612 return ResFAIL;
613 }
614 res = MRGDeregister(arena->finalPool, obj);
606 return res; 615 return res;
607} 616}
608 617
diff --git a/mps/code/hqbuild/data/cv_alpha.txt b/mps/code/hqbuild/data/cv_alpha.txt
deleted file mode 100644
index cb5d08aa6c5..00000000000
--- a/mps/code/hqbuild/data/cv_alpha.txt
+++ /dev/null
@@ -1 +0,0 @@
1MSVCNT 5_0
diff --git a/mps/code/hqbuild/data/cv_x86.txt b/mps/code/hqbuild/data/cv_x86.txt
deleted file mode 100644
index 1feeab52711..00000000000
--- a/mps/code/hqbuild/data/cv_x86.txt
+++ /dev/null
@@ -1,3 +0,0 @@
1MSVCNT 5_0
2MSTOOLS Aug96US9
3MSMASM 6.11
diff --git a/mps/code/hqbuild/tools/hqbuild b/mps/code/hqbuild/tools/hqbuild
deleted file mode 100644
index 3101120869b..00000000000
--- a/mps/code/hqbuild/tools/hqbuild
+++ /dev/null
@@ -1,20 +0,0 @@
1#!/bin/sh
2# impl.sh.hqbuild
3#
4# $Id$
5# Copyright (c) 2001 Ravenbrook Limited.
6#
7# Build script for SWIG autobuild system.
8# The SWIG autobuild system expects to execute this file passing it
9# an argument.
10#
11# We specify that the argument will be the platform code to make life
12# easy for us
13
14case $# in
15 1) ;;
16 *) echo 1>&2 'Wrong number of arguments to hqbuild.
17Exactly one argument expected'; exit 1;;
18esac
19
20gnumake -r -f "$1.gmk"
diff --git a/mps/code/hqbuild/tools/hqbuild.bat b/mps/code/hqbuild/tools/hqbuild.bat
deleted file mode 100644
index a0862a92fe8..00000000000
--- a/mps/code/hqbuild/tools/hqbuild.bat
+++ /dev/null
@@ -1,12 +0,0 @@
1@REM impl.bat.hqbuild: setup for SWIG autobuild system
2@REM $Id$
3@REM Copyright (c) 2001 Ravenbrook Limited.
4@REM Called by SWIG autobuild system
5@
6@REM we expect whatcom to have set MSVCNT and possibly MSMASM and MSTOOLS
7IF NOT %MSMASM%X == X SET PATH=%MSMASM%\bin;%PATH%
8SET PATH=%MSVCNT%\..\sharedide\bin\ide;%MSVCNT%\..\sharedide\bin;%MSVCNT%\bin;%PATH%
9SET INCLUDE=%MSVCNT%\include;%MSVCNT%\mfc\include;%INCLUDE%
10SET LIB=%MSVCNT%\lib;%MSVCNT%\mfc\lib;%LIB%
11@REM First argument is expected to be platform code, rest we pass on
12nmake /f %1.nmk %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/mps/code/lo.h b/mps/code/lo.h
index 21ffbdaf108..2f50920d73a 100644
--- a/mps/code/lo.h
+++ b/mps/code/lo.h
@@ -1,4 +1,4 @@
1/* impl.h.lo 1/* impl.h.lo: LEAF OBJECT POOL CLASS INTERFACE
2 * 2 *
3 * LEAF OBJECT POOL CLASS 3 * LEAF OBJECT POOL CLASS
4 * 4 *
@@ -29,7 +29,6 @@
29 * 29 *
30 * Space and time performance will degrade when fragmentation 30 * Space and time performance will degrade when fragmentation
31 * increases. 31 * increases.
32 *
33 */ 32 */
34 33
35#ifndef lo_h 34#ifndef lo_h
diff --git a/mps/code/locbwcss.c b/mps/code/locbwcss.c
new file mode 100644
index 00000000000..e5c267dff8f
--- /dev/null
+++ b/mps/code/locbwcss.c
@@ -0,0 +1,206 @@
1/* impl.c.locbwcss: LOCUS BACKWARDS COMPATIBILITY STRESS TEST
2 *
3 * $Id: locbwcss.c,v 1.4 2002/05/10 11:11:39 pekka Exp $
4 * $HopeName: MMsrc!locbwcss.c(trunk.4) $
5 * Copyright (c) 2001 Ravenbrook Limited.
6 */
7
8#include "mpscmvff.h"
9#include "mpslib.h"
10#include "mpsavm.h"
11#include "testlib.h"
12#include "mps.h"
13
14#include <stdlib.h>
15#include <stdarg.h>
16
17
18/* some constants */
19
20#define TRUE 1
21#define FALSE 0
22
23#define iterationCount 30 /* number of iterations */
24#define allocsPerIteration 8 /* number of allocs each iteration */
25#define chunkSize ((size_t)65536) /* our allocation chunk size */
26
27#define testArenaSIZE \
28 ((size_t)(chunkSize * iterationCount * allocsPerIteration * 3))
29
30
31#define AddressOffset(b, l) \
32 ((size_t)((char *)(l) - (char *)(b)))
33
34
35/* PoolStat -- maintain data about contiguous allocations */
36
37typedef struct PoolStatStruct *PoolStat;
38
39typedef struct PoolStatStruct {
40 mps_pool_t pool; /* the pool being measured */
41 size_t objSize; /* size of each allocation */
42 mps_addr_t min; /* lowest address lock allocated to the pool */
43 mps_addr_t max; /* highest address lock allocated to the pool */
44 int ncCount; /* count of non-contiguous allocations */
45 int aCount; /* count of allocations */
46 int fCount; /* count of frees */
47} PoolStatStruct;
48
49
50
51static mps_addr_t allocObject(mps_pool_t pool, size_t size)
52{
53 mps_addr_t addr;
54 die(mps_alloc(&addr, pool, size),
55 "Allocate Object");
56 return addr;
57}
58
59
60static void recordNewObjectStat(PoolStat stat, mps_addr_t obj)
61{
62 stat->aCount++;
63 if (obj < stat->min) {
64 if (AddressOffset(obj, stat->min) > stat->objSize) {
65 stat->ncCount++;
66 }
67 stat->min = obj;
68 } else if (obj > stat->max) {
69 if (AddressOffset(stat->max, obj) > stat->objSize) {
70 stat->ncCount++;
71 }
72 stat->max = obj;
73 }
74}
75
76static void recordFreedObjectStat(PoolStat stat)
77{
78 stat->fCount++;
79}
80
81
82static void poolStatInit(PoolStat stat, mps_pool_t pool, size_t objSize)
83{
84 mps_addr_t s1, s2, s3;
85
86 stat->pool = pool;
87 stat->objSize = objSize;
88 stat->ncCount = 0;
89 stat->aCount = 0;
90 stat->fCount = 0;
91
92 /* allocate 3 half-size sentinel objects, freeing the middle one */
93 /* to leave a bit of space for the control pool */
94 s1 = allocObject(pool, objSize / 2);
95 stat->min = s1;
96 stat->max = s1;
97 stat->aCount++;
98
99 s2 = allocObject(pool, objSize / 2);
100 recordNewObjectStat(stat, s2);
101 s3 = allocObject(pool, objSize / 2);
102 recordNewObjectStat(stat, s3);
103
104 mps_free(pool, s2, objSize / 2);
105 recordFreedObjectStat(stat);
106
107}
108
109
110static void allocMultiple(PoolStat stat)
111{
112 mps_addr_t objects[allocsPerIteration];
113 int i;
114
115 /* allocate a few objects, and record stats for them */
116 for (i = 0; i < allocsPerIteration; i++) {
117 mps_addr_t obj = allocObject(stat->pool, stat->objSize);
118 recordNewObjectStat(stat, obj);
119 objects[i] = obj;
120 }
121
122 /* free one of the objects, to make the test more interesting */
123 i = rnd() % allocsPerIteration;
124 mps_free(stat->pool, objects[i], stat->objSize);
125 recordFreedObjectStat(stat);
126
127}
128
129
130/* reportResults - print a report on a PoolStat */
131
132static void reportResults(PoolStat stat, char *name)
133{
134 printf("\nResults for ");
135 printf(name);
136 printf("\n");
137 printf(" Allocated %lu objects\n", (unsigned long)stat->aCount);
138 printf(" Freed %lu objects\n", (unsigned long)stat->fCount);
139 printf(" There were %lu non-contiguous allocations\n",
140 (unsigned long)stat->ncCount);
141 printf(" Address range from %p to %p\n",
142 (void *)stat->min, (void *)stat->max);
143 printf("\n");
144}
145
146
147static void testInArena(mps_arena_t arena)
148{
149 mps_pool_t lopool, hipool;
150 PoolStatStruct lostruct; /* stats about lopool */
151 PoolStatStruct histruct; /* stats about lopool */
152 PoolStat lostat = &lostruct;
153 PoolStat histat = &histruct;
154 int i;
155
156 die(mps_pool_create(&hipool, arena, mps_class_mvff(),
157 chunkSize, chunkSize, 1024,
158 TRUE, TRUE, TRUE),
159 "Create HI MFFV");
160
161 die(mps_pool_create(&lopool, arena, mps_class_mvff(),
162 chunkSize, chunkSize, 1024,
163 FALSE, FALSE, TRUE),
164 "Create LO MFFV");
165
166 poolStatInit(lostat, lopool, chunkSize);
167 poolStatInit(histat, hipool, chunkSize);
168
169 /* iterate, allocating objects */
170 for (i=0; i<iterationCount; ++i) {
171 allocMultiple(lostat);
172 allocMultiple(histat);
173 }
174
175 /* report results */
176 reportResults(lostat, "the low MVFF pool");
177 reportResults(histat, "the high MVFF pool");
178
179 if (lostat->max > histat->min) {
180 printf("\nFOUND PROBLEM - low range overlaps high\n");
181 } else if (lostat->ncCount != 0 || histat->ncCount != 0) {
182 printf("\nFOUND POSSIBLE PROBLEM - some non-contiguous allocations\n");
183 } else {
184 printf("\nNo problems detected.\n");
185 }
186
187 mps_pool_destroy(hipool);
188 mps_pool_destroy(lopool);
189}
190
191
192int main(int argc, char **argv)
193{
194 mps_arena_t arena;
195
196 randomize(argc, argv);
197
198 die(mps_arena_create(&arena, mps_arena_class_vmnz(), testArenaSIZE),
199 "mps_arena_create");
200
201 testInArena(arena);
202
203 mps_arena_destroy(arena);
204
205 return 0;
206}
diff --git a/mps/code/locus.c b/mps/code/locus.c
index fe8a97b4a31..106ef830288 100644
--- a/mps/code/locus.c
+++ b/mps/code/locus.c
@@ -15,7 +15,6 @@
15#include "mpstd.h" 15#include "mpstd.h"
16#include <float.h> /* for DBL_MAX */ 16#include <float.h> /* for DBL_MAX */
17 17
18
19SRCID(locus, "$Id$"); 18SRCID(locus, "$Id$");
20 19
21 20
@@ -45,7 +44,7 @@ SegPref SegPrefDefault(void)
45 44
46/* SegPrefExpress -- express a segment preference */ 45/* SegPrefExpress -- express a segment preference */
47 46
48Res SegPrefExpress(SegPref pref, SegPrefKind kind, void *p) 47void SegPrefExpress(SegPref pref, SegPrefKind kind, void *p)
49{ 48{
50 AVERT(SegPref, pref); 49 AVERT(SegPref, pref);
51 AVER(pref != &segPrefDefault); 50 AVER(pref != &segPrefDefault);
@@ -82,13 +81,9 @@ Res SegPrefExpress(SegPref pref, SegPrefKind kind, void *p)
82 /* See design.mps.pref. */ 81 /* See design.mps.pref. */
83 break; 82 break;
84 } 83 }
85
86 return ResOK;
87} 84}
88 85
89 86
90#if 1
91
92/* GenDescCheck -- check a GenDesc */ 87/* GenDescCheck -- check a GenDesc */
93 88
94static Bool GenDescCheck(GenDesc gen) 89static Bool GenDescCheck(GenDesc gen)
@@ -473,9 +468,6 @@ void LocusFinish(Arena arena)
473Bool LocusCheck(Arena arena) 468Bool LocusCheck(Arena arena)
474{ 469{
475 /* Can't check arena, because this is part of ArenaCheck. */ 470 /* Can't check arena, because this is part of ArenaCheck. */
476 GenDescCheck(&arena->topGen); 471 CHECKL(GenDescCheck(&arena->topGen));
477 return TRUE; 472 return TRUE;
478} 473}
479
480
481#endif
diff --git a/mps/code/locusss.c b/mps/code/locusss.c
new file mode 100644
index 00000000000..eb61c980c0f
--- /dev/null
+++ b/mps/code/locusss.c
@@ -0,0 +1,248 @@
1/* impl.c.locusss: LOCUS STRESS TEST
2 *
3 * $Id: locusss.c,v 1.4 2002/05/10 11:00:15 pekka Exp $
4 * $HopeName: MMsrc!locusss.c(trunk.4) $
5 * Copyright (c) 2001 Ravenbrook Limited.
6 */
7
8#include "mpscmvff.h"
9#include "mpscmv.h"
10#include "mpslib.h"
11#include "mpsavm.h"
12#include "testlib.h"
13#include "mps.h"
14
15#include <stdlib.h>
16#include <stdarg.h>
17
18
19/* some constants */
20
21#define TRUE 1
22#define FALSE 0
23
24#define iterationCount 30 /* number of iterations */
25#define contigAllocs 8 /* number of allocs each iteration */
26#define chunkSize ((size_t)65536) /* our allocation chunk size */
27
28#define smallArenaSize \
29 ((size_t)(chunkSize * iterationCount * contigAllocs * 2))
30
31
32#define AddressOffset(b, l) \
33 ((size_t)((char *)(l) - (char *)(b)))
34
35
36/* PoolStat -- maintain data about contiguous allocations */
37
38typedef struct PoolStatStruct *PoolStat;
39
40typedef struct PoolStatStruct {
41 mps_pool_t pool; /* the pool being measured */
42 size_t objSize; /* size of each allocation */
43 mps_addr_t min; /* lowest address lock allocated to the pool */
44 mps_addr_t max; /* highest address lock allocated to the pool */
45 int ncCount; /* count of non-contiguous allocations */
46 int aCount; /* count of allocations */
47 int fCount; /* count of frees */
48} PoolStatStruct;
49
50
51
52static mps_addr_t allocObject(mps_pool_t pool, size_t size)
53{
54 mps_addr_t addr;
55 die(mps_alloc(&addr, pool, size),
56 "Allocate Object");
57 return addr;
58}
59
60static void recordNewObjectStat(PoolStat stat, mps_addr_t obj)
61{
62 stat->aCount++;
63 if (obj < stat->min) {
64 if (AddressOffset(obj, stat->min) > stat->objSize) {
65 stat->ncCount++;
66 }
67 stat->min = obj;
68 } else if (obj > stat->max) {
69 if (AddressOffset(stat->max, obj) > stat->objSize) {
70 stat->ncCount++;
71 }
72 stat->max = obj;
73 }
74}
75
76static void recordFreedObjectStat(PoolStat stat)
77{
78 stat->fCount++;
79}
80
81
82static void poolStatInit(PoolStat stat, mps_pool_t pool, size_t objSize)
83{
84 mps_addr_t s1, s2, s3;
85
86 stat->pool = pool;
87 stat->objSize = objSize;
88 stat->ncCount = 0;
89 stat->aCount = 0;
90 stat->fCount = 0;
91
92 /* allocate 3 half-size sentinel objects, freeing the middle one */
93 /* to leave a bit of space for the control pool */
94 s1 = allocObject(pool, objSize / 2);
95 stat->min = s1;
96 stat->max = s1;
97 stat->aCount++;
98
99 s2 = allocObject(pool, objSize / 2);
100 recordNewObjectStat(stat, s2);
101 s3 = allocObject(pool, objSize / 2);
102 recordNewObjectStat(stat, s3);
103
104 mps_free(pool, s2, objSize / 2);
105 recordFreedObjectStat(stat);
106
107}
108
109
110static mps_res_t allocMultiple(PoolStat stat)
111{
112 mps_addr_t objects[contigAllocs];
113 int i;
114
115 /* allocate a few objects, and record stats for them */
116 for (i = 0; i < contigAllocs; i++) {
117 mps_addr_t obj;
118 mps_res_t res = mps_alloc(&obj, stat->pool, stat->objSize);
119 if (res != MPS_RES_OK)
120 return res;
121 recordNewObjectStat(stat, obj);
122 objects[i] = obj;
123 }
124
125 /* free one of the objects, to make the test more interesting */
126 i = rnd() % contigAllocs;
127 mps_free(stat->pool, objects[i], stat->objSize);
128 recordFreedObjectStat(stat);
129
130 return MPS_RES_OK;
131}
132
133
134/* reportResults - print a report on a PoolStat */
135
136static void reportResults(PoolStat stat, char *name)
137{
138 printf("\nResults for ");
139 printf(name);
140 printf("\n");
141 printf(" Allocated %lu objects\n", (unsigned long)stat->aCount);
142 printf(" Freed %lu objects\n", (unsigned long)stat->fCount);
143 printf(" There were %lu non-contiguous allocations\n",
144 (unsigned long)stat->ncCount);
145 printf(" Address range from %p to %p\n", stat->min, stat->max);
146 printf("\n");
147}
148
149
150static void testInArena(mps_arena_t arena,
151 mps_bool_t failcase,
152 mps_bool_t usefulFailcase)
153{
154 mps_pool_t lopool, hipool, temppool;
155 PoolStatStruct lostruct; /* stats about lopool */
156 PoolStatStruct histruct; /* stats about lopool */
157 PoolStatStruct tempstruct; /* stats about temppool */
158 PoolStat lostat = &lostruct;
159 PoolStat histat = &histruct;
160 PoolStat tempstat = &tempstruct;
161 int i;
162
163 die(mps_pool_create(&hipool, arena, mps_class_mvff(),
164 chunkSize, chunkSize, 1024,
165 TRUE, TRUE, TRUE),
166 "Create HI MFFV");
167
168 die(mps_pool_create(&lopool, arena, mps_class_mvff(),
169 chunkSize, chunkSize, 1024,
170 FALSE, FALSE, TRUE),
171 "Create LO MFFV");
172
173 die(mps_pool_create(&temppool, arena, mps_class_mv(),
174 chunkSize, chunkSize, chunkSize),
175 "Create TEMP");
176
177 if(failcase) {
178 if(usefulFailcase) {
179 /* describe a useful failure case */
180 } else {
181 /* describe a misleading failure case */
182 }
183 }
184
185 poolStatInit(lostat, lopool, chunkSize);
186 poolStatInit(histat, hipool, chunkSize);
187 poolStatInit(tempstat, temppool, chunkSize);
188
189 /* iterate, allocating objects */
190 for (i=0; i<iterationCount; ++i) {
191 mps_res_t res;
192 res = allocMultiple(lostat);
193 if (res != MPS_RES_OK)
194 break;
195 res = allocMultiple(histat);
196 if (res != MPS_RES_OK)
197 break;
198 res = allocMultiple(tempstat);
199 if (res != MPS_RES_OK)
200 break;
201 }
202
203 /* report results */
204 reportResults(lostat, "the low MVFF pool");
205 reportResults(histat, "the high MVFF pool");
206 reportResults(tempstat, "the temp pool");
207
208 mps_pool_destroy(hipool);
209 mps_pool_destroy(lopool);
210 mps_pool_destroy(temppool);
211
212}
213
214static void runArenaTest(size_t size,
215 mps_bool_t failcase,
216 mps_bool_t usefulFailcase)
217{
218 mps_arena_t arena;
219
220 die(mps_arena_create(&arena, mps_arena_class_vmnz(), size),
221 "mps_arena_create");
222
223 die(mps_arena_commit_limit_set(arena, size - chunkSize),
224 "mps_arena_commit_limit_set");
225
226 testInArena(arena, failcase, usefulFailcase);
227
228 mps_arena_destroy(arena);
229
230}
231
232
233int main(int argc, char **argv)
234{
235
236 randomize(argc, argv);
237
238 printf("\nRunning test with no information about peak usage.\n");
239 runArenaTest(smallArenaSize, FALSE, FALSE);
240 /*
241 printf("\nRunning test with useful information about peak usage.\n");
242 runArenaTest(smallArenaSize, TRUE, TRUE);
243 printf("\nRunning test with misleading information about peak usage.\n");
244 runArenaTest(smallArenaSize, TRUE, FALSE);
245 */
246
247 return 0;
248}
diff --git a/mps/code/makefile.jam b/mps/code/makefile.jam
new file mode 100644
index 00000000000..3a312cce850
--- /dev/null
+++ b/mps/code/makefile.jam
@@ -0,0 +1,291 @@
1#
2# Makefile for CORE RIP MPS subsystem
3#
4# $HopeName: SWmps!make:makefile.jam(trunk.11) $
5#
6
7# Variant details come before compilation rules
8
9RequiresVariant warning_level : high ;
10# RequiresVariant warnings_are_fatal ;
11
12
13# generic_MPS turns off SW-specific configuration; Non_generic_MPS
14# means SW. We do it this way round so that SW is the default. You
15# never want to build a generic_MPS variant of SW, only of MPS tests.
16ImplementsVariant generic_MPS ;
17
18
19# Determine which MPS platform code matches this target.
20local MPSOS ; local MPSPF ;
21switch $(TargetOS) {
22 case win_32 :
23 MPSOS = w3 ;
24 switch $(TargetArch) {
25 case pentium : MPSPF = w3i3mv ;
26 case alpha : MPSPF = w3almv ;
27 case ppc : MPSPF = w3ppmv ;
28 }
29 case irix_5 : MPSOS = i5 ; MPSPF = i5m2cc ;
30 case irix_6 : MPSOS = ia ; MPSPF = iam4cc ;
31
32 case linux_2 : MPSOS = li ; MPSPF = lii4gc ;
33
34 case solaris : MPSOS = so ; MPSPF = sos8gc ;
35
36 case macos_8 : MPSOS = s7 ; MPSPF = s7ppac ;
37 case macos_x : MPSOS = xc ; MPSPF = xcppgc ;
38}
39if ! $(MPSPF) {
40 Error Cannot determine MPS platform for target $(TargetOS)-$(TargetArch) ;
41}
42
43
44# Set MPS configuration
45
46AddToVar Inherited Local : C-Defines : CONFIG_PF_$(MPSPF:U) ;
47
48AddToVar Inherited Local : C-Defines : CONFIG_PROD_EPCORE
49 : Variant Non_generic_MPS ;
50AddToVar Inherited Local : C-Defines : CONFIG_PROD_MPS
51 : Variant generic_MPS ;
52AddToVar Inherited Local : Suffix : mps : Variant generic_MPS ;
53
54AddToVar Inherited Local : C-Defines : CONFIG_ASSERT : Build ASSERT ;
55AddToVar Inherited Local : C-Defines : CONFIG_DEBUG : Build DEBUG ;
56
57
58# Compilation rules
59
60
61 DependsOn all : mps ;
62
63# C-IncludeExportDirectories
64# : .. ;
65
66
67AddToVar Local : VariantMPSsources
68 : prmcan.c protsw.c ssan.c than.c
69 mpsioan.c poolepdl.c poolepvm.c
70 : Variant Non_generic_MPS ;
71
72switch $(MPSPF) {
73case w3i3mv :
74 AddToVar Local : VariantMPSsources
75 : lockw3.c prmci3w3.c proti3.c protw3.c spi3.c ssw3i3.c thw3i3.c
76 mpsiw3.c
77 : Variant generic_MPS ;
78 AddToVar Local : VariantMPSsources : vmw3.c ;
79case w3ppmv :
80 AddToVar Local : VariantMPSsources
81 : lockw3.c prmcan.c protw3.c span.c ssan.c than.c
82 mpsiw3.c
83 : Variant generic_MPS ;
84 AddToVar Local : VariantMPSsources : vmw3.c ;
85case w3almv :
86 AddToVar Local : VariantMPSsources
87 : lockw3.c prmcan.c protw3.c span.c ssan.c than.c
88 mpsiw3.c
89 : Variant generic_MPS ;
90 AddToVar Local : VariantMPSsources : vmw3.c ;
91case sos8gc :
92 AddToVar Local : VariantMPSsources
93 : lockan.c prmcan.c protso.c span.c sssus8.c than.c
94 : Variant generic_MPS ;
95 AddToVar Local : VariantMPSsources : vmso.c ;
96case iam4cc :
97 AddToVar Local : VariantMPSsources
98 : lockan.c prmcan.c protan.c span.c ssan.c than.c
99 : Variant generic_MPS ;
100 AddToVar Local : VariantMPSsources : vmi5.c ;
101case lii4gc :
102 AddToVar Local : VariantMPSsources
103 : lockli.c prmci3li.c protli.c protlii3.c proti3.c pthrdext.c
104 span.c sslii3.c thlii4.c
105 : Variant generic_MPS ;
106 AddToVar Local : VariantMPSsources : vmli.c ;
107 AddToVar Local Inherited : C-Defines : _REENTRANT : Variant generic_MPS ;
108case s7ppac :
109 AddToVar Local : VariantMPSsources
110 : lockan.c prmcan.c protan.c span.c ssan.c than.c
111 : Variant generic_MPS ;
112 AddToVar Local : VariantMPSsources : vman.c ;
113case xcppgc :
114 AddToVar Local : VariantMPSsources
115 : lockan.c prmcan.c protan.c span.c ssan.c than.c
116 : Variant generic_MPS ;
117 AddToVar Local : VariantMPSsources : vmxc.c ;
118case * :
119 Error Undefined MPS platform ;
120}
121
122 Library mps :
123 $(VariantMPSsources)
124 arena.c
125 arenacl.c
126 arenavm.c
127 boot.c
128 bt.c
129 buffer.c
130 cbs.c
131 dbgpool.c
132 dbgpooli.c
133 event.c
134 format.c
135 global.c
136 ld.c
137 locus.c
138 message.c
139 meter.c
140 mpm.c
141 mpsi.c
142 pool.c
143 poolabs.c
144 poolamc.c
145 poolams.c
146 poolamsi.c
147 poolawl.c
148 poollo.c
149 poolmfs.c
150 poolmrg.c
151 poolmv.c
152 poolmvff.c
153 poolsnc.c
154 protocol.c
155 ref.c
156 reserv.c
157 ring.c
158 root.c
159 sac.c
160 seg.c
161 shield.c
162 splay.c
163 trace.c
164 tract.c
165 version.c
166 walk.c
167 ;
168
169
170 # Auxiliary tools
171
172 AddToVar Local : VariantPlinthSources : mpsioan.c : Variant generic_MPS ;
173 Library plinth :
174 $(VariantPlinthSources)
175 mpsliban.c
176 ;
177
178 Executable eventcnv : eventcnv.c eventpro.c table.c ;
179
180 Executable replay
181 : replay.c eventrep.c eventpro.c table.c mpsliban.c fmtpstst.c ;
182 C-LinkWithLibraries replay : mps testlib ;
183
184
185 # Test files
186
187 # testrun is the target for building and running all tests.
188 FloatingDepends testrun ;
189 # testrun1 is an intermediate target required by a bug in GenericTarget.
190 DependsOn testrun : testrun1 ;
191 local testTarget ; MakeGristed testTarget : testrun : $(CurrentPath) ;
192 local testTarget1 ; MakeGristed testTarget1 : testrun1 : $(CurrentPath) ;
193 NOTFILE $(testTarget) $(testTarget1) ;
194 ALWAYS $(testTarget) $(testTarget1) ;
195
196rule TestExecutable {
197 # TestExecutable executable : additional_sources : variant_for_testrun ;
198 Executable $(1) : $(1).c $(2).c ;
199 if $(MPSPF) in sos8gc {
200 # We'd like to do
201 # C-Exec-Linker_Libraries on $(1) += -lm ;
202 # but for some reason, it doesn't work. As long as there's nothing
203 # in this file after the TestExecutables, this AddToVar is harmless.
204 AddToVar Local : C-Exec-Linker_Libraries : -lm ;
205 }
206 C-LinkWithLibraries $(1) :
207 mps
208 plinth
209 testlib
210 ;
211 # Parse the variant by using AddToVar.
212 AddToVar Local : runTest : yes : Variant $(3) ;
213 if $(runTest) = yes {
214 GenericTarget testrun1 : $(1:S=$(C-Exec-Suffix)) :
215 # There must be a space after $>, or GenericTarget won't replace it.
216 echo ...TESTING $> ...$(NewLine)
217 $> ;
218 }
219 ReplaceVar Local : runTest : : Variant $(3) ;
220}
221
222 Library testlib :
223 testlib.c
224 ;
225
226 TestExecutable abqtest : : mv2_broken ;
227 TestExecutable amcss : fmtdy fmtdytst : generic_MPS ;
228 TestExecutable amcsshe : fmthe : generic_MPS ;
229 TestExecutable amcssth : fmtdy fmtdytst : pthreads ;
230 TestExecutable amsss : fmtdy fmtdytst : generic_MPS ;
231 TestExecutable apss ;
232 TestExecutable arenacv ;
233 TestExecutable btcv ;
234 TestExecutable bttest : : interactive_test ;
235 TestExecutable cbstest ;
236 TestExecutable epdss : : Non_generic_MPS ;
237 TestExecutable epvmss : fmtpstst : Non_generic_MPS ;
238 TestExecutable finalcv : fmtdy fmtdytst ;
239 TestExecutable locbwcss ;
240 TestExecutable lockcov ;
241 TestExecutable lockutw3 : : Windows ;
242 TestExecutable locusss ;
243 TestExecutable locv ;
244 TestExecutable messtest ;
245 TestExecutable mpmss ;
246 TestExecutable mpsicv : fmtdy fmtdytst ;
247 TestExecutable mv2test : poolmv2 abq : mv2_broken ;
248 TestExecutable poolncv : pooln ;
249 TestExecutable qs : : generic_MPS ;
250 TestExecutable sacss ;
251 TestExecutable segsmss : fmtdy fmtdytst : generic_MPS ;
252 TestExecutable teletest : : interactive_test ;
253
254
255# $Log: make:makefile.jam,v $
256# Revision 1.11 2002/05/21 13:22:47 pekka
257# Remove assert.c (change.mps.epcore.chub.160200)
258#
259# Revision 1.10 2002/05/09 17:50:03 pekka
260# Add testrun
261#
262# Revision 1.9 2002/02/15 19:14:04 pekka
263# Remove .s file on Solaris
264#
265# Revision 1.8 2002/02/12 14:45:00 pekka
266# [Bug #24034]
267# On Solaris, you have add -lm
268#
269# Revision 1.7 2002/02/07 17:13:52 pekka
270# [Bug #24034]
271# clean up
272#
273# Revision 1.6 2002/01/09 17:11:45 pekka
274# Add poolamsi.c
275#
276# Revision 1.5 2002/01/04 17:25:06 pekka
277# Add dbgpooli.c
278#
279# Revision 1.4 2002/01/02 19:50:04 pekka
280# Clarify comment on generic_MPS; add some more tests
281#
282# Revision 1.3 2001/12/21 14:34:43 pekka
283# Add missing Linux stuff
284#
285# Revision 1.2 2001/12/18 21:08:32 pekka
286# Warnings can't be fatal yet
287#
288# Revision 1.1 2001/12/18 21:03:44 pekka
289# new unit
290# New makefile for building MPS with Jam Doughtnut
291#
diff --git a/mps/code/message.c b/mps/code/message.c
index 8390a124b79..3c5213c1491 100644
--- a/mps/code/message.c
+++ b/mps/code/message.c
@@ -14,6 +14,7 @@
14 * "real work" goes on in the modules that provide the actual messages. 14 * "real work" goes on in the modules that provide the actual messages.
15 */ 15 */
16 16
17#include "bt.h"
17#include "mpm.h" 18#include "mpm.h"
18 19
19SRCID(message, "$Id$"); 20SRCID(message, "$Id$");
diff --git a/mps/code/misc.h b/mps/code/misc.h
index d8ecff44f36..a1be7ba180a 100644
--- a/mps/code/misc.h
+++ b/mps/code/misc.h
@@ -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) 2001 Global Graphics Software.
5 * 6 *
6 * Small general things which are useful for C but aren't part of the 7 * Small general things which are useful for C but aren't part of the
7 * memory manager itself. The only reason that this file exists is 8 * memory manager itself. The only reason that this file exists is
@@ -22,25 +23,6 @@ enum {
22}; 23};
23 24
24 25
25/* offsetof -- offset of field within structure
26 *
27 * .hack.offsetof: On platform.sus8lc the offsetof macro is not defined
28 * (because LCC does not bother fixing up SunOS's broken header files).
29 * We define it here using normal C constructs. This hack is only
30 * required on platform.sus8lc and no other platforms. See
31 * change.mps.tracer2.170226
32 */
33
34#ifdef MPS_PF_SUS8LC
35#ifdef offsetof
36#error "offsetof was unexpectedly already defined on platform SUS8LC"
37#else
38#define offsetof(type, field) ((size_t)(((char *)&((type *)0)->field) \
39 - (char *)0))
40#endif /* offsetof */
41#endif /* MPS_PF_SUS8LC */
42
43
44/* SrcId -- source identification 26/* SrcId -- source identification
45 * 27 *
46 * Every C source file should start with a SRCID declaration to 28 * Every C source file should start with a SRCID declaration to
@@ -157,11 +139,15 @@ typedef const struct SrcIdStruct {
157 * Given a pointer to a field of a structure this returns a pointer to 139 * Given a pointer to a field of a structure this returns a pointer to
158 * the main structure. PARENT(foo_t, x, foo->x) == foo. 140 * the main structure. PARENT(foo_t, x, foo->x) == foo.
159 * 141 *
160 * This macro is thread-safe. design.mps.misc.parent.thread-safe 142 * This macro is thread-safe, see design.mps.misc.parent.thread-safe.
143 *
144 * That intermediate (void *) is required to stop some compilers complaining
145 * about alignment of 'type *' being greater than that of 'char *'. Which
146 * is true, but not a bug, since p really is a pointer into a 'type' struct.
161 */ 147 */
162 148
163#define PARENT(type, field, p) \ 149#define PARENT(type, field, p) \
164 ((type *)((char *)(p) - offsetof(type, field))) 150 ((type *)(void *)((char *)(p) - offsetof(type, field)))
165 151
166 152
167/* Bit Sets -- sets of integers in [0,N-1]. 153/* Bit Sets -- sets of integers in [0,N-1].
diff --git a/mps/code/mpm.c b/mps/code/mpm.c
index bfdc8dad29e..9bfc426a8d8 100644
--- a/mps/code/mpm.c
+++ b/mps/code/mpm.c
@@ -8,16 +8,27 @@
8 * 8 *
9 * .sources: design.mps.writef */ 9 * .sources: design.mps.writef */
10 10
11#include "check.h"
11#include "mpm.h" 12#include "mpm.h"
12#include <stdarg.h> 13#include <stdarg.h>
13/* Get some floating constants for WriteDouble */ 14/* Get some floating constants for WriteDouble */
14#include <float.h> 15#include <float.h>
15#include <limits.h> 16#include <limits.h>
16 17
17
18SRCID(mpm, "$Id$"); 18SRCID(mpm, "$Id$");
19 19
20 20
21#if defined(CHECK)
22
23
24/* CheckLevel -- Control check level
25 *
26 * This controls the behaviour of Check methods (see impl.h.check).
27 */
28
29unsigned CheckLevel = CHECK_DEFAULT;
30
31
21/* MPMCheck -- test MPM assumptions */ 32/* MPMCheck -- test MPM assumptions */
22 33
23Bool MPMCheck(void) 34Bool MPMCheck(void)
@@ -112,6 +123,9 @@ Bool AlignCheck(Align align)
112} 123}
113 124
114 125
126#endif /* defined(CHECK) */
127
128
115/* WordIsAligned -- test whether a word is aligned */ 129/* WordIsAligned -- test whether a word is aligned */
116 130
117Bool (WordIsAligned)(Word word, Align align) 131Bool (WordIsAligned)(Word word, Align align)
@@ -446,7 +460,8 @@ Res WriteF(mps_lib_FILE *stream, ...)
446 460
447 case 'F': { /* function */ 461 case 'F': { /* function */
448 WriteFF f = va_arg(args, WriteFF); 462 WriteFF f = va_arg(args, WriteFF);
449 Byte *b = (Byte *)&f; 463 WriteFF *fp = &f; /* dodge to placate splint */
464 Byte *b = *((Byte **)&fp);
450 for(i=0; i < sizeof(WriteFF); i++) { 465 for(i=0; i < sizeof(WriteFF); i++) {
451 res = WriteWord(stream, (Word)(b[i]), 16, 466 res = WriteWord(stream, (Word)(b[i]), 16,
452 (CHAR_BIT + 3) / 4); 467 (CHAR_BIT + 3) / 4);
diff --git a/mps/code/mpm.h b/mps/code/mpm.h
index ecf16e2975c..ff9541eecaa 100644
--- a/mps/code/mpm.h
+++ b/mps/code/mpm.h
@@ -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 * .trans.bufferinit: The Buffer data structure has an Init field and 7 * .trans.bufferinit: The Buffer data structure has an Init field and
7 * an Init method, there's a name clash. We resolve this by calling the 8 * an Init method, there's a name clash. We resolve this by calling the
@@ -156,61 +157,6 @@ extern size_t StringLength(const char *s);
156extern char *MPSVersion(void); 157extern char *MPSVersion(void);
157 158
158 159
159/* Bit Table Interface -- see design.mps.bt.if.* for doc */
160
161/* design.mps.bt.if.size */
162extern size_t (BTSize)(unsigned long length);
163#define BTSize(n) (((n) + MPS_WORD_WIDTH-1) / MPS_WORD_WIDTH * sizeof(Word))
164
165
166/* design.mps.bt.if.get */
167extern Bool (BTGet)(BT bt, Index index);
168#define BTGet(a, i) \
169 ((Bool)(((a)[((i) >> MPS_WORD_SHIFT)] \
170 >> ((i) & ~((Word)-1 << MPS_WORD_SHIFT))) \
171 & (Word)1))
172
173/* design.mps.bt.if.set */
174extern void (BTSet)(BT bt, Index index);
175#define BTSet(a, i) \
176 BEGIN \
177 (a)[((i)>>MPS_WORD_SHIFT)] |= (Word)1<<((i)&~((Word)-1<<MPS_WORD_SHIFT)); \
178 END
179
180/* design.mps.bt.if.res */
181extern void (BTRes)(BT bt, Index index);
182#define BTRes(a, i) \
183 BEGIN \
184 (a)[((i)>>MPS_WORD_SHIFT)] &= \
185 ~((Word)1 << ((i) & ~((Word)-1<<MPS_WORD_SHIFT))); \
186 END
187
188extern Res BTCreate(BT *btReturn, Arena arena, Count length);
189extern void BTDestroy(BT bt, Arena arena, Count length);
190extern void BTSetRange(BT bt, Index base, Index limit);
191extern Bool BTIsSetRange(BT bt, Index base, Index limit);
192extern void BTResRange(BT bt, Index base, Index limit);
193extern Bool BTIsResRange(BT bt, Index base, Index limit);
194extern Bool BTFindShortResRange(Index *baseReturn, Index *limitReturn,
195 BT bt, Index searchBase, Index searchLimit,
196 unsigned long length);
197extern Bool BTFindShortResRangeHigh(Index *baseReturn, Index *limitReturn,
198 BT bt, Index searchBase, Index searchLimit,
199 unsigned long length);
200extern Bool BTFindLongResRange(Index *baseReturn, Index *limitReturn,
201 BT bt, Index searchBase, Index searchLimit,
202 unsigned long length);
203extern Bool BTFindLongResRangeHigh(Index *baseReturn, Index *limitReturn,
204 BT bt, Index searchBase, Index searchLimit,
205 unsigned long length);
206extern Bool BTRangesSame(BT BTx, BT BTy, Index base, Index limit);
207extern void BTCopyInvertRange(BT fromBT, BT toBT, Index base, Index limit);
208extern void BTCopyRange(BT fromBT, BT toBT, Index base, Index limit);
209extern void BTCopyOffsetRange(BT fromBT, BT toBT,
210 Index fromBase, Index fromLimit,
211 Index toBase, Index toLimit);
212
213
214/* Pool Interface -- see impl.c.pool */ 160/* Pool Interface -- see impl.c.pool */
215 161
216extern Res PoolInit(Pool pool, Arena arena, PoolClass class, ...); 162extern Res PoolInit(Pool pool, Arena arena, PoolClass class, ...);
@@ -253,6 +199,7 @@ extern void PoolFixEmergency(Pool pool, ScanState ss, Seg seg, Addr *refIO);
253extern void PoolReclaim(Pool pool, Trace trace, Seg seg); 199extern void PoolReclaim(Pool pool, Trace trace, Seg seg);
254extern void PoolWalk(Pool pool, Seg seg, FormattedObjectsStepMethod f, 200extern void PoolWalk(Pool pool, Seg seg, FormattedObjectsStepMethod f,
255 void *v, unsigned long s); 201 void *v, unsigned long s);
202extern void PoolFreeWalk(Pool pool, FreeBlockStepMethod f, void *p);
256extern Res PoolTrivInit(Pool pool, va_list arg); 203extern Res PoolTrivInit(Pool pool, va_list arg);
257extern void PoolTrivFinish(Pool pool); 204extern void PoolTrivFinish(Pool pool);
258extern Res PoolNoAlloc(Addr *pReturn, Pool pool, Size size, 205extern Res PoolNoAlloc(Addr *pReturn, Pool pool, Size size,
@@ -300,6 +247,7 @@ extern Res PoolTrivFramePop(Pool pool, Buffer buf, AllocFrame frame);
300extern void PoolNoFramePopPending(Pool pool, Buffer buf, AllocFrame frame); 247extern void PoolNoFramePopPending(Pool pool, Buffer buf, AllocFrame frame);
301extern void PoolNoWalk(Pool pool, Seg seg, FormattedObjectsStepMethod step, 248extern void PoolNoWalk(Pool pool, Seg seg, FormattedObjectsStepMethod step,
302 void *p, unsigned long s); 249 void *p, unsigned long s);
250extern void PoolNoFreeWalk(Pool pool, FreeBlockStepMethod f, void *p);
303extern PoolDebugMixin PoolNoDebugMixin(Pool pool); 251extern PoolDebugMixin PoolNoDebugMixin(Pool pool);
304extern BufferClass PoolNoBufferClass(void); 252extern BufferClass PoolNoBufferClass(void);
305 253
@@ -584,6 +532,7 @@ extern Size ArenaAvail(Arena arena);
584extern Res ArenaExtend(Arena, Addr base, Size size); 532extern Res ArenaExtend(Arena, Addr base, Size size);
585 533
586extern Res ArenaFinalize(Arena arena, Ref obj); 534extern Res ArenaFinalize(Arena arena, Ref obj);
535extern Res ArenaDefinalize(Arena arena, Ref obj);
587 536
588extern Bool ArenaIsReservedAddr(Arena arena, Addr addr); 537extern Bool ArenaIsReservedAddr(Arena arena, Addr addr);
589 538
@@ -611,7 +560,7 @@ extern Res ArenaNoExtend(Arena arena, Addr base, Size size);
611 560
612extern Bool SegPrefCheck(SegPref pref); 561extern Bool SegPrefCheck(SegPref pref);
613extern SegPref SegPrefDefault(void); 562extern SegPref SegPrefDefault(void);
614extern Res SegPrefExpress(SegPref pref, SegPrefKind kind, void *p); 563extern void SegPrefExpress(SegPref pref, SegPrefKind kind, void *p);
615 564
616extern void LocusInit(Arena arena); 565extern void LocusInit(Arena arena);
617extern void LocusFinish(Arena arena); 566extern void LocusFinish(Arena arena);
diff --git a/mps/code/mpmss.c b/mps/code/mpmss.c
index 3394e283f70..3bf764e8ccd 100644
--- a/mps/code/mpmss.c
+++ b/mps/code/mpmss.c
@@ -2,9 +2,11 @@
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 "mpscmv.h" 8#include "mpscmv.h"
9#include "mpscmvff.h"
8#include "mpslib.h" 10#include "mpslib.h"
9#include "mpsavm.h" 11#include "mpsavm.h"
10#include "testlib.h" 12#include "testlib.h"
@@ -23,8 +25,10 @@ extern mps_class_t PoolClassMFS(void);
23#define testLOOPS 10 25#define testLOOPS 10
24 26
25 27
26static mps_res_t stress(mps_class_t class, mps_arena_t arena, 28/* stress -- create a pool of the requested type and allocate in it */
27 size_t (*size)(int i), ...) 29
30static mps_res_t stress(mps_class_t class, size_t (*size)(int i),
31 mps_arena_t arena, ...)
28{ 32{
29 mps_res_t res; 33 mps_res_t res;
30 mps_pool_t pool; 34 mps_pool_t pool;
@@ -33,7 +37,7 @@ static mps_res_t stress(mps_class_t class, mps_arena_t arena,
33 int *ps[testSetSIZE]; 37 int *ps[testSetSIZE];
34 size_t ss[testSetSIZE]; 38 size_t ss[testSetSIZE];
35 39
36 va_start(arg, size); 40 va_start(arg, arena);
37 res = mps_pool_create_v(&pool, arena, class, arg); 41 res = mps_pool_create_v(&pool, arena, class, arg);
38 va_end(arg); 42 va_end(arg);
39 if (res != MPS_RES_OK) 43 if (res != MPS_RES_OK)
@@ -87,6 +91,10 @@ static mps_res_t stress(mps_class_t class, mps_arena_t arena,
87 91
88#define max(a, b) (((a) > (b)) ? (a) : (b)) 92#define max(a, b) (((a) > (b)) ? (a) : (b))
89 93
94#define alignUp(w, a) (((w) + (a) - 1) & ~((size_t)(a) - 1))
95
96
97/* randomSize -- produce sizes both latge and small */
90 98
91static size_t randomSize(int i) 99static size_t randomSize(int i)
92{ 100{
@@ -98,6 +106,18 @@ static size_t randomSize(int i)
98} 106}
99 107
100 108
109/* randomSize8 -- produce sizes both latge and small, 8-byte aligned */
110
111static size_t randomSize8(int i)
112{
113 size_t maxSize = 2 * 160 * 0x2000;
114 /* Reduce by a factor of 2 every 10 cycles. Total allocation about 40 MB. */
115 return alignUp(rnd() % max((maxSize >> (i / 10)), 2) + 1, 8);
116}
117
118
119/* fixedSize -- produce always the same size */
120
101static size_t fixedSizeSize = 0; 121static size_t fixedSizeSize = 0;
102 122
103static size_t fixedSize(int i) 123static size_t fixedSize(int i)
@@ -107,23 +127,35 @@ static size_t fixedSize(int i)
107} 127}
108 128
109 129
110static mps_pool_debug_option_s debugOptions = { (void *)"postpost", 8 }; 130/* testInArena -- test all the pool classes in the given arena */
131
132static mps_pool_debug_option_s bothOptions =
133 { (void *)"postpost", 8, (void *)"DEAD", 4 };
134
135static mps_pool_debug_option_s fenceOptions =
136 { (void *)"\0XXX ''\"\"'' XXX\0", 16, NULL, 0 };
111 137
112static int testInArena(mps_arena_t arena) 138static int testInArena(mps_arena_t arena, mps_pool_debug_option_s *options)
113{ 139{
140 /* IWBN to test MVFFDebug, but the MPS doesn't support debugging */
141 /* cross-segment allocation (possibly MVFF ought not to). */
142 printf("MVFF\n");
143 die(stress(mps_class_mvff(), randomSize8, arena,
144 (size_t)65536, (size_t)32, (size_t)4, TRUE, TRUE, TRUE),
145 "stress MVFF");
114 printf("MV debug\n"); 146 printf("MV debug\n");
115 die(stress(mps_class_mv_debug(), arena, randomSize, 147 die(stress(mps_class_mv_debug(), randomSize, arena,
116 &debugOptions, (size_t)65536, (size_t)32, (size_t)65536), 148 options, (size_t)65536, (size_t)32, (size_t)65536),
117 "stress MV debug"); 149 "stress MV debug");
118 150
119 printf("MFS\n"); 151 printf("MFS\n");
120 fixedSizeSize = 13; 152 fixedSizeSize = 13;
121 die(stress(PoolClassMFS(), 153 die(stress(PoolClassMFS(),
122 arena, fixedSize, (size_t)100000, fixedSizeSize), 154 fixedSize, arena, (size_t)100000, fixedSizeSize),
123 "stress MFS"); 155 "stress MFS");
124 156
125 printf("MV\n"); 157 printf("MV\n");
126 die(stress(mps_class_mv(), arena, randomSize, 158 die(stress(mps_class_mv(), randomSize, arena,
127 (size_t)65536, (size_t)32, (size_t)65536), 159 (size_t)65536, (size_t)32, (size_t)65536),
128 "stress MV"); 160 "stress MV");
129 161
@@ -139,12 +171,12 @@ int main(int argc, char **argv)
139 171
140 die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE), 172 die(mps_arena_create(&arena, mps_arena_class_vm(), testArenaSIZE),
141 "mps_arena_create"); 173 "mps_arena_create");
142 testInArena(arena); 174 testInArena(arena, &bothOptions);
143 mps_arena_destroy(arena); 175 mps_arena_destroy(arena);
144 176
145 die(mps_arena_create(&arena, mps_arena_class_vm(), smallArenaSIZE), 177 die(mps_arena_create(&arena, mps_arena_class_vm(), smallArenaSIZE),
146 "mps_arena_create"); 178 "mps_arena_create");
147 testInArena(arena); 179 testInArena(arena, &fenceOptions);
148 mps_arena_destroy(arena); 180 mps_arena_destroy(arena);
149 181
150 fflush(stdout); /* synchronize */ 182 fflush(stdout); /* synchronize */
diff --git a/mps/code/mpmst.h b/mps/code/mpmst.h
index 6c7a50642e5..ab03c57d704 100644
--- a/mps/code/mpmst.h
+++ b/mps/code/mpmst.h
@@ -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) 2001 Global Graphics Software.
5 * 6 *
6 * .design: This header file crosses module boundaries. The relevant 7 * .design: This header file crosses module boundaries. The relevant
7 * design a module's structures should be found in that module's design 8 * design a module's structures should be found in that module's design
@@ -71,6 +72,7 @@ typedef struct PoolClassStruct {
71 PoolFramePopMethod framePop; /* pop an allocation frame */ 72 PoolFramePopMethod framePop; /* pop an allocation frame */
72 PoolFramePopPendingMethod framePopPending; /* notify pending pop */ 73 PoolFramePopPendingMethod framePopPending; /* notify pending pop */
73 PoolWalkMethod walk; /* walk over a segment */ 74 PoolWalkMethod walk; /* walk over a segment */
75 PoolFreeWalkMethod freewalk; /* walk over free blocks */
74 PoolBufferClassMethod bufferClass; /* default BufferClass of pool */ 76 PoolBufferClassMethod bufferClass; /* default BufferClass of pool */
75 PoolDescribeMethod describe; /* describe the contents of the pool */ 77 PoolDescribeMethod describe; /* describe the contents of the pool */
76 PoolDebugMixinMethod debugMixin; /* find the debug mixin, if any */ 78 PoolDebugMixinMethod debugMixin; /* find the debug mixin, if any */
diff --git a/mps/code/mpmtypes.h b/mps/code/mpmtypes.h
index 5263163688e..28dafbcd9b5 100644
--- a/mps/code/mpmtypes.h
+++ b/mps/code/mpmtypes.h
@@ -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) 2001 Global Graphics Software.
5 * 6 *
6 * .design: design.mps.type 7 * .design: design.mps.type
7 * 8 *
@@ -137,8 +138,12 @@ typedef Res (*TraceFixMethod)(ScanState ss, Ref *refIO);
137/* Heap Walker */ 138/* Heap Walker */
138 139
139/* This type is used by the PoolClass method Walk */ 140/* This type is used by the PoolClass method Walk */
140typedef void (*FormattedObjectsStepMethod)(Addr, Format, Pool, 141typedef void (*FormattedObjectsStepMethod)(Addr obj, Format fmt, Pool pool,
141 void *, Size); 142 void *v, unsigned long s);
143
144/* This type is used by the PoolClass method Walk */
145typedef void (*FreeBlockStepMethod)(Addr base, Addr limit, Pool pool, void *p);
146
142 147
143/* Seg*Method -- see design.mps.seg */ 148/* Seg*Method -- see design.mps.seg */
144 149
@@ -212,7 +217,8 @@ typedef void (*PoolFramePopPendingMethod)(Pool pool, Buffer buf,
212 AllocFrame frame); 217 AllocFrame frame);
213typedef void (*PoolWalkMethod)(Pool pool, Seg seg, 218typedef void (*PoolWalkMethod)(Pool pool, Seg seg,
214 FormattedObjectsStepMethod f, 219 FormattedObjectsStepMethod f,
215 void *p, unsigned long s); 220 void *v, unsigned long s);
221typedef void (*PoolFreeWalkMethod)(Pool pool, FreeBlockStepMethod f, void *p);
216typedef BufferClass (*PoolBufferClassMethod)(void); 222typedef BufferClass (*PoolBufferClassMethod)(void);
217typedef Res (*PoolDescribeMethod)(Pool pool, mps_lib_FILE *stream); 223typedef Res (*PoolDescribeMethod)(Pool pool, mps_lib_FILE *stream);
218typedef PoolDebugMixin (*PoolDebugMixinMethod)(Pool pool); 224typedef PoolDebugMixin (*PoolDebugMixinMethod)(Pool pool);
@@ -294,10 +300,11 @@ typedef Res (*RootScanRegMethod)(ScanState ss, Thread thread, void *p, size_t s)
294 300
295/* Format varieties */ 301/* Format varieties */
296enum { 302enum {
297 FormatVarietyA = 1, 303 FormatVarietyA = 1,
298 FormatVarietyB, 304 FormatVarietyB,
299 FormatVarietyAutoHeader, 305 FormatVarietyAutoHeader,
300 FormatVarietyLIMIT 306 FormatVarietyFixed,
307 FormatVarietyLIMIT
301}; 308};
302 309
303 310
diff --git a/mps/code/mps.h b/mps/code/mps.h
index eb7812143c3..10849aa63f5 100644
--- a/mps/code/mps.h
+++ b/mps/code/mps.h
@@ -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 * .readership: customers, MPS developers. 7 * .readership: customers, MPS developers.
7 * .sources: design.mps.interface.c. 8 * .sources: design.mps.interface.c.
@@ -10,7 +11,6 @@
10#ifndef mps_h 11#ifndef mps_h
11#define mps_h 12#define mps_h
12 13
13#include "mpstd.h" /* detect platform */
14#include <stddef.h> 14#include <stddef.h>
15#include <stdarg.h> 15#include <stdarg.h>
16#include <limits.h> 16#include <limits.h>
@@ -39,7 +39,7 @@ typedef struct mps_frame_s
39 39
40/* Concrete Types */ 40/* Concrete Types */
41 41
42typedef MPS_T_WORD mps_word_t; /* machine word (target dep.) */ 42typedef unsigned long mps_word_t; /* pointer-sized word */
43typedef int mps_bool_t; /* boolean (int) */ 43typedef int mps_bool_t; /* boolean (int) */
44typedef int mps_res_t; /* result code (int) */ 44typedef int mps_res_t; /* result code (int) */
45typedef unsigned mps_shift_t; /* shift amount (unsigned int) */ 45typedef unsigned mps_shift_t; /* shift amount (unsigned int) */
@@ -133,11 +133,13 @@ typedef struct mps_sac_s {
133} mps_sac_s; 133} mps_sac_s;
134 134
135/* .sacc: Keep in sync with impl.h.sac. */ 135/* .sacc: Keep in sync with impl.h.sac. */
136typedef struct mps_sac_classes_s { 136typedef struct mps_sac_class_s {
137 size_t mps_block_size; 137 size_t mps_block_size;
138 size_t mps_cached_count; 138 size_t mps_cached_count;
139 unsigned mps_frequency; 139 unsigned mps_frequency;
140} mps_sac_classes_s; 140} mps_sac_class_s;
141
142#define mps_sac_classes_s mps_sac_class_s
141 143
142 144
143/* Location Dependency */ 145/* Location Dependency */
@@ -210,6 +212,15 @@ typedef struct mps_fmt_auto_header_s {
210} mps_fmt_auto_header_s; 212} mps_fmt_auto_header_s;
211 213
212 214
215typedef struct mps_fmt_fixed_s {
216 mps_align_t align;
217 mps_fmt_scan_t scan;
218 mps_fmt_fwd_t fwd;
219 mps_fmt_isfwd_t isfwd;
220 mps_fmt_pad_t pad;
221} mps_fmt_fixed_s;
222
223
213/* Internal Definitions */ 224/* Internal Definitions */
214 225
215#define MPS_BEGIN do { 226#define MPS_BEGIN do {
@@ -222,15 +233,6 @@ typedef struct mps_fmt_auto_header_s {
222 */ 233 */
223 234
224 235
225/* Assertion Handling */
226
227typedef void (*mps_assert_t)(const char *, const char *, const char *,
228 unsigned);
229
230extern mps_assert_t mps_assert_install(mps_assert_t);
231extern mps_assert_t mps_assert_default(void);
232
233
234/* arenas */ 236/* arenas */
235 237
236extern void mps_arena_clamp(mps_arena_t); 238extern void mps_arena_clamp(mps_arena_t);
@@ -278,6 +280,8 @@ extern mps_res_t mps_fmt_create_B(mps_fmt_t *, mps_arena_t,
278 mps_fmt_B_s *); 280 mps_fmt_B_s *);
279extern mps_res_t mps_fmt_create_auto_header(mps_fmt_t *, mps_arena_t, 281extern mps_res_t mps_fmt_create_auto_header(mps_fmt_t *, mps_arena_t,
280 mps_fmt_auto_header_s *); 282 mps_fmt_auto_header_s *);
283extern mps_res_t mps_fmt_create_fixed(mps_fmt_t *, mps_arena_t,
284 mps_fmt_fixed_s *);
281extern void mps_fmt_destroy(mps_fmt_t); 285extern void mps_fmt_destroy(mps_fmt_t);
282 286
283 287
@@ -481,22 +485,8 @@ extern mps_res_t mps_stack_scan_ambig(mps_ss_t, mps_thr_t,
481/* Protection Trampoline and Thread Registration */ 485/* Protection Trampoline and Thread Registration */
482 486
483typedef void *(*mps_tramp_t)(void *, size_t); 487typedef void *(*mps_tramp_t)(void *, size_t);
484
485extern void (mps_tramp)(void **, mps_tramp_t, void *, size_t); 488extern void (mps_tramp)(void **, mps_tramp_t, void *, size_t);
486 489
487#ifndef mps_tramp /* If a platform-specific version hasn't been defined */
488
489#define mps_tramp(r_o, f, p, s) \
490 MPS_BEGIN \
491 void **_r_o = (r_o); \
492 mps_tramp_t _f = (f); \
493 void *_p = (p); \
494 size_t _s = (s); \
495 *_r_o = (*_f)(_p, _s); \
496 MPS_END
497
498#endif
499
500extern mps_res_t mps_thread_reg(mps_thr_t *, mps_arena_t); 490extern mps_res_t mps_thread_reg(mps_thr_t *, mps_arena_t);
501extern void mps_thread_dereg(mps_thr_t); 491extern void mps_thread_dereg(mps_thr_t);
502 492
@@ -542,7 +532,7 @@ extern size_t mps_message_gc_not_condemned_size(mps_arena_t,
542/* Finalization */ 532/* Finalization */
543 533
544extern mps_res_t mps_finalize(mps_arena_t, mps_addr_t *); 534extern mps_res_t mps_finalize(mps_arena_t, mps_addr_t *);
545extern void mps_definalize(mps_arena_t, mps_addr_t *); 535extern mps_res_t mps_definalize(mps_arena_t, mps_addr_t *);
546 536
547 537
548/* Telemetry */ 538/* Telemetry */
@@ -573,15 +563,18 @@ extern void mps_arena_roots_walk(mps_arena_t,
573 void *, size_t); 563 void *, size_t);
574 564
575 565
576/* Fenceposting */ 566/* Allocation debug options */
577 567
578 568
579typedef struct mps_pool_debug_option_s { 569typedef struct mps_pool_debug_option_s {
580 void* fence_template; 570 void* fence_template;
581 size_t fence_size; 571 size_t fence_size;
572 void* free_template;
573 size_t free_size;
582} mps_pool_debug_option_s; 574} mps_pool_debug_option_s;
583 575
584extern void mps_pool_check_fenceposts(mps_pool_t); 576extern void mps_pool_check_fenceposts(mps_pool_t);
577extern void mps_pool_check_free_space(mps_pool_t);
585 578
586 579
587/* Scanner Support */ 580/* Scanner Support */
@@ -598,7 +591,8 @@ extern mps_res_t mps_fix(mps_ss_t, mps_addr_t *);
598 { 591 {
599 592
600#define MPS_FIX1(ss, ref) \ 593#define MPS_FIX1(ss, ref) \
601 (_mps_wt = 1uL<<((mps_word_t)(ref)>>_mps_w0&(MPS_WORD_WIDTH-1)), \ 594 (_mps_wt = 1uL << ((mps_word_t)(ref) >> _mps_w0 \
595 & (sizeof(mps_word_t) * CHAR_BIT - 1)), \
602 _mps_w2 |= _mps_wt, \ 596 _mps_w2 |= _mps_wt, \
603 _mps_w1 & _mps_wt) 597 _mps_w1 & _mps_wt)
604 598
diff --git a/mps/code/mpscams.h b/mps/code/mpscams.h
index 1d881c00497..82eb3f210cf 100644
--- a/mps/code/mpscams.h
+++ b/mps/code/mpscams.h
@@ -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#ifndef mpscams_h 8#ifndef mpscams_h
@@ -10,5 +11,6 @@
10#include "mps.h" 11#include "mps.h"
11 12
12extern mps_class_t mps_class_ams(void); 13extern mps_class_t mps_class_ams(void);
14extern mps_class_t mps_class_ams_debug(void);
13 15
14#endif /* mpscams_h */ 16#endif /* mpscams_h */
diff --git a/mps/code/mpsi.c b/mps/code/mpsi.c
index 09bac2ef6aa..5f338acf9ac 100644
--- a/mps/code/mpsi.c
+++ b/mps/code/mpsi.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 * .purpose: This code bridges between the MPS interface to C, 7 * .purpose: This code bridges between the MPS interface to C,
7 * impl.h.mps, and the internal MPM interfaces, as defined by 8 * impl.h.mps, and the internal MPM interfaces, as defined by
@@ -186,18 +187,6 @@ mps_rank_t mps_rank_weak(void)
186} 187}
187 188
188 189
189mps_assert_t mps_assert_install(mps_assert_t handler)
190{
191 AVER(handler != NULL);
192 return AssertInstall(handler);
193}
194
195mps_assert_t mps_assert_default(void)
196{
197 return AssertDefault();
198}
199
200
201mps_res_t mps_arena_extend(mps_arena_t mps_arena, 190mps_res_t mps_arena_extend(mps_arena_t mps_arena,
202 mps_addr_t base, size_t size) 191 mps_addr_t base, size_t size)
203{ 192{
@@ -442,6 +431,7 @@ void mps_space_destroy(mps_space_t mps_space)
442} 431}
443#endif 432#endif
444 433
434
445/* mps_arena_has_addr -- is this address managed by this arena? */ 435/* mps_arena_has_addr -- is this address managed by this arena? */
446 436
447mps_bool_t mps_arena_has_addr(mps_arena_t mps_arena, mps_addr_t p) 437mps_bool_t mps_arena_has_addr(mps_arena_t mps_arena, mps_addr_t p)
@@ -554,7 +544,7 @@ mps_res_t mps_fmt_create_auto_header(mps_fmt_t *mps_fmt_o,
554 (FormatSkipMethod)mps_fmt->skip, 544 (FormatSkipMethod)mps_fmt->skip,
555 (FormatMoveMethod)mps_fmt->fwd, 545 (FormatMoveMethod)mps_fmt->fwd,
556 (FormatIsMovedMethod)mps_fmt->isfwd, 546 (FormatIsMovedMethod)mps_fmt->isfwd,
557 (FormatCopyMethod)NULL, 547 NULL,
558 (FormatPadMethod)mps_fmt->pad, 548 (FormatPadMethod)mps_fmt->pad,
559 NULL, 549 NULL,
560 (Size)mps_fmt->mps_headerSize); 550 (Size)mps_fmt->mps_headerSize);
@@ -567,6 +557,41 @@ mps_res_t mps_fmt_create_auto_header(mps_fmt_t *mps_fmt_o,
567} 557}
568 558
569 559
560/* mps_fmt_create_fixed -- create an object format of variant fixed */
561
562mps_res_t mps_fmt_create_fixed(mps_fmt_t *mps_fmt_o,
563 mps_arena_t mps_arena,
564 mps_fmt_fixed_s *mps_fmt_fixed)
565{
566 Arena arena = (Arena)mps_arena;
567 Format format;
568 Res res;
569
570 ArenaEnter(arena);
571
572 AVER(mps_fmt_fixed != NULL);
573
574 res = FormatCreate(&format,
575 arena,
576 (Align)mps_fmt_fixed->align,
577 FormatVarietyFixed,
578 (FormatScanMethod)mps_fmt_fixed->scan,
579 NULL,
580 (FormatMoveMethod)mps_fmt_fixed->fwd,
581 (FormatIsMovedMethod)mps_fmt_fixed->isfwd,
582 NULL,
583 (FormatPadMethod)mps_fmt_fixed->pad,
584 NULL,
585 (Size)0);
586
587 ArenaLeave(arena);
588
589 if (res != ResOK) return res;
590 *mps_fmt_o = (mps_fmt_t)format;
591 return MPS_RES_OK;
592}
593
594
570/* mps_fmt_destroy -- destroy a format object */ 595/* mps_fmt_destroy -- destroy a format object */
571 596
572void mps_fmt_destroy(mps_fmt_t mps_fmt) 597void mps_fmt_destroy(mps_fmt_t mps_fmt)
@@ -1462,7 +1487,7 @@ mps_word_t mps_collections(mps_arena_t mps_arena)
1462} 1487}
1463 1488
1464 1489
1465/* mps_finalize -- register for finalize */ 1490/* mps_finalize -- register for finalization */
1466 1491
1467mps_res_t mps_finalize(mps_arena_t mps_arena, mps_addr_t *refref) 1492mps_res_t mps_finalize(mps_arena_t mps_arena, mps_addr_t *refref)
1468{ 1493{
@@ -1479,11 +1504,22 @@ mps_res_t mps_finalize(mps_arena_t mps_arena, mps_addr_t *refref)
1479 return res; 1504 return res;
1480} 1505}
1481 1506
1482void mps_definalize(mps_arena_t arena, mps_addr_t *refref) 1507
1508/* mps_definalize -- deregister for finalization */
1509
1510mps_res_t mps_definalize(mps_arena_t mps_arena, mps_addr_t *refref)
1483{ 1511{
1484 /* Not yet implemented */ 1512 Res res;
1485 UNUSED(arena); UNUSED(refref); 1513 Addr object;
1486 NOTREACHED; 1514 Arena arena = (Arena)mps_arena;
1515
1516 ArenaEnter(arena);
1517
1518 object = (Addr)ArenaPeek(arena, (Addr)refref);
1519 res = ArenaDefinalize(arena, object);
1520
1521 ArenaLeave(arena);
1522 return res;
1487} 1523}
1488 1524
1489 1525
diff --git a/mps/code/mpsicv.c b/mps/code/mpsicv.c
index b22f845bf92..c6e765a2751 100644
--- a/mps/code/mpsicv.c
+++ b/mps/code/mpsicv.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 "testlib.h" 8#include "testlib.h"
@@ -10,11 +11,13 @@
10#include "mpscmv.h" 11#include "mpscmv.h"
11#include "fmtdy.h" 12#include "fmtdy.h"
12#include "fmtdytst.h" 13#include "fmtdytst.h"
13#include "mpstd.h"
14#ifdef MPS_OS_W3
15#include "mpsw3.h"
16#endif
17#include "mps.h" 14#include "mps.h"
15#if !defined(CONFIG_PROD_EPCORE)
16# include "mpstd.h"
17# ifdef MPS_OS_W3
18# include "mpsw3.h"
19# endif
20#endif
18#include <stdlib.h> 21#include <stdlib.h>
19#include <stdarg.h> 22#include <stdarg.h>
20#include <math.h> 23#include <math.h>
@@ -229,12 +232,12 @@ static void arena_commit_test(mps_arena_t arena)
229 die(mps_pool_create(&pool, arena, mps_class_mv(), 0x1000, 1024, 16384), 232 die(mps_pool_create(&pool, arena, mps_class_mv(), 0x1000, 1024, 16384),
230 "commit pool create"); 233 "commit pool create");
231 limit = mps_arena_commit_limit(arena); 234 limit = mps_arena_commit_limit(arena);
232 mps_arena_commit_limit_set(arena, committed); 235 die(mps_arena_commit_limit_set(arena, committed), "commit_limit_set before");
233 do { 236 do {
234 res = mps_alloc(&p, pool, FILLER_OBJECT_SIZE); 237 res = mps_alloc(&p, pool, FILLER_OBJECT_SIZE);
235 } while (res == MPS_RES_OK); 238 } while (res == MPS_RES_OK);
236 die_expect(res, MPS_RES_COMMIT_LIMIT, "Commit limit allocation"); 239 die_expect(res, MPS_RES_COMMIT_LIMIT, "Commit limit allocation");
237 mps_arena_commit_limit_set(arena, limit); 240 die(mps_arena_commit_limit_set(arena, limit), "commit_limit_set after");
238 res = mps_alloc(&p, pool, FILLER_OBJECT_SIZE); 241 res = mps_alloc(&p, pool, FILLER_OBJECT_SIZE);
239 die_expect(res, MPS_RES_OK, "Allocation failed after raising commit_limit"); 242 die_expect(res, MPS_RES_OK, "Allocation failed after raising commit_limit");
240 mps_pool_destroy(pool); 243 mps_pool_destroy(pool);
@@ -280,6 +283,8 @@ static void *test(void *arg, size_t s)
280 mps_addr_t obj; 283 mps_addr_t obj;
281 mps_ld_s ld; 284 mps_ld_s ld;
282 mps_alloc_pattern_t ramp = mps_alloc_pattern_ramp(); 285 mps_alloc_pattern_t ramp = mps_alloc_pattern_ramp();
286 size_t rampCount = 0;
287 mps_res_t res;
283 288
284 arena = (mps_arena_t)arg; 289 arena = (mps_arena_t)arg;
285 testlib_unused(s); 290 testlib_unused(s);
@@ -358,9 +363,20 @@ static void *test(void *arg, size_t s)
358 363
359 if (rnd() % patternFREQ == 0) 364 if (rnd() % patternFREQ == 0)
360 switch(rnd() % 4) { 365 switch(rnd() % 4) {
361 case 0: case 1: mps_ap_alloc_pattern_begin(ap, ramp); break; 366 case 0: case 1: {
362 case 2: mps_ap_alloc_pattern_end(ap, ramp); break; 367 die(mps_ap_alloc_pattern_begin(ap, ramp), "alloc_pattern_begin");
363 case 3: mps_ap_alloc_pattern_reset(ap); break; 368 ++rampCount;
369 } break;
370 case 2: {
371 res = mps_ap_alloc_pattern_end(ap, ramp);
372 cdie(rampCount > 0 ? res == MPS_RES_OK : res == MPS_RES_FAIL,
373 "alloc_pattern_end");
374 if (rampCount > 0) --rampCount;
375 } break;
376 case 3: {
377 die(mps_ap_alloc_pattern_reset(ap), "alloc_pattern_reset");
378 rampCount = 0;
379 } break;
364 } 380 }
365 381
366 if (rnd() & 1) 382 if (rnd() & 1)
@@ -377,7 +393,7 @@ static void *test(void *arg, size_t s)
377 reservoir_test(arena); 393 reservoir_test(arena);
378 alignmentTest(arena); 394 alignmentTest(arena);
379 395
380 mps_arena_collect(arena); 396 die(mps_arena_collect(arena), "collect");
381 397
382 mps_free(mv, alloced_obj, 32); 398 mps_free(mv, alloced_obj, 32);
383 alloc_v_test(mv); 399 alloc_v_test(mv);
@@ -402,26 +418,31 @@ int main(int argc, char **argv)
402{ 418{
403 mps_arena_t arena; 419 mps_arena_t arena;
404 mps_thr_t thread; 420 mps_thr_t thread;
421#if !defined(CONFIG_PROD_EPCORE) && !defined(CONFIG_PF_XCPPGC)
405 mps_root_t reg_root; 422 mps_root_t reg_root;
423#endif
406 void *r; 424 void *r;
407 void *marker = &marker; 425 void *marker = &marker;
408 426
409 randomize(argc, argv); 427 randomize(argc, argv);
410 428
411 (void)mps_assert_install(mps_assert_default());
412 die(mps_arena_create(&arena, mps_arena_class_vm(), TEST_ARENA_SIZE), 429 die(mps_arena_create(&arena, mps_arena_class_vm(), TEST_ARENA_SIZE),
413 "arena_create"); 430 "arena_create");
414 die(mps_thread_reg(&thread, arena), "thread_reg"); 431 die(mps_thread_reg(&thread, arena), "thread_reg");
415 432
433#if !defined(CONFIG_PROD_EPCORE) && !defined(CONFIG_PF_XCPPGC)
416 die(mps_root_create_reg(&reg_root, arena, 434 die(mps_root_create_reg(&reg_root, arena,
417 MPS_RANK_AMBIG, (mps_rm_t)0, 435 MPS_RANK_AMBIG, (mps_rm_t)0,
418 thread, &mps_stack_scan_ambig, 436 thread, &mps_stack_scan_ambig,
419 marker, (size_t)0), 437 marker, (size_t)0),
420 "root_create_reg"); 438 "root_create_reg");
439#endif
421 440
422 (mps_tramp)(&r, test, arena, 0); /* non-inlined trampoline */ 441 (mps_tramp)(&r, test, arena, 0); /* non-inlined trampoline */
423 mps_tramp(&r, test, arena, 0); 442 mps_tramp(&r, test, arena, 0);
443#if !defined(CONFIG_PROD_EPCORE) && !defined(CONFIG_PF_XCPPGC)
424 mps_root_destroy(reg_root); 444 mps_root_destroy(reg_root);
445#endif
425 mps_thread_dereg(thread); 446 mps_thread_dereg(thread);
426 mps_arena_destroy(arena); 447 mps_arena_destroy(arena);
427 448
diff --git a/mps/code/mpsiw3.c b/mps/code/mpsiw3.c
index b4b78638e92..f1992eecfd9 100644
--- a/mps/code/mpsiw3.c
+++ b/mps/code/mpsiw3.c
@@ -1,4 +1,4 @@
1/* impl.c.mpsint: 1/* impl.c.mpsiw3: WIN32 MEMORY POOL SYSTEM INTERFACE LAYER EXTRAS
2 * 2 *
3 * WIN32 MEMORY POOL SYSTEM INTERFACE LAYER EXTRAS 3 * WIN32 MEMORY POOL SYSTEM INTERFACE LAYER EXTRAS
4 * 4 *
@@ -12,9 +12,10 @@
12 12
13#include "mpswin.h" 13#include "mpswin.h"
14 14
15SRCID(mpsint, "$Id$"); 15SRCID(mpsiw3, "$Id$");
16 16
17/* This is defined in protnt.c */ 17
18/* This is defined in protw3.c */
18extern LONG ProtSEHfilter(LPEXCEPTION_POINTERS info); 19extern LONG ProtSEHfilter(LPEXCEPTION_POINTERS info);
19 20
20LONG mps_SEH_filter(LPEXCEPTION_POINTERS info, 21LONG mps_SEH_filter(LPEXCEPTION_POINTERS info,
diff --git a/mps/code/mpslib.h b/mps/code/mpslib.h
index 99c89c59ed7..204d080edd2 100644
--- a/mps/code/mpslib.h
+++ b/mps/code/mpslib.h
@@ -29,9 +29,7 @@ extern mps_lib_FILE *mps_lib_get_stdout(void);
29extern int mps_lib_fputc(int, mps_lib_FILE *); 29extern int mps_lib_fputc(int, mps_lib_FILE *);
30extern int mps_lib_fputs(const char *, mps_lib_FILE *); 30extern int mps_lib_fputs(const char *, mps_lib_FILE *);
31 31
32 32extern void mps_lib_assert_fail(const char *);
33extern void mps_lib_abort(void);
34
35 33
36extern void *(mps_lib_memset)(void *, int, size_t); 34extern void *(mps_lib_memset)(void *, int, size_t);
37extern void *(mps_lib_memcpy)(void *, const void *, size_t); 35extern void *(mps_lib_memcpy)(void *, const void *, size_t);
diff --git a/mps/code/mpsliban.c b/mps/code/mpsliban.c
index 5b5c16fbcec..8777d342a67 100644
--- a/mps/code/mpsliban.c
+++ b/mps/code/mpsliban.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 * .purpose: The purpose of this code is 7 * .purpose: The purpose of this code is
7 * 1. to connect the MPS Library Interface to the ANSI C libraries, 8 * 1. to connect the MPS Library Interface to the ANSI C libraries,
@@ -78,8 +79,11 @@ int mps_lib_fputs(const char *s, mps_lib_FILE *stream)
78} 79}
79 80
80 81
81void mps_lib_abort(void) 82void mps_lib_assert_fail(const char *message)
82{ 83{
84 fflush(stdout); /* synchronize */
85 fprintf(stderr, "\nMPS ASSERTION FAILURE: %s\n", message);
86 fflush(stderr); /* make sure the message is output */
83 abort(); 87 abort();
84} 88}
85 89
diff --git a/mps/code/mpstd.h b/mps/code/mpstd.h
index 62edfcdfa8d..68c98ec7556 100644
--- a/mps/code/mpstd.h
+++ b/mps/code/mpstd.h
@@ -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) 2001 Global Graphics Software.
5 * 6 *
6 * Detect the target platform using predefined preprocessor symbols 7 * Detect the target platform using predefined preprocessor symbols
7 * defined by the build environment. The symbols are derived from the 8 * defined by the build environment. The symbols are derived from the
@@ -24,8 +25,9 @@
24 * them. Alignment from testing. 25 * them. Alignment from testing.
25 */ 26 */
26 27
27#if defined(__sgi) && defined(__unix) && defined(__mips) \ 28#if defined(CONFIG_PF_I5M2CC) \
28 && defined(_SYSTYPE_SVR4) && (_MIPS_FPSET == 16) 29 || defined(__sgi) && defined(__unix) && defined(__mips) \
30 && defined(_SYSTYPE_SVR4) && (_MIPS_FPSET == 16)
29#define MPS_PF_I5M2CC 31#define MPS_PF_I5M2CC
30#define MPS_PF_STRING "i5m2cc" 32#define MPS_PF_STRING "i5m2cc"
31#define MPS_OS_I5 33#define MPS_OS_I5
@@ -38,8 +40,9 @@
38 40
39/* See above. Alignment from testing. */ 41/* See above. Alignment from testing. */
40 42
41#elif defined(__sgi) && defined(__unix) && defined(__mips) \ 43#elif defined(CONFIG_PF_IAM4CC) \
42 && defined(_SYSTYPE_SVR4) && defined(_ABIN32) 44 || defined(__sgi) && defined(__unix) && defined(__mips) \
45 && defined(_SYSTYPE_SVR4) && defined(_ABIN32)
43#define MPS_PF_IAM4CC 46#define MPS_PF_IAM4CC
44#define MPS_PF_STRING "iam4cc" 47#define MPS_PF_STRING "iam4cc"
45#define MPS_OS_IA 48#define MPS_OS_IA
@@ -52,7 +55,8 @@
52 55
53/* winnt.h from MS VC 2.0 */ 56/* winnt.h from MS VC 2.0 */
54 57
55#elif defined(_MSC_VER) && defined(_WIN32) && defined(_M_ALPHA) 58#elif defined(CONFIG_PF_W3ALMV) \
59 || defined(_MSC_VER) && defined(_WIN32) && defined(_M_ALPHA)
56#define MPS_PF_W3ALMV 60#define MPS_PF_W3ALMV
57#define MPS_PF_STRING "w3almv" 61#define MPS_PF_STRING "w3almv"
58#define MPS_OS_W3 62#define MPS_OS_W3
@@ -65,7 +69,8 @@
65 69
66/* winnt.h from MS VC 2.0 */ 70/* winnt.h from MS VC 2.0 */
67 71
68#elif defined(_MSC_VER) && defined(_WIN32) && defined(_M_PPC) 72#elif defined(CONFIG_PF_W3PPMV) \
73 || defined(_MSC_VER) && defined(_WIN32) && defined(_M_PPC)
69#define MPS_PF_W3PPMV 74#define MPS_PF_W3PPMV
70#define MPS_PF_STRING "w3ppmv" 75#define MPS_PF_STRING "w3ppmv"
71#define MPS_OS_W3 76#define MPS_OS_W3
@@ -83,7 +88,8 @@
83 * VC malloc is 16! 88 * VC malloc is 16!
84 */ 89 */
85 90
86#elif defined(_MSC_VER) && defined(_WIN32) && defined(_M_IX86) 91#elif defined(CONFIG_PF_W3I3MV) \
92 || defined(_MSC_VER) && defined(_WIN32) && defined(_M_IX86)
87#define MPS_PF_W3I3MV 93#define MPS_PF_W3I3MV
88#define MPS_PF_STRING "w3i3mv" 94#define MPS_PF_STRING "w3i3mv"
89#define MPS_OS_W3 95#define MPS_OS_W3
@@ -98,7 +104,8 @@
98 * a way to determine the OS -- we assume MacOS 7. 104 * a way to determine the OS -- we assume MacOS 7.
99 */ 105 */
100 106
101#elif defined(__MWERKS__) && __MC68K__ == 1 107#elif defined(CONFIG_PF_S760MW) \
108 || (defined(__MWERKS__) && __MC68K__ == 1)
102#define MPS_PF_S760MW 109#define MPS_PF_S760MW
103#define MPS_PF_STRING "s760mw" 110#define MPS_PF_STRING "s760mw"
104#define MPS_OS_S7 111#define MPS_OS_S7
@@ -113,7 +120,8 @@
113 * a way to determine the OS -- we assume MacOS 7. 120 * a way to determine the OS -- we assume MacOS 7.
114 */ 121 */
115 122
116#elif defined(__MWERKS__) && __POWERPC__ == 1 123#elif defined(CONFIG_PF_S7PPMW) \
124 || defined(__MWERKS__) && __POWERPC__ == 1
117#define MPS_PF_S7PPMW 125#define MPS_PF_S7PPMW
118#define MPS_PF_STRING "s7ppmw" 126#define MPS_PF_STRING "s7ppmw"
119#define MPS_OS_S7 127#define MPS_OS_S7
@@ -130,7 +138,8 @@
130 * which lets us determine the system version. 138 * which lets us determine the system version.
131 */ 139 */
132 140
133#elif defined(m68k) && (defined (applec) || defined(__SC__)) 141#elif defined(CONFIG_PF_S760AC) \
142 || defined(m68k) && (defined (applec) || defined(__SC__))
134#define MPS_PF_S760AC 143#define MPS_PF_S760AC
135#define MPS_PF_STRING "s760ac" 144#define MPS_PF_STRING "s760ac"
136#define MPS_OS_S7 145#define MPS_OS_S7
@@ -147,7 +156,8 @@
147 * which lets us determine the system version. 156 * which lets us determine the system version.
148 */ 157 */
149 158
150#elif defined(__PPCC__) || (defined(__MRC__) && defined(__POWERPC)) 159#elif defined(CONFIG_PF_S7PPAC) \
160 || defined(__PPCC__) || (defined(__MRC__) && defined(__POWERPC))
151#define MPS_PF_S7PPAC 161#define MPS_PF_S7PPAC
152#define MPS_PF_STRING "s7ppac" 162#define MPS_PF_STRING "s7ppac"
153#define MPS_OS_S7 163#define MPS_OS_S7
@@ -163,7 +173,9 @@
163 * ools/Preprocessor/Preprocessor.[ef].html> 173 * ools/Preprocessor/Preprocessor.[ef].html>
164 */ 174 */
165 175
166#elif defined(__APPLE__) && defined(__ppc__) && defined(__MACH__) && defined(__GNUC__) 176#elif defined(CONFIG_PF_XCPPGC) \
177 || defined(__APPLE__) && defined(__ppc__) && defined(__MACH__) \
178 && defined(__GNUC__)
167#define MPS_PF_XCPPGC 179#define MPS_PF_XCPPGC
168#define MPS_PF_STRING "xcppgc" 180#define MPS_PF_STRING "xcppgc"
169#define MPS_OS_XC 181#define MPS_OS_XC
@@ -176,8 +188,9 @@
176 188
177/* GCC 2.5.8, gcc -E -dM, (__SVR4 indicates Solaris) */ 189/* GCC 2.5.8, gcc -E -dM, (__SVR4 indicates Solaris) */
178 190
179#elif defined(__sun__) && defined(__sparc__) && defined(__GNUC__) \ 191#elif defined(CONFIG_PF_SUS8GC) \
180 && !defined(__svr4__) 192 || defined(__sun__) && defined(__sparc__) && defined(__GNUC__) \
193 && !defined(__svr4__)
181#define MPS_PF_SUS8GC 194#define MPS_PF_SUS8GC
182#define MPS_PF_STRING "sus8gc" 195#define MPS_PF_STRING "sus8gc"
183#define MPS_OS_SU 196#define MPS_OS_SU
@@ -190,8 +203,9 @@
190 203
191/* LCC 3.4 (ish), man page */ 204/* LCC 3.4 (ish), man page */
192 205
193#elif defined(sun) && defined(sparc) && defined(__LCC__) \ 206#elif defined(CONFIG_PF_SUS8LC) \
194 && !defined(__svr4__) 207 || defined(sun) && defined(sparc) && defined(__LCC__) \
208 && !defined(__svr4__)
195#define MPS_PF_SUS8LC 209#define MPS_PF_SUS8LC
196#define MPS_PF_STRING "sus8lc" 210#define MPS_PF_STRING "sus8lc"
197#define MPS_OS_SU 211#define MPS_OS_SU
@@ -204,8 +218,9 @@
204 218
205/* GCC 2.5.8, gcc -E -dM */ 219/* GCC 2.5.8, gcc -E -dM */
206 220
207#elif defined(__sun__) && defined(__sparc__) && defined(__GNUC__) \ 221#elif defined(CONFIG_PF_SOS8GC) \
208 && defined(__svr4__) 222 || defined(__sun__) && defined(__sparc__) && defined(__GNUC__) \
223 && defined(__svr4__)
209#define MPS_PF_SOS8GC 224#define MPS_PF_SOS8GC
210#define MPS_PF_STRING "sos8gc" 225#define MPS_PF_STRING "sos8gc"
211#define MPS_OS_SO 226#define MPS_OS_SO
@@ -221,9 +236,9 @@
221 * macros for that. 236 * macros for that.
222 */ 237 */
223 238
224#elif defined(__sun) && defined(__SUNPRO_C) && defined(__SVR4) \ 239#elif defined(CONFIG_PF_SOS9SC) \
225 && defined(__sparc) 240 || defined(__sun) && defined(__SUNPRO_C) && defined(__SVR4) \
226 241 && defined(__sparc)
227#define MPS_PF_SOS9SC 242#define MPS_PF_SOS9SC
228#define MPS_PF_STRING "sos9sc" 243#define MPS_PF_STRING "sos9sc"
229#define MPS_OS_SO 244#define MPS_OS_SO
@@ -236,7 +251,8 @@
236 251
237/* GCC 2.6.3, gcc -E -dM */ 252/* GCC 2.6.3, gcc -E -dM */
238 253
239#elif defined(__osf__) && defined(__alpha__) && defined(__GNUC__) 254#elif defined(CONFIG_PF_O1ALGC) \
255 || defined(__osf__) && defined(__alpha__) && defined(__GNUC__)
240#define MPS_PF_O1ALGC 256#define MPS_PF_O1ALGC
241#define MPS_PF_STRING "o1algc" 257#define MPS_PF_STRING "o1algc"
242#define MPS_OS_O1 258#define MPS_OS_O1
@@ -250,7 +266,8 @@
250 266
251/* From the cc(1) man page */ 267/* From the cc(1) man page */
252 268
253#elif defined(__osf__) && defined(__alpha) && defined(__DECC) 269#elif defined(CONFIG_PF_O1ALCC) \
270 || defined(__osf__) && defined(__alpha) && defined(__DECC)
254#define MPS_PF_O1ALCC 271#define MPS_PF_O1ALCC
255#define MPS_PF_STRING "o1alcc" 272#define MPS_PF_STRING "o1alcc"
256#define MPS_OS_O1 273#define MPS_OS_O1
@@ -267,7 +284,8 @@
267 * all 4. 284 * all 4.
268 */ 285 */
269 286
270#elif defined(__linux__) && defined(__i386__) && defined(__GNUC__) 287#elif defined(CONFIG_PF_LII4GC) \
288 || defined(__linux__) && defined(__i386__) && defined(__GNUC__)
271#define MPS_PF_LII4GC 289#define MPS_PF_LII4GC
272#define MPS_PF_STRING "lii4gc" 290#define MPS_PF_STRING "lii4gc"
273#define MPS_OS_LI 291#define MPS_OS_LI
@@ -280,7 +298,8 @@
280 298
281/* GCC 2.7.2, gcc -E -dM */ 299/* GCC 2.7.2, gcc -E -dM */
282 300
283#elif defined(__linux__) && defined(__PPC__) && defined(__GNUC__) 301#elif defined(CONFIG_PF_LIPPGC) \
302 || defined(__linux__) && defined(__PPC__) && defined(__GNUC__)
284#define MPS_PF_LIPPGC 303#define MPS_PF_LIPPGC
285#define MPS_PF_STRING "lippgc" 304#define MPS_PF_STRING "lippgc"
286#define MPS_OS_LI 305#define MPS_OS_LI
@@ -294,7 +313,8 @@
294/* GCC 2.95.3, gcc -E -dM 313/* GCC 2.95.3, gcc -E -dM
295 */ 314 */
296 315
297#elif defined(__FreeBSD__) && defined (__i386__) && defined (__GNUC__) 316#elif defined(CONFIG_PF_FRI4GC) \
317 || defined(__FreeBSD__) && defined (__i386__) && defined (__GNUC__)
298#define MPS_PF_FRI4GC 318#define MPS_PF_FRI4GC
299#define MPS_PF_STRING "fri4gc" 319#define MPS_PF_STRING "fri4gc"
300#define MPS_OS_FR 320#define MPS_OS_FR
diff --git a/mps/code/mpsw3.h b/mps/code/mpsw3.h
index 57c9f58619e..cd62dd8a8c6 100644
--- a/mps/code/mpsw3.h
+++ b/mps/code/mpsw3.h
@@ -11,15 +11,13 @@
11#define mpsw3_h 11#define mpsw3_h
12 12
13#include "mps.h" /* needed for mps_tramp_t */ 13#include "mps.h" /* needed for mps_tramp_t */
14#include "mpswin.h" /* needed for SEH filter */ 14#include <windows.h> /* needed for SEH filter */
15 15
16 16
17extern LONG mps_SEH_filter(LPEXCEPTION_POINTERS, void **, size_t *); 17extern LONG mps_SEH_filter(LPEXCEPTION_POINTERS, void **, size_t *);
18extern void mps_SEH_handler(void *, size_t); 18extern void mps_SEH_handler(void *, size_t);
19 19
20 20
21#undef mps_tramp /* Override generic version */
22
23#define mps_tramp(r_o, f, p, s) \ 21#define mps_tramp(r_o, f, p, s) \
24 MPS_BEGIN \ 22 MPS_BEGIN \
25 void **_r_o = (r_o); \ 23 void **_r_o = (r_o); \
diff --git a/mps/code/pool.c b/mps/code/pool.c
index 71f32977824..c9de434b10e 100644
--- a/mps/code/pool.c
+++ b/mps/code/pool.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) 2001 Global Graphics Software.
5 * 6 *
6 * DESIGN 7 * DESIGN
7 * 8 *
@@ -51,10 +52,13 @@ Bool PoolClassCheck(PoolClass class)
51 CHECKL(FUNCHECK(class->free)); 52 CHECKL(FUNCHECK(class->free));
52 CHECKL(FUNCHECK(class->bufferFill)); 53 CHECKL(FUNCHECK(class->bufferFill));
53 CHECKL(FUNCHECK(class->bufferEmpty)); 54 CHECKL(FUNCHECK(class->bufferEmpty));
55 CHECKL(FUNCHECK(class->access));
54 CHECKL(FUNCHECK(class->whiten)); 56 CHECKL(FUNCHECK(class->whiten));
55 CHECKL(FUNCHECK(class->grey)); 57 CHECKL(FUNCHECK(class->grey));
58 CHECKL(FUNCHECK(class->blacken));
56 CHECKL(FUNCHECK(class->scan)); 59 CHECKL(FUNCHECK(class->scan));
57 CHECKL(FUNCHECK(class->fix)); 60 CHECKL(FUNCHECK(class->fix));
61 CHECKL(FUNCHECK(class->fixEmergency));
58 CHECKL(FUNCHECK(class->reclaim)); 62 CHECKL(FUNCHECK(class->reclaim));
59 CHECKL(FUNCHECK(class->rampBegin)); 63 CHECKL(FUNCHECK(class->rampBegin));
60 CHECKL(FUNCHECK(class->rampEnd)); 64 CHECKL(FUNCHECK(class->rampEnd));
@@ -62,7 +66,10 @@ Bool PoolClassCheck(PoolClass class)
62 CHECKL(FUNCHECK(class->framePop)); 66 CHECKL(FUNCHECK(class->framePop));
63 CHECKL(FUNCHECK(class->framePopPending)); 67 CHECKL(FUNCHECK(class->framePopPending));
64 CHECKL(FUNCHECK(class->walk)); 68 CHECKL(FUNCHECK(class->walk));
69 CHECKL(FUNCHECK(class->freewalk));
70 CHECKL(FUNCHECK(class->bufferClass));
65 CHECKL(FUNCHECK(class->describe)); 71 CHECKL(FUNCHECK(class->describe));
72 CHECKL(FUNCHECK(class->debugMixin));
66 CHECKS(PoolClass, class); 73 CHECKS(PoolClass, class);
67 return TRUE; 74 return TRUE;
68} 75}
@@ -452,7 +459,7 @@ void PoolReclaim(Pool pool, Trace trace, Seg seg)
452} 459}
453 460
454 461
455/* PoolWalk -- walk objects in this pool */ 462/* PoolWalk -- walk objects in this segment */
456 463
457void PoolWalk(Pool pool, Seg seg, FormattedObjectsStepMethod f, 464void PoolWalk(Pool pool, Seg seg, FormattedObjectsStepMethod f,
458 void *p, Size s) 465 void *p, Size s)
@@ -466,6 +473,21 @@ void PoolWalk(Pool pool, Seg seg, FormattedObjectsStepMethod f,
466} 473}
467 474
468 475
476/* PoolFreeWalk -- walk free blocks in this pool
477 *
478 * PoolFreeWalk is not required to find all free blocks.
479 */
480
481void PoolFreeWalk(Pool pool, FreeBlockStepMethod f, void *p)
482{
483 AVERT(Pool, pool);
484 AVER(FUNCHECK(f));
485 /* p is arbitrary, hence can't be checked. */
486
487 (*pool->class->freewalk)(pool, f, p);
488}
489
490
469/* PoolDescribe -- describe a pool */ 491/* PoolDescribe -- describe a pool */
470 492
471Res PoolDescribe(Pool pool, mps_lib_FILE *stream) 493Res PoolDescribe(Pool pool, mps_lib_FILE *stream)
diff --git a/mps/code/poolabs.c b/mps/code/poolabs.c
index 86fd76ddf31..eaab36f4d12 100644
--- a/mps/code/poolabs.c
+++ b/mps/code/poolabs.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 * PURPOSE 7 * PURPOSE
7 * 8 *
@@ -141,6 +142,7 @@ DEFINE_CLASS(AbstractPoolClass, class)
141 class->framePop = PoolNoFramePop; 142 class->framePop = PoolNoFramePop;
142 class->framePopPending = PoolNoFramePopPending; 143 class->framePopPending = PoolNoFramePopPending;
143 class->walk = PoolNoWalk; 144 class->walk = PoolNoWalk;
145 class->freewalk = PoolNoFreeWalk;
144 class->bufferClass = PoolNoBufferClass; 146 class->bufferClass = PoolNoBufferClass;
145 class->describe = PoolTrivDescribe; 147 class->describe = PoolTrivDescribe;
146 class->debugMixin = PoolNoDebugMixin; 148 class->debugMixin = PoolNoDebugMixin;
@@ -620,6 +622,18 @@ void PoolNoWalk(Pool pool, Seg seg,
620} 622}
621 623
622 624
625void PoolNoFreeWalk(Pool pool, FreeBlockStepMethod f, void *p)
626{
627 AVERT(Pool, pool);
628 AVER(FUNCHECK(f));
629 /* p is arbitrary, hence can't be checked */
630 UNUSED(p);
631
632 /* FreeWalk doesn't have be perfect, so just pretend you didn't find any. */
633 NOOP;
634}
635
636
623BufferClass PoolNoBufferClass(void) 637BufferClass PoolNoBufferClass(void)
624{ 638{
625 NOTREACHED; 639 NOTREACHED;
diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c
index 417d5cb455f..66a515b258b 100644
--- a/mps/code/poolamc.c
+++ b/mps/code/poolamc.c
@@ -2,12 +2,14 @@
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 * .sources: design.mps.poolamc. 7 * .sources: design.mps.poolamc.
7 */ 8 */
8 9
9#include "mpscamc.h" 10#include "mpscamc.h"
10#include "chain.h" 11#include "chain.h"
12#include "bt.h"
11#include "mpm.h" 13#include "mpm.h"
12 14
13SRCID(poolamc, "$Id$"); 15SRCID(poolamc, "$Id$");
@@ -1694,14 +1696,7 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
1694 arena = PoolArena(pool); 1696 arena = PoolArena(pool);
1695 AVERT(Arena, arena); 1697 AVERT(Arena, arena);
1696 1698
1697 if (!amcSegHasNailboard(seg)) { 1699 /* see design.mps.poolamc.nailboard.limitations for improvements */
1698 /* We didn't keep a mark table, so preserve everything. */
1699 /* We can't do anything about preservedInPlaceCount. */
1700 trace->preservedInPlaceSize += SegSize(seg);
1701 goto adjustColour;
1702 }
1703
1704 /* see design.mps.poolamc.Nailboard.limitations for improvements */
1705 headerSize = format->headerSize; 1700 headerSize = format->headerSize;
1706 ShieldExpose(arena, seg); 1701 ShieldExpose(arena, seg);
1707 p = AddrAdd(SegBase(seg), headerSize); 1702 p = AddrAdd(SegBase(seg), headerSize);
@@ -1715,7 +1710,11 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
1715 Size length; 1710 Size length;
1716 q = (*format->skip)(p); 1711 q = (*format->skip)(p);
1717 length = AddrOffset(p, q); 1712 length = AddrOffset(p, q);
1718 if (!amcNailGetMark(seg, p)) { 1713 if (amcSegHasNailboard(seg)
1714 ? !amcNailGetMark(seg, p)
1715 /* If there's no mark table, retain all that hasn't been forwarded. In
1716 * this case, preservedInPlace* become somewhat overstated. */
1717 : (*format->isMoved)(p) != NULL) {
1719 (*format->pad)(AddrSub(p, headerSize), length); 1718 (*format->pad)(AddrSub(p, headerSize), length);
1720 bytesReclaimed += length; 1719 bytesReclaimed += length;
1721 } else { 1720 } else {
@@ -1729,7 +1728,6 @@ static void amcReclaimNailed(Pool pool, Trace trace, Seg seg)
1729 AVER(p == limit); 1728 AVER(p == limit);
1730 ShieldCover(arena, seg); 1729 ShieldCover(arena, seg);
1731 1730
1732adjustColour:
1733 SegSetNailed(seg, TraceSetDel(SegNailed(seg), trace)); 1731 SegSetNailed(seg, TraceSetDel(SegNailed(seg), trace));
1734 SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace)); 1732 SegSetWhite(seg, TraceSetDel(SegWhite(seg), trace));
1735 if (SegNailed(seg) == TraceSetEMPTY && amcSegHasNailboard(seg)) { 1733 if (SegNailed(seg) == TraceSetEMPTY && amcSegHasNailboard(seg)) {
diff --git a/mps/code/poolams.c b/mps/code/poolams.c
index 5d38a0b475f..990043ecc0d 100644
--- a/mps/code/poolams.c
+++ b/mps/code/poolams.c
@@ -2,6 +2,8 @@
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.
6 *
5 * 7 *
6 * .design: See design.mps.poolams. 8 * .design: See design.mps.poolams.
7 * 9 *
@@ -13,8 +15,8 @@
13 * (as opposed to being constructed by the caller). 15 * (as opposed to being constructed by the caller).
14 */ 16 */
15 17
16#include "mpscams.h"
17#include "poolams.h" 18#include "poolams.h"
19#include "dbgpool.h"
18#include "mpm.h" 20#include "mpm.h"
19#include <stdarg.h> 21#include <stdarg.h>
20 22
@@ -25,6 +27,21 @@ SRCID(poolams, "$Id$");
25#define AMSSegSig ((Sig)0x519A3559) /* SIGnature AMS SeG */ 27#define AMSSegSig ((Sig)0x519A3559) /* SIGnature AMS SeG */
26 28
27 29
30/* AMSDebugStruct -- structure for a debug subclass */
31
32typedef struct AMSDebugStruct {
33 AMSStruct amsStruct; /* AMS structure */
34 PoolDebugMixinStruct debug; /* debug mixin */
35} AMSDebugStruct;
36
37typedef struct AMSDebugStruct *AMSDebug;
38
39
40#define AMS2AMSDebug(ams) PARENT(AMSDebugStruct, amsStruct, ams)
41#define AMSDebug2AMS(amsd) (&((amsd)->amsStruct))
42
43
44
28/* AMSSegCheck -- check an AMS segment */ 45/* AMSSegCheck -- check an AMS segment */
29 46
30Bool AMSSegCheck(AMSSeg amsseg) 47Bool AMSSegCheck(AMSSeg amsseg)
@@ -34,18 +51,26 @@ Bool AMSSegCheck(AMSSeg amsseg)
34 CHECKL(GCSegCheck(&amsseg->gcSegStruct)); 51 CHECKL(GCSegCheck(&amsseg->gcSegStruct));
35 CHECKU(AMS, amsseg->ams); 52 CHECKU(AMS, amsseg->ams);
36 CHECKL(AMS2Pool(amsseg->ams) == SegPool(seg)); 53 CHECKL(AMS2Pool(amsseg->ams) == SegPool(seg));
37 CHECKL(RingCheck(&amsseg->segRing)); 54 CHECKD_NOSIG(Ring, &amsseg->segRing);
38 55
39 CHECKL(amsseg->grains == AMSGrains(amsseg->ams, SegSize(seg))); 56 CHECKL(amsseg->grains == AMSGrains(amsseg->ams, SegSize(seg)));
40 CHECKL(amsseg->grains > 0); 57 CHECKL(amsseg->grains > 0);
41 CHECKL(amsseg->grains >= amsseg->free + amsseg->newAlloc); 58 CHECKL(amsseg->grains >= amsseg->free + amsseg->newAlloc);
42 59
43 if (SegWhite(seg) != TraceSetEMPTY) 60 CHECKL(BoolCheck(amsseg->allocTableInUse));
61 if (!amsseg->allocTableInUse)
62 CHECKL(amsseg->firstFree <= amsseg->grains);
63 CHECKL(amsseg->allocTable != NULL);
64
65 if (SegWhite(seg) != TraceSetEMPTY) {
44 /* design.mps.poolams.colour.single */ 66 /* design.mps.poolams.colour.single */
45 CHECKL(TraceSetIsSingle(SegWhite(seg))); 67 CHECKL(TraceSetIsSingle(SegWhite(seg)));
68 CHECKL(amsseg->colourTablesInUse);
69 }
46 70
47 CHECKL(BoolCheck(amsseg->marksChanged)); 71 CHECKL(BoolCheck(amsseg->marksChanged));
48 CHECKL(amsseg->allocTable != NULL); 72 CHECKL(BoolCheck(amsseg->ambiguousFixes));
73 CHECKL(BoolCheck(amsseg->colourTablesInUse));
49 CHECKL(amsseg->nongreyTable != NULL); 74 CHECKL(amsseg->nongreyTable != NULL);
50 CHECKL(amsseg->nonwhiteTable != NULL); 75 CHECKL(amsseg->nonwhiteTable != NULL);
51 76
@@ -53,9 +78,69 @@ Bool AMSSegCheck(AMSSeg amsseg)
53} 78}
54 79
55 80
81/* AMSSegFreeWalk -- walk the free space in a segment */
82
83void AMSSegFreeWalk(AMSSeg amsseg, FreeBlockStepMethod f, void *p)
84{
85 Pool pool;
86 Seg seg;
87
88 AVERT(AMSSeg, amsseg);
89 pool = SegPool(AMSSeg2Seg(amsseg));
90 seg = AMSSeg2Seg(amsseg);
91
92 if (amsseg->free == 0)
93 return;
94 if (amsseg->allocTableInUse) {
95 Index base, limit, next;
96
97 next = 0;
98 while (next < amsseg->grains) {
99 Bool found = BTFindLongResRange(&base, &limit, amsseg->allocTable,
100 next, amsseg->grains, 1);
101 if (!found) break;
102 (*f)(AMS_INDEX_ADDR(seg, base), AMS_INDEX_ADDR(seg, limit), pool, p);
103 next = limit + 1;
104 }
105 } else {
106 if ( amsseg->firstFree < amsseg->grains )
107 (*f)(AMS_INDEX_ADDR(seg, amsseg->firstFree), SegLimit(seg), pool, p);
108 }
109}
110
111
112/* AMSSegFreeCheck -- check the free space in a segment */
113
114static void amsFreeBlockCheckStep(Addr base, Addr limit, Pool pool, void *p)
115{
116 UNUSED(p);
117 DebugPoolFreeCheck(pool, base, limit);
118}
119
120void AMSSegFreeCheck(AMSSeg amsseg)
121{
122 Pool pool;
123 PoolDebugMixin debug;
124
125 AVERT(AMSSeg, amsseg);
126
127 if (amsseg->free == 0)
128 return;
129
130 /* If it's not a debug class, don't bother walking. */
131 pool = SegPool(AMSSeg2Seg(amsseg));
132 AVERT(Pool, pool);
133 debug = ((pool)->class->debugMixin)(pool);
134 if (debug == NULL)
135 return;
136
137 AMSSegFreeWalk(amsseg, amsFreeBlockCheckStep, NULL);
138}
139
140
56/* amsCreateTables -- create the tables for an AMS seg */ 141/* amsCreateTables -- create the tables for an AMS seg */
57 142
58static Res amsCreateTables(BT *allocReturn, 143static Res amsCreateTables(AMS ams, BT *allocReturn,
59 BT *nongreyReturn, BT *nonwhiteReturn, 144 BT *nongreyReturn, BT *nonwhiteReturn,
60 Arena arena, Count length) 145 Arena arena, Count length)
61{ 146{
@@ -74,9 +159,13 @@ static Res amsCreateTables(BT *allocReturn,
74 res = BTCreate(&nongreyTable, arena, length); 159 res = BTCreate(&nongreyTable, arena, length);
75 if (res != ResOK) 160 if (res != ResOK)
76 goto failGrey; 161 goto failGrey;
77 res = BTCreate(&nonwhiteTable, arena, length); 162 if (ams->shareAllocTable)
78 if (res != ResOK) 163 nonwhiteTable = allocTable;
79 goto failWhite; 164 else {
165 res = BTCreate(&nonwhiteTable, arena, length);
166 if (res != ResOK)
167 goto failWhite;
168 }
80 169
81 *allocReturn = allocTable; 170 *allocReturn = allocTable;
82 *nongreyReturn = nongreyTable; 171 *nongreyReturn = nongreyTable;
@@ -94,7 +183,7 @@ failAlloc:
94 183
95/* amsDestroyTables -- destroy the tables for an AMS seg */ 184/* amsDestroyTables -- destroy the tables for an AMS seg */
96 185
97static void amsDestroyTables(BT allocTable, 186static void amsDestroyTables(AMS ams, BT allocTable,
98 BT nongreyTable, BT nonwhiteTable, 187 BT nongreyTable, BT nonwhiteTable,
99 Arena arena, Count length) 188 Arena arena, Count length)
100{ 189{
@@ -104,7 +193,8 @@ static void amsDestroyTables(BT allocTable,
104 AVERT(Arena, arena); 193 AVERT(Arena, arena);
105 AVER(length > 0); 194 AVER(length > 0);
106 195
107 BTDestroy(nonwhiteTable, arena, length); 196 if (!ams->shareAllocTable)
197 BTDestroy(nonwhiteTable, arena, length);
108 BTDestroy(nongreyTable, arena, length); 198 BTDestroy(nongreyTable, arena, length);
109 BTDestroy(allocTable, arena, length); 199 BTDestroy(allocTable, arena, length);
110} 200}
@@ -142,7 +232,7 @@ static Res AMSSegInit(Seg seg, Pool pool, Addr base, Size size,
142 amsseg->marksChanged = FALSE; /* design.mps.poolams.marked.unused */ 232 amsseg->marksChanged = FALSE; /* design.mps.poolams.marked.unused */
143 amsseg->ambiguousFixes = FALSE; 233 amsseg->ambiguousFixes = FALSE;
144 234
145 res = amsCreateTables(&amsseg->allocTable, 235 res = amsCreateTables(ams, &amsseg->allocTable,
146 &amsseg->nongreyTable, &amsseg->nonwhiteTable, 236 &amsseg->nongreyTable, &amsseg->nonwhiteTable,
147 arena, amsseg->grains); 237 arena, amsseg->grains);
148 if (res != ResOK) 238 if (res != ResOK)
@@ -189,7 +279,7 @@ static void AMSSegFinish(Seg seg)
189 AVER(SegBuffer(seg) == NULL); 279 AVER(SegBuffer(seg) == NULL);
190 280
191 /* keep the destructions in step with AMSSegInit failure cases */ 281 /* keep the destructions in step with AMSSegInit failure cases */
192 amsDestroyTables(amsseg->allocTable, amsseg->nongreyTable, 282 amsDestroyTables(ams, amsseg->allocTable, amsseg->nongreyTable,
193 amsseg->nonwhiteTable, arena, amsseg->grains); 283 amsseg->nonwhiteTable, arena, amsseg->grains);
194 284
195 RingRemove(&amsseg->segRing); 285 RingRemove(&amsseg->segRing);
@@ -259,7 +349,7 @@ static Res AMSSegMerge(Seg seg, Seg segHi,
259 AVER(!amssegHi->marksChanged); 349 AVER(!amssegHi->marksChanged);
260 350
261 /* .alloc-early */ 351 /* .alloc-early */
262 res = amsCreateTables(&allocTable, &nongreyTable, &nonwhiteTable, 352 res = amsCreateTables(ams, &allocTable, &nongreyTable, &nonwhiteTable,
263 arena, allGrains); 353 arena, allGrains);
264 if (res != ResOK) 354 if (res != ResOK)
265 goto failCreateTables; 355 goto failCreateTables;
@@ -283,9 +373,10 @@ static Res AMSSegMerge(Seg seg, Seg segHi,
283 amsseg->table = (table); \ 373 amsseg->table = (table); \
284 END 374 END
285 375
286 MERGE_TABLES(nonwhiteTable, BTSetRange);
287 MERGE_TABLES(nongreyTable, BTSetRange);
288 MERGE_TABLES(allocTable, BTResRange); 376 MERGE_TABLES(allocTable, BTResRange);
377 MERGE_TABLES(nongreyTable, BTSetRange);
378 if (!ams->shareAllocTable)
379 MERGE_TABLES(nonwhiteTable, BTSetRange);
289 380
290 amsseg->grains = allGrains; 381 amsseg->grains = allGrains;
291 amsseg->free = amsseg->free + amssegHi->free; 382 amsseg->free = amsseg->free + amssegHi->free;
@@ -300,7 +391,7 @@ static Res AMSSegMerge(Seg seg, Seg segHi,
300 return ResOK; 391 return ResOK;
301 392
302failSuper: 393failSuper:
303 amsDestroyTables(allocTable, nongreyTable, nonwhiteTable, 394 amsDestroyTables(ams, allocTable, nongreyTable, nonwhiteTable,
304 arena, allGrains); 395 arena, allGrains);
305failCreateTables: 396failCreateTables:
306 AVERT(AMSSeg, amsseg); 397 AVERT(AMSSeg, amsseg);
@@ -346,11 +437,11 @@ static Res AMSSegSplit(Seg seg, Seg segHi,
346 } 437 }
347 438
348 /* .alloc-early */ 439 /* .alloc-early */
349 res = amsCreateTables(&allocTableLo, &nongreyTableLo, &nonwhiteTableLo, 440 res = amsCreateTables(ams, &allocTableLo, &nongreyTableLo, &nonwhiteTableLo,
350 arena, loGrains); 441 arena, loGrains);
351 if (res != ResOK) 442 if (res != ResOK)
352 goto failCreateTablesLo; 443 goto failCreateTablesLo;
353 res = amsCreateTables(&allocTableHi, &nongreyTableHi, &nonwhiteTableHi, 444 res = amsCreateTables(ams, &allocTableHi, &nongreyTableHi, &nonwhiteTableHi,
354 arena, hiGrains); 445 arena, hiGrains);
355 if (res != ResOK) 446 if (res != ResOK)
356 goto failCreateTablesHi; 447 goto failCreateTablesHi;
@@ -403,10 +494,10 @@ static Res AMSSegSplit(Seg seg, Seg segHi,
403 return ResOK; 494 return ResOK;
404 495
405failSuper: 496failSuper:
406 amsDestroyTables(allocTableHi, nongreyTableHi, nonwhiteTableHi, 497 amsDestroyTables(ams, allocTableHi, nongreyTableHi, nonwhiteTableHi,
407 arena, hiGrains); 498 arena, hiGrains);
408failCreateTablesHi: 499failCreateTablesHi:
409 amsDestroyTables(allocTableLo, nongreyTableLo, nonwhiteTableLo, 500 amsDestroyTables(ams, allocTableLo, nongreyTableLo, nonwhiteTableLo,
410 arena, loGrains); 501 arena, loGrains);
411failCreateTablesLo: 502failCreateTablesLo:
412 AVERT(AMSSeg, amsseg); 503 AVERT(AMSSeg, amsseg);
@@ -481,11 +572,11 @@ static Res AMSSegDescribe(Seg seg, mps_lib_FILE *stream)
481 572
482 if (AMS_ALLOCED(seg, i)) { 573 if (AMS_ALLOCED(seg, i)) {
483 if (amsseg->colourTablesInUse) { 574 if (amsseg->colourTablesInUse) {
484 if (AMSIsInvalidColor(seg, i)) 575 if (AMS_IS_INVALID_COLOUR(seg, i))
485 c = '!'; 576 c = '!';
486 else if (AMSIsWhite(seg, i)) 577 else if (AMS_IS_WHITE(seg, i))
487 c = '-'; 578 c = '-';
488 else if (AMSIsGrey(seg, i)) 579 else if (AMS_IS_GREY(seg, i))
489 c = '+'; 580 c = '+';
490 else /* must be black */ 581 else /* must be black */
491 c = '*'; 582 c = '*';
@@ -599,14 +690,15 @@ static Res AMSSegCreate(Seg *segReturn, Pool pool, Size size,
599 if (res != ResOK) 690 if (res != ResOK)
600 goto failSeg; 691 goto failSeg;
601 } 692 }
602 PoolGenUpdateZones(&ams->pgen, seg);
603 693
694 PoolGenUpdateZones(&ams->pgen, seg);
604 /* see design.mps.seg.field.rankset */ 695 /* see design.mps.seg.field.rankset */
605 if (rankSet != RankSetEMPTY) { 696 if (rankSet != RankSetEMPTY) {
606 SegSetRankAndSummary(seg, rankSet, RefSetUNIV); 697 SegSetRankAndSummary(seg, rankSet, RefSetUNIV);
607 } else { 698 } else {
608 SegSetRankAndSummary(seg, rankSet, RefSetEMPTY); 699 SegSetRankAndSummary(seg, rankSet, RefSetEMPTY);
609 } 700 }
701 DebugPoolFreeSplat(pool, SegBase(seg), SegLimit(seg));
610 702
611 AVERT(AMSSeg, Seg2AMSSeg(seg)); 703 AVERT(AMSSeg, Seg2AMSSeg(seg));
612 704
@@ -629,14 +721,12 @@ static void AMSSegsDestroy(AMS ams)
629 RING_FOR(node, ring, next) { 721 RING_FOR(node, ring, next) {
630 Seg seg = SegOfPoolRing(node); 722 Seg seg = SegOfPoolRing(node);
631 AVER(Seg2AMSSeg(seg)->ams == ams); 723 AVER(Seg2AMSSeg(seg)->ams == ams);
724 AMSSegFreeCheck(Seg2AMSSeg(seg));
632 SegFree(seg); 725 SegFree(seg);
633 } 726 }
634} 727}
635 728
636 729
637static Res AMSIterate(Seg seg, AMSObjectFunction f, void *closure);
638
639
640/* AMSInit -- the pool class initialization method 730/* AMSInit -- the pool class initialization method
641 * 731 *
642 * Takes one additional argument: the format of the objects 732 * Takes one additional argument: the format of the objects
@@ -647,12 +737,16 @@ static Res AMSInit(Pool pool, va_list args)
647 Res res; 737 Res res;
648 Format format; 738 Format format;
649 Chain chain; 739 Chain chain;
740 Bool supportAmbiguous;
650 741
651 AVERT(Pool, pool); 742 AVERT(Pool, pool);
652 743
653 format = va_arg(args, Format); 744 format = va_arg(args, Format);
654 chain = va_arg(args, Chain); 745 chain = va_arg(args, Chain);
655 res = AMSInitInternal(Pool2AMS(pool), format, chain); 746 supportAmbiguous = va_arg(args, Bool);
747 /* .ambiguous.noshare: If the pool is required to support ambiguous */
748 /* references, the alloc and white tables cannot be shared. */
749 res = AMSInitInternal(Pool2AMS(pool), format, chain, !supportAmbiguous);
656 if (res == ResOK) { 750 if (res == ResOK) {
657 EVENT_PPP(PoolInitAMS, pool, PoolArena(pool), format); 751 EVENT_PPP(PoolInitAMS, pool, PoolArena(pool), format);
658 } 752 }
@@ -662,7 +756,7 @@ static Res AMSInit(Pool pool, va_list args)
662 756
663/* AMSInitInternal -- initialize an AMS pool, given the format and the chain */ 757/* AMSInitInternal -- initialize an AMS pool, given the format and the chain */
664 758
665Res AMSInitInternal(AMS ams, Format format, Chain chain) 759Res AMSInitInternal(AMS ams, Format format, Chain chain, Bool shareAllocTable)
666{ 760{
667 Pool pool; 761 Pool pool;
668 Res res; 762 Res res;
@@ -684,10 +778,11 @@ Res AMSInitInternal(AMS ams, Format format, Chain chain)
684 if (res != ResOK) 778 if (res != ResOK)
685 return res; 779 return res;
686 780
781 ams->shareAllocTable = shareAllocTable;
782
687 RingInit(&ams->segRing); 783 RingInit(&ams->segRing);
688 784
689 /* The next five might be overridden by a subclass. */ 785 /* The next four might be overridden by a subclass. */
690 ams->iterate = AMSIterate; /* should be done using a format variant */
691 ams->segSize = AMSSegSizePolicy; 786 ams->segSize = AMSSegSizePolicy;
692 ams->allocRing = AMSPoolRing; 787 ams->allocRing = AMSPoolRing;
693 ams->segsDestroy = AMSSegsDestroy; 788 ams->segsDestroy = AMSSegsDestroy;
@@ -725,8 +820,7 @@ void AMSFinish(Pool pool)
725/* amsSegAlloc -- try to allocate an area in the given segment 820/* amsSegAlloc -- try to allocate an area in the given segment
726 * 821 *
727 * Tries to find an area of at least the given size. If successful, 822 * Tries to find an area of at least the given size. If successful,
728 * makes that area black, if necessary, and returns its base and limit 823 * returns its base and limit grain indices.
729 * grain indices.
730 */ 824 */
731static Bool amsSegAlloc(Index *baseReturn, Index *limitReturn, 825static Bool amsSegAlloc(Index *baseReturn, Index *limitReturn,
732 Seg seg, Size size) 826 Seg seg, Size size)
@@ -766,6 +860,9 @@ static Bool amsSegAlloc(Index *baseReturn, Index *limitReturn,
766 amsseg->firstFree = limit; 860 amsseg->firstFree = limit;
767 } 861 }
768 862
863 /* We don't place buffers on white segments, so no need to adjust colour. */
864 AVER(!amsseg->colourTablesInUse);
865
769 amsseg->free -= limit - base; 866 amsseg->free -= limit - base;
770 amsseg->newAlloc += limit - base; 867 amsseg->newAlloc += limit - base;
771 *baseReturn = base; 868 *baseReturn = base;
@@ -779,15 +876,16 @@ static Bool amsSegAlloc(Index *baseReturn, Index *limitReturn,
779 * Iterates over the segments looking for space. See 876 * Iterates over the segments looking for space. See
780 * design.mps.poolams.fill. 877 * design.mps.poolams.fill.
781 */ 878 */
782Res AMSBufferFill(Addr *baseReturn, Addr *limitReturn, 879static Res AMSBufferFill(Addr *baseReturn, Addr *limitReturn,
783 Pool pool, Buffer buffer, Size size, 880 Pool pool, Buffer buffer, Size size,
784 Bool withReservoirPermit) 881 Bool withReservoirPermit)
785{ 882{
786 Res res; 883 Res res;
787 AMS ams; 884 AMS ams;
788 Seg seg; 885 Seg seg;
789 Ring node, ring, nextNode; /* for iterating over the segments */ 886 Ring node, ring, nextNode; /* for iterating over the segments */
790 Index base, limit; 887 Index base, limit;
888 Addr baseAddr, limitAddr;
791 RankSet rankSet; 889 RankSet rankSet;
792 Bool b; /* the return value of amsSegAlloc */ 890 Bool b; /* the return value of amsSegAlloc */
793 SegPrefStruct segPrefStruct; 891 SegPrefStruct segPrefStruct;
@@ -816,7 +914,9 @@ Res AMSBufferFill(Addr *baseReturn, Addr *limitReturn,
816 if (amsseg->free >= AMSGrains(ams, size)) { 914 if (amsseg->free >= AMSGrains(ams, size)) {
817 seg = AMSSeg2Seg(amsseg); 915 seg = AMSSeg2Seg(amsseg);
818 916
819 if (SegRankSet(seg) == rankSet && SegBuffer(seg) == NULL) { 917 if (SegRankSet(seg) == rankSet && SegBuffer(seg) == NULL
918 /* Can't use a white or grey segment, see d.m.p.fill.colour. */
919 && SegWhite(seg) == TraceSetEMPTY && SegGrey(seg) == TraceSetEMPTY) {
820 b = amsSegAlloc(&base, &limit, seg, size); 920 b = amsSegAlloc(&base, &limit, seg, size);
821 if (b) 921 if (b)
822 goto found; 922 goto found;
@@ -824,7 +924,7 @@ Res AMSBufferFill(Addr *baseReturn, Addr *limitReturn,
824 } 924 }
825 } 925 }
826 926
827 /* no segment has enough room; make a new segment */ 927 /* No suitable segment found; make a new one. */
828 segPrefStruct = *SegPrefDefault(); 928 segPrefStruct = *SegPrefDefault();
829 SegPrefExpress(&segPrefStruct, SegPrefCollected, NULL); 929 SegPrefExpress(&segPrefStruct, SegPrefCollected, NULL);
830 res = AMSSegCreate(&seg, pool, size, &segPrefStruct, rankSet, 930 res = AMSSegCreate(&seg, pool, size, &segPrefStruct, rankSet,
@@ -835,13 +935,13 @@ Res AMSBufferFill(Addr *baseReturn, Addr *limitReturn,
835 935
836found: 936found:
837 AVER(b); 937 AVER(b);
838 allocatedSize = AddrOffset(AMS_INDEX_ADDR(seg, base), 938 baseAddr = AMS_INDEX_ADDR(seg, base); limitAddr = AMS_INDEX_ADDR(seg, limit);
839 AMS_INDEX_ADDR(seg, limit)); 939 DebugPoolFreeCheck(pool, baseAddr, limitAddr);
940 allocatedSize = AddrOffset(baseAddr, limitAddr);
840 ams->pgen.totalSize += allocatedSize; 941 ams->pgen.totalSize += allocatedSize;
841 ams->pgen.newSize += allocatedSize; 942 ams->pgen.newSize += allocatedSize;
842 943
843 *baseReturn = AMS_INDEX_ADDR(seg, base); 944 *baseReturn = baseAddr; *limitReturn = limitAddr;
844 *limitReturn = AMS_INDEX_ADDR(seg, limit);
845 return ResOK; 945 return ResOK;
846} 946}
847 947
@@ -851,7 +951,7 @@ found:
851 * Frees the unused part of the buffer. The colour of the area doesn't 951 * Frees the unused part of the buffer. The colour of the area doesn't
852 * need to be changed. See design.mps.poolams.empty. 952 * need to be changed. See design.mps.poolams.empty.
853 */ 953 */
854void AMSBufferEmpty(Pool pool, Buffer buffer, Addr init, Addr limit) 954static void AMSBufferEmpty(Pool pool, Buffer buffer, Addr init, Addr limit)
855{ 955{
856 AMS ams; 956 AMS ams;
857 Index initIndex, limitIndex; 957 Index initIndex, limitIndex;
@@ -876,6 +976,9 @@ void AMSBufferEmpty(Pool pool, Buffer buffer, Addr init, Addr limit)
876 if (init == limit) 976 if (init == limit)
877 return; 977 return;
878 978
979 /* Tripped allocations might have scribbled on it, need to splat again. */
980 DebugPoolFreeSplat(pool, init, limit);
981
879 initIndex = AMS_ADDR_INDEX(seg, init); 982 initIndex = AMS_ADDR_INDEX(seg, init);
880 limitIndex = AMS_ADDR_INDEX(seg, limit); 983 limitIndex = AMS_ADDR_INDEX(seg, limit);
881 984
@@ -896,6 +999,10 @@ void AMSBufferEmpty(Pool pool, Buffer buffer, Addr init, Addr limit)
896 BTResRange(amsseg->allocTable, initIndex, limitIndex); 999 BTResRange(amsseg->allocTable, initIndex, limitIndex);
897 } 1000 }
898 } 1001 }
1002
1003 if (amsseg->colourTablesInUse)
1004 AMS_RANGE_WHITEN(seg, initIndex, limitIndex);
1005
899 amsseg->free += limitIndex - initIndex; 1006 amsseg->free += limitIndex - initIndex;
900 /* The unused portion of the buffer must be new, since it's not condemned. */ 1007 /* The unused portion of the buffer must be new, since it's not condemned. */
901 AVER(amsseg->newAlloc >= limitIndex - initIndex); 1008 AVER(amsseg->newAlloc >= limitIndex - initIndex);
@@ -907,8 +1014,6 @@ void AMSBufferEmpty(Pool pool, Buffer buffer, Addr init, Addr limit)
907 1014
908 1015
909/* amsRangeCondemn -- Condemn a part of an AMS segment 1016/* amsRangeCondemn -- Condemn a part of an AMS segment
910 *
911 * I.e., alloc -> white, free -> black.
912 * Allow calling it with base = limit, to simplify the callers. 1017 * Allow calling it with base = limit, to simplify the callers.
913 */ 1018 */
914static void amsRangeCondemn(Seg seg, Index base, Index limit) 1019static void amsRangeCondemn(Seg seg, Index base, Index limit)
@@ -919,25 +1024,14 @@ static void amsRangeCondemn(Seg seg, Index base, Index limit)
919 AVER(base < limit); 1024 AVER(base < limit);
920 AVER(limit <= amsseg->grains); 1025 AVER(limit <= amsseg->grains);
921 1026
922 if (amsseg->allocTableInUse) { 1027 AMS_RANGE_WHITEN(seg, base, limit);
923 BTSetRange(amsseg->nongreyTable, base, limit);
924 BTCopyInvertRange(amsseg->allocTable, amsseg->nonwhiteTable,
925 base, limit);
926 } else {
927 if (base < amsseg->firstFree) {
928 AMSRangeWhiten(seg, base, amsseg->firstFree);
929 }
930 if (amsseg->firstFree < limit) {
931 AMSRangeBlacken(seg, amsseg->firstFree, limit);
932 }
933 }
934 } 1028 }
935} 1029}
936 1030
937 1031
938/* AMSWhiten -- the pool class segment condemning method */ 1032/* AMSCondemn -- the pool class segment condemning method */
939 1033
940Res AMSWhiten(Pool pool, Trace trace, Seg seg) 1034static Res AMSCondemn(Pool pool, Trace trace, Seg seg)
941{ 1035{
942 AMS ams; 1036 AMS ams;
943 AMSSeg amsseg; 1037 AMSSeg amsseg;
@@ -959,6 +1053,28 @@ Res AMSWhiten(Pool pool, Trace trace, Seg seg)
959 AVER(!amsseg->colourTablesInUse); 1053 AVER(!amsseg->colourTablesInUse);
960 1054
961 amsseg->colourTablesInUse = TRUE; 1055 amsseg->colourTablesInUse = TRUE;
1056
1057 /* Init allocTable, if necessary. */
1058 if (!amsseg->allocTableInUse) {
1059 if (0 < amsseg->firstFree)
1060 BTSetRange(amsseg->allocTable, 0, amsseg->firstFree);
1061 if (amsseg->firstFree < amsseg->grains)
1062 BTResRange(amsseg->allocTable, amsseg->firstFree, amsseg->grains);
1063 }
1064
1065 /* Start using allocTable as the white table, if so configured. */
1066 if (ams->shareAllocTable) {
1067 if (amsseg->allocTableInUse) {
1068 /* During the collection, it can't use allocTable for AMS_ALLOCED, so */
1069 /* make it use firstFree. */
1070 amsseg->allocTableInUse = FALSE;
1071 /* Could find a better value for firstFree, but probably not worth it. */
1072 amsseg->firstFree = amsseg->grains;
1073 }
1074 } else { /* Otherwise, use it as alloc table. */
1075 amsseg->allocTableInUse = TRUE;
1076 }
1077
962 buffer = SegBuffer(seg); 1078 buffer = SegBuffer(seg);
963 if (buffer != NULL) { /* design.mps.poolams.condemn.buffer */ 1079 if (buffer != NULL) { /* design.mps.poolams.condemn.buffer */
964 Index scanLimitIndex, limitIndex; 1080 Index scanLimitIndex, limitIndex;
@@ -967,7 +1083,7 @@ Res AMSWhiten(Pool pool, Trace trace, Seg seg)
967 1083
968 amsRangeCondemn(seg, 0, scanLimitIndex); 1084 amsRangeCondemn(seg, 0, scanLimitIndex);
969 if (scanLimitIndex < limitIndex) 1085 if (scanLimitIndex < limitIndex)
970 AMSRangeBlacken(seg, scanLimitIndex, limitIndex); 1086 AMS_RANGE_BLACKEN(seg, scanLimitIndex, limitIndex);
971 amsRangeCondemn(seg, limitIndex, amsseg->grains); 1087 amsRangeCondemn(seg, limitIndex, amsseg->grains);
972 /* We didn't condemn the buffer, subtract it from the count. */ 1088 /* We didn't condemn the buffer, subtract it from the count. */
973 uncondemned = limitIndex - scanLimitIndex; 1089 uncondemned = limitIndex - scanLimitIndex;
@@ -989,14 +1105,26 @@ Res AMSWhiten(Pool pool, Trace trace, Seg seg)
989} 1105}
990 1106
991 1107
1108/* AMSObjectFunction is the type of the method that an */
1109/* amsIterate applies to each object in a segment. */
1110typedef Res (*AMSObjectFunction)(
1111 /* the segment */ Seg seg,
1112 /* the object grain index */ Index i,
1113 /* the address of the object */Addr p,
1114 /* " " after the object */Addr next,
1115 /* the iteration closure */ void *closure);
1116
1117#define AMSObjectFunctionCheck(f) \
1118 ((f) != NULL) /* that's the best we can do */
1119
992 1120
993/* AMSIterate -- applies a function to each object in a segment 1121/* amsIterate -- applies a function to each object in a segment
994 * 1122 *
995 * AMSIterate(seg, f, closure) applies f to all the 1123 * amsIterate(seg, f, closure) applies f to all the objects in the
996 * objects in the segment. It skips the buffer, if any (from 1124 * segment. It skips the buffer, if any (from BufferScanLimit to
997 * BufferScanLimit to BufferLimit). 1125 * BufferLimit). */
998 */ 1126
999static Res AMSIterate(Seg seg, AMSObjectFunction f, void *closure) 1127static Res amsIterate(Seg seg, AMSObjectFunction f, void *closure)
1000{ 1128{
1001 Res res; 1129 Res res;
1002 AMS ams; 1130 AMS ams;
@@ -1019,13 +1147,17 @@ static Res AMSIterate(Seg seg, AMSObjectFunction f, void *closure)
1019 AVERT(Format, format); 1147 AVERT(Format, format);
1020 alignment = PoolAlignment(AMS2Pool(ams)); 1148 alignment = PoolAlignment(AMS2Pool(ams));
1021 1149
1150 /* If we're using the alloc table as a white table, we can't use it to */
1151 /* determine where there are objects. */
1152 AVER(!(ams->shareAllocTable && amsseg->colourTablesInUse));
1153
1022 p = SegBase(seg); 1154 p = SegBase(seg);
1023 limit = SegLimit(seg); 1155 limit = SegLimit(seg);
1024 buffer = SegBuffer(seg); 1156 buffer = SegBuffer(seg);
1025 1157
1026 while (p < limit) { /* loop over the objects in the segment */ 1158 while (p < limit) { /* loop over the objects in the segment */
1027 if (buffer != NULL 1159 if (buffer != NULL
1028 && p == BufferScanLimit(buffer) && p != BufferLimit(buffer)) { 1160 && p == BufferScanLimit(buffer) && p != BufferLimit(buffer)) {
1029 /* skip buffer */ 1161 /* skip buffer */
1030 next = BufferLimit(buffer); 1162 next = BufferLimit(buffer);
1031 AVER(AddrIsAligned(next, alignment)); 1163 AVER(AddrIsAligned(next, alignment));
@@ -1036,10 +1168,26 @@ static Res AMSIterate(Seg seg, AMSObjectFunction f, void *closure)
1036 1168
1037 i = AMS_ADDR_INDEX(seg, p); 1169 i = AMS_ADDR_INDEX(seg, p);
1038 if (!AMS_ALLOCED(seg, i)) { /* no object here */ 1170 if (!AMS_ALLOCED(seg, i)) { /* no object here */
1039 next = AddrAdd(p, alignment); /* @@@@ this could be improved */ 1171 if (amsseg->allocTableInUse) {
1172 Index dummy, nextIndex;
1173 Bool more;
1174
1175 /* Find out how large the free block is. */
1176 more = BTFindLongResRange(&dummy, &nextIndex, amsseg->allocTable,
1177 i, amsseg->grains, 1);
1178 AVER(more && dummy == i);
1179 next = AMS_INDEX_ADDR(seg, nextIndex);
1180 } else {
1181 /* If there's no allocTable, this is the free block at the end. */
1182 next = limit;
1183 }
1040 } else { /* there is an object here */ 1184 } else { /* there is an object here */
1041 next = (*format->skip)(AddrAdd(p, format->headerSize)); 1185 if (format->skip != NULL) {
1042 next = AddrSub(next, format->headerSize); 1186 next = (*format->skip)(AddrAdd(p, format->headerSize));
1187 next = AddrSub(next, format->headerSize);
1188 } else {
1189 next = AddrAdd(p, alignment);
1190 }
1043 AVER(AddrIsAligned(next, alignment)); 1191 AVER(AddrIsAligned(next, alignment));
1044 res = (*f)(seg, i, p, next, closure); 1192 res = (*f)(seg, i, p, next, closure);
1045 if (res != ResOK) 1193 if (res != ResOK)
@@ -1056,8 +1204,7 @@ static Res AMSIterate(Seg seg, AMSObjectFunction f, void *closure)
1056 1204
1057/* amsScanObject -- scan a single object 1205/* amsScanObject -- scan a single object
1058 * 1206 *
1059 * This is the object function passed to AMSIterate by AMSScan. 1207 * This is the object function passed to amsIterate by AMSScan. */
1060 */
1061 1208
1062struct amsScanClosureStruct { 1209struct amsScanClosureStruct {
1063 ScanState ss; 1210 ScanState ss;
@@ -1074,12 +1221,12 @@ static Res amsScanObject(Seg seg, Index i, Addr p, Addr next, void *clos)
1074 Res res; 1221 Res res;
1075 1222
1076 amsseg = Seg2AMSSeg(seg); 1223 amsseg = Seg2AMSSeg(seg);
1077 /* seg & amsseg have already been checked, in AMSIterate. */ 1224 /* seg & amsseg have already been checked, in amsIterate. */
1078 AVER(i < amsseg->grains); 1225 AVER(i < amsseg->grains);
1079 AVER(p != 0); 1226 AVER(p != 0);
1080 AVER(p < next); 1227 AVER(p < next);
1081 AVER(clos != NULL); 1228 AVER(clos != NULL);
1082 closure = clos; 1229 closure = (amsScanClosure)clos;
1083 AVERT(ScanState, closure->ss); 1230 AVERT(ScanState, closure->ss);
1084 AVER(BoolCheck(closure->scanAllObjects)); 1231 AVER(BoolCheck(closure->scanAllObjects));
1085 1232
@@ -1087,7 +1234,7 @@ static Res amsScanObject(Seg seg, Index i, Addr p, Addr next, void *clos)
1087 AVERT(Format, format); 1234 AVERT(Format, format);
1088 1235
1089 /* @@@@ This isn't quite right for multiple traces. */ 1236 /* @@@@ This isn't quite right for multiple traces. */
1090 if (closure->scanAllObjects || AMSIsGrey(seg, i)) { 1237 if (closure->scanAllObjects || AMS_IS_GREY(seg, i)) {
1091 res = (*format->scan)(closure->ss, 1238 res = (*format->scan)(closure->ss,
1092 AddrAdd(p, format->headerSize), 1239 AddrAdd(p, format->headerSize),
1093 AddrAdd(next, format->headerSize)); 1240 AddrAdd(next, format->headerSize));
@@ -1096,10 +1243,10 @@ static Res amsScanObject(Seg seg, Index i, Addr p, Addr next, void *clos)
1096 closure->ss->scannedSize += AddrOffset(p, next); 1243 closure->ss->scannedSize += AddrOffset(p, next);
1097 if (!closure->scanAllObjects) { 1244 if (!closure->scanAllObjects) {
1098 Index j = AMS_ADDR_INDEX(seg, next); 1245 Index j = AMS_ADDR_INDEX(seg, next);
1099 AVER(!AMSIsInvalidColor(seg, i)); 1246 AVER(!AMS_IS_INVALID_COLOUR(seg, i));
1100 AMSGreyBlacken(seg, i); 1247 AMS_GREY_BLACKEN(seg, i);
1101 if (i+1 < j) 1248 if (i+1 < j)
1102 AMSRangeWhiteBlacken(seg, i+1, j); 1249 AMS_RANGE_WHITE_BLACKEN(seg, i+1, j);
1103 } 1250 }
1104 } 1251 }
1105 1252
@@ -1141,7 +1288,7 @@ Res AMSScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg)
1141 /* @@@@ This isn't quite right for multiple traces. */ 1288 /* @@@@ This isn't quite right for multiple traces. */
1142 if (closureStruct.scanAllObjects) { 1289 if (closureStruct.scanAllObjects) {
1143 /* The whole seg (except the buffer) is grey for some trace. */ 1290 /* The whole seg (except the buffer) is grey for some trace. */
1144 res = (ams->iterate)(seg, amsScanObject, &closureStruct); 1291 res = amsIterate(seg, amsScanObject, &closureStruct);
1145 if (res != ResOK) { 1292 if (res != ResOK) {
1146 *totalReturn = FALSE; 1293 *totalReturn = FALSE;
1147 return res; 1294 return res;
@@ -1157,7 +1304,7 @@ Res AMSScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg)
1157 amsseg->marksChanged = FALSE; /* design.mps.poolams.marked.scan */ 1304 amsseg->marksChanged = FALSE; /* design.mps.poolams.marked.scan */
1158 /* design.mps.poolams.ambiguous.middle */ 1305 /* design.mps.poolams.ambiguous.middle */
1159 if (amsseg->ambiguousFixes) { 1306 if (amsseg->ambiguousFixes) {
1160 res = (ams->iterate)(seg, amsScanObject, &closureStruct); 1307 res = amsIterate(seg, amsScanObject, &closureStruct);
1161 if (res != ResOK) { 1308 if (res != ResOK) {
1162 /* design.mps.poolams.marked.scan.fail */ 1309 /* design.mps.poolams.marked.scan.fail */
1163 amsseg->marksChanged = TRUE; 1310 amsseg->marksChanged = TRUE;
@@ -1170,13 +1317,17 @@ Res AMSScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg)
1170 1317
1171 while(j < amsseg->grains 1318 while(j < amsseg->grains
1172 && AMSFindGrey(&i, &j, seg, j, amsseg->grains)) { 1319 && AMSFindGrey(&i, &j, seg, j, amsseg->grains)) {
1173 Addr clientP, clientNext; 1320 Addr clientP, clientNext;
1174 AVER(!AMSIsInvalidColor(seg, i)); 1321 AVER(!AMS_IS_INVALID_COLOUR(seg, i));
1175 p = AMS_INDEX_ADDR(seg, i); 1322 p = AMS_INDEX_ADDR(seg, i);
1176 clientP = AddrAdd(p, format->headerSize); 1323 clientP = AddrAdd(p, format->headerSize);
1177 clientNext = (*format->skip)(clientP); 1324 if (format->skip != NULL) {
1178 next = AddrSub(clientNext, format->headerSize); 1325 clientNext = (*format->skip)(clientP);
1179 AVER(AddrIsAligned(next, alignment)); 1326 next = AddrSub(clientNext, format->headerSize);
1327 } else {
1328 clientNext = AddrAdd(clientP, alignment);
1329 next = AddrAdd(p, alignment);
1330 }
1180 j = AMS_ADDR_INDEX(seg, next); 1331 j = AMS_ADDR_INDEX(seg, next);
1181 res = (*format->scan)(ss, clientP, clientNext); 1332 res = (*format->scan)(ss, clientP, clientNext);
1182 if (res != ResOK) { 1333 if (res != ResOK) {
@@ -1185,10 +1336,13 @@ Res AMSScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg)
1185 *totalReturn = FALSE; 1336 *totalReturn = FALSE;
1186 return res; 1337 return res;
1187 } 1338 }
1339 /* Check that there haven't been any ambiguous fixes during the */
1340 /* scan, because AMSFindGrey won't work otherwise. */
1341 AVER_CRITICAL(!amsseg->ambiguousFixes);
1188 ss->scannedSize += AddrOffset(p, next); 1342 ss->scannedSize += AddrOffset(p, next);
1189 AMSGreyBlacken(seg, i); 1343 AMS_GREY_BLACKEN(seg, i);
1190 if (i+1 < j) 1344 if (i+1 < j)
1191 AMSRangeWhiteBlacken(seg, i+1, j); 1345 AMS_RANGE_WHITE_BLACKEN(seg, i+1, j);
1192 } 1346 }
1193 } 1347 }
1194 } while(amsseg->marksChanged); 1348 } while(amsseg->marksChanged);
@@ -1201,7 +1355,7 @@ Res AMSScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg)
1201 1355
1202/* AMSFix -- the pool class fixing method */ 1356/* AMSFix -- the pool class fixing method */
1203 1357
1204Res AMSFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) 1358static Res AMSFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
1205{ 1359{
1206 AMSSeg amsseg; 1360 AMSSeg amsseg;
1207 Index i; /* the index of the fixed grain */ 1361 Index i; /* the index of the fixed grain */
@@ -1238,12 +1392,16 @@ Res AMSFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
1238 } 1392 }
1239 1393
1240 i = AMS_ADDR_INDEX(seg, base); 1394 i = AMS_ADDR_INDEX(seg, base);
1241 AVER_CRITICAL(!AMSIsInvalidColor(seg, i)); 1395 AVER_CRITICAL(!AMS_IS_INVALID_COLOUR(seg, i));
1242 1396
1243 ss->wasMarked = TRUE; 1397 ss->wasMarked = TRUE;
1244 1398
1245 switch (ss->rank) { 1399 switch (ss->rank) {
1246 case RankAMBIG: 1400 case RankAMBIG:
1401 if (Pool2AMS(pool)->shareAllocTable)
1402 /* In this state, the pool doesn't support ambiguous references (see */
1403 /* .ambiguous.noshare), so this is not a reference. */
1404 break;
1247 /* not a real pointer if not aligned or not allocated */ 1405 /* not a real pointer if not aligned or not allocated */
1248 if (!AddrIsAligned(base, PoolAlignment(pool)) 1406 if (!AddrIsAligned(base, PoolAlignment(pool))
1249 || !AMS_ALLOCED(seg, i)) { 1407 || !AMS_ALLOCED(seg, i)) {
@@ -1256,7 +1414,7 @@ Res AMSFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
1256 case RankWEAK: 1414 case RankWEAK:
1257 AVER_CRITICAL(AddrIsAligned(base, PoolAlignment(pool))); 1415 AVER_CRITICAL(AddrIsAligned(base, PoolAlignment(pool)));
1258 AVER_CRITICAL(AMS_ALLOCED(seg, i)); 1416 AVER_CRITICAL(AMS_ALLOCED(seg, i));
1259 if (AMSIsWhite(seg, i)) { 1417 if (AMS_IS_WHITE(seg, i)) {
1260 ss->wasMarked = FALSE; 1418 ss->wasMarked = FALSE;
1261 if (ss->rank == RankWEAK) { /* then splat the reference */ 1419 if (ss->rank == RankWEAK) { /* then splat the reference */
1262 *refIO = (Ref)0; 1420 *refIO = (Ref)0;
@@ -1272,9 +1430,9 @@ Res AMSFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
1272 next = AddrSub(clientNext, format->headerSize); 1430 next = AddrSub(clientNext, format->headerSize);
1273 /* Part of the object might be grey, because of ambiguous */ 1431 /* Part of the object might be grey, because of ambiguous */
1274 /* fixes, but that's OK, because scan will ignore that. */ 1432 /* fixes, but that's OK, because scan will ignore that. */
1275 AMSRangeWhiteBlacken(seg, i, AMS_ADDR_INDEX(seg, next)); 1433 AMS_RANGE_WHITE_BLACKEN(seg, i, AMS_ADDR_INDEX(seg, next));
1276 } else { /* turn it grey */ 1434 } else { /* turn it grey */
1277 AMSWhiteGreyen(seg, i); 1435 AMS_WHITE_GREYEN(seg, i);
1278 SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces)); 1436 SegSetGrey(seg, TraceSetUnion(SegGrey(seg), ss->traces));
1279 /* mark it for scanning - design.mps.poolams.marked.fix */ 1437 /* mark it for scanning - design.mps.poolams.marked.fix */
1280 amsseg->marksChanged = TRUE; 1438 amsseg->marksChanged = TRUE;
@@ -1294,7 +1452,7 @@ Res AMSFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
1294 * 1452 *
1295 * Turn all grey objects black. 1453 * Turn all grey objects black.
1296 */ 1454 */
1297void AMSBlacken(Pool pool, TraceSet traceSet, Seg seg) 1455static void AMSBlacken(Pool pool, TraceSet traceSet, Seg seg)
1298{ 1456{
1299 AMS ams; 1457 AMS ams;
1300 1458
@@ -1304,7 +1462,7 @@ void AMSBlacken(Pool pool, TraceSet traceSet, Seg seg)
1304 AVERT(TraceSet, traceSet); 1462 AVERT(TraceSet, traceSet);
1305 AVERT(Seg, seg); 1463 AVERT(Seg, seg);
1306 1464
1307 /* If it's white for any trace, remove the greyness from tables. */ 1465 /* If it's white for any of these traces, remove the greyness from tables. */
1308 if (TraceSetInter(traceSet, SegWhite(seg)) != TraceSetEMPTY) { 1466 if (TraceSetInter(traceSet, SegWhite(seg)) != TraceSetEMPTY) {
1309 AMSSeg amsseg = Seg2AMSSeg(seg); 1467 AMSSeg amsseg = Seg2AMSSeg(seg);
1310 AVERT(AMSSeg, amsseg); 1468 AVERT(AMSSeg, amsseg);
@@ -1318,61 +1476,64 @@ void AMSBlacken(Pool pool, TraceSet traceSet, Seg seg)
1318 1476
1319/* AMSReclaim -- the pool class reclamation method */ 1477/* AMSReclaim -- the pool class reclamation method */
1320 1478
1321void AMSReclaim(Pool pool, Trace trace, Seg seg) 1479static void AMSReclaim(Pool pool, Trace trace, Seg seg)
1322{ 1480{
1323 AMS ams; 1481 AMS ams;
1324 AMSSeg amsseg; 1482 AMSSeg amsseg;
1325 Format format; 1483 Count nowFree, grains;
1326 Align alignment; 1484 Size reclaimedSize;
1327 Count reclaimed = 0; 1485 PoolDebugMixin debug;
1328 Index i, j = 0;
1329 Addr p, next;
1330 1486
1331 AVERT(Pool, pool); 1487 AVERT(Pool, pool);
1332 ams = Pool2AMS(pool); 1488 ams = Pool2AMS(pool);
1333 AVERT(AMS, ams); 1489 AVERT(AMS, ams);
1490 AVERT(Trace, trace);
1334 AVERT(Seg, seg); 1491 AVERT(Seg, seg);
1335 1492
1336 amsseg = Seg2AMSSeg(seg); 1493 amsseg = Seg2AMSSeg(seg);
1337 /* It's a white seg, so it must have colour tables. */ 1494 /* It's a white seg, so it must have colour tables. */
1338 AVER(amsseg->colourTablesInUse); 1495 AVER(amsseg->colourTablesInUse);
1339 AVER(!amsseg->marksChanged); /* there must be nothing grey */ 1496 AVER(!amsseg->marksChanged); /* there must be nothing grey */
1340 format = pool->format; 1497 grains = amsseg->grains;
1341 AVERT(Format, format);
1342 alignment = PoolAlignment(AMS2Pool(ams));
1343 1498
1344 /* Start using allocTable */ 1499 /* Loop over all white blocks and splat them, if it's a debug class. */
1345 if (!amsseg->allocTableInUse) { 1500 debug = ((pool)->class->debugMixin)(pool);
1346 amsseg->allocTableInUse = TRUE; 1501 if (debug != NULL) {
1347 if (0 < amsseg->firstFree) 1502 Index i, j = 0;
1348 BTSetRange(amsseg->allocTable, 0, amsseg->firstFree); 1503
1349 if (amsseg->firstFree < amsseg->grains) 1504 while(j < grains && AMS_FIND_WHITE_RANGE(&i, &j, seg, j, grains)) {
1350 BTResRange(amsseg->allocTable, amsseg->firstFree, amsseg->grains); 1505 AVER(!AMS_IS_INVALID_COLOUR(seg, i));
1506 DebugPoolFreeSplat(pool, AMS_INDEX_ADDR(seg, i), AMS_INDEX_ADDR(seg, j));
1507 ++j; /* we know next grain is not white */
1508 }
1351 } 1509 }
1352 1510
1353 /* Loop over all white objects and free them */ 1511 nowFree = BTCountResRange(amsseg->nonwhiteTable, 0, grains);
1354 while(j < amsseg->grains 1512
1355 && AMSFindWhite(&i, &j, seg, j, amsseg->grains)) { 1513 /* If the free space is all after firstFree, keep on using firstFree. */
1356 Addr clientP, clientNext; 1514 /* It could have a more complicated condition, but not worth the trouble. */
1357 AVER(!AMSIsInvalidColor(seg, i)); 1515 if (!amsseg->allocTableInUse && amsseg->firstFree + nowFree == grains) {
1358 p = AMS_INDEX_ADDR(seg, i); 1516 AVER(amsseg->firstFree == grains
1359 clientP = AddrAdd(p, format->headerSize); 1517 || BTIsResRange(amsseg->nonwhiteTable,
1360 clientNext = (*format->skip)(clientP); 1518 amsseg->firstFree, grains));
1361 next = AddrSub(clientNext, format->headerSize); 1519 } else {
1362 AVER(AddrIsAligned(next, alignment)); 1520 if (ams->shareAllocTable) {
1363 j = AMS_ADDR_INDEX(seg, next); 1521 /* Stop using allocTable as the white table. */
1364 BTResRange(amsseg->allocTable, i, j); 1522 amsseg->allocTableInUse = TRUE;
1365 reclaimed += j - i; 1523 } else {
1524 AVER(amsseg->allocTableInUse);
1525 BTCopyRange(amsseg->nonwhiteTable, amsseg->allocTable, 0, grains);
1526 }
1366 } 1527 }
1367 1528
1368 amsseg->free += reclaimed; 1529 reclaimedSize = (nowFree - amsseg->free) << ams->grainShift;
1369 trace->reclaimSize += reclaimed << ams->grainShift; 1530 amsseg->free = nowFree;
1370 ams->pgen.totalSize -= reclaimed << ams->grainShift; 1531 trace->reclaimSize += reclaimedSize;
1532 ams->pgen.totalSize -= reclaimedSize;
1371 /* preservedInPlaceCount is updated on fix */ 1533 /* preservedInPlaceCount is updated on fix */
1372 trace->preservedInPlaceSize += 1534 trace->preservedInPlaceSize += (grains - amsseg->free) << ams->grainShift;
1373 (amsseg->grains - amsseg->free) << ams->grainShift;
1374 1535
1375 if (amsseg->free == amsseg->grains && SegBuffer(seg) == NULL) { 1536 if (amsseg->free == grains && SegBuffer(seg) == NULL) {
1376 /* No survivors */ 1537 /* No survivors */
1377 SegFree(seg); 1538 SegFree(seg);
1378 } else { 1539 } else {
@@ -1382,6 +1543,24 @@ void AMSReclaim(Pool pool, Trace trace, Seg seg)
1382} 1543}
1383 1544
1384 1545
1546/* AMSFreeWalk -- free block walking method of the pool class */
1547
1548static void AMSFreeWalk(Pool pool, FreeBlockStepMethod f, void *p)
1549{
1550 AMS ams;
1551 Ring node, ring, nextNode; /* for iterating over the segments */
1552
1553 AVERT(Pool, pool);
1554 ams = Pool2AMS(pool);
1555 AVERT(AMS, ams);
1556
1557 ring = &ams->segRing;
1558 RING_FOR(node, ring, nextNode) {
1559 AMSSegFreeWalk(RING_ELT(AMSSeg, segRing, node), f, p);
1560 }
1561}
1562
1563
1385/* AMSDescribe -- the pool class description method 1564/* AMSDescribe -- the pool class description method
1386 * 1565 *
1387 * Iterates over the segments, describing all of them. 1566 * Iterates over the segments, describing all of them.
@@ -1441,41 +1620,60 @@ DEFINE_CLASS(AMSPoolClass, this)
1441 this->bufferClass = RankBufClassGet; 1620 this->bufferClass = RankBufClassGet;
1442 this->bufferFill = AMSBufferFill; 1621 this->bufferFill = AMSBufferFill;
1443 this->bufferEmpty = AMSBufferEmpty; 1622 this->bufferEmpty = AMSBufferEmpty;
1444 this->whiten = AMSWhiten; 1623 this->whiten = AMSCondemn;
1445 this->blacken = AMSBlacken; 1624 this->blacken = AMSBlacken;
1446 this->scan = AMSScan; 1625 this->scan = AMSScan;
1447 this->fix = AMSFix; 1626 this->fix = AMSFix;
1448 this->fixEmergency = AMSFix; 1627 this->fixEmergency = AMSFix;
1449 this->reclaim = AMSReclaim; 1628 this->reclaim = AMSReclaim;
1629 this->freewalk = AMSFreeWalk;
1450 this->describe = AMSDescribe; 1630 this->describe = AMSDescribe;
1451} 1631}
1452 1632
1453 1633
1634/* AMSDebugMixin - find debug mixin in class AMSDebug */
1635
1636static PoolDebugMixin AMSDebugMixin(Pool pool)
1637{
1638 AMS ams;
1639
1640 AVERT(Pool, pool);
1641 ams = Pool2AMS(pool);
1642 AVERT(AMS, ams);
1643 /* Can't check AMSDebug, because this is called during init */
1644 return &(AMS2AMSDebug(ams)->debug);
1645}
1646
1647
1648/* AMSDebugPoolClass -- the class definition for the debug version */
1649
1650DEFINE_POOL_CLASS(AMSDebugPoolClass, this)
1651{
1652 INHERIT_CLASS(this, AMSPoolClass);
1653 PoolClassMixInDebug(this);
1654 this->name = "AMSDBG";
1655 this->size = sizeof(AMSDebugStruct);
1656 this->debugMixin = AMSDebugMixin;
1657}
1658
1659
1454/* AMSCheck -- the check method for an AMS */ 1660/* AMSCheck -- the check method for an AMS */
1455 1661
1456Bool AMSCheck(AMS ams) 1662Bool AMSCheck(AMS ams)
1457{ 1663{
1458 CHECKS(AMS, ams); 1664 CHECKS(AMS, ams);
1459 CHECKD(Pool, AMS2Pool(ams)); 1665 CHECKL(PoolCheck(AMS2Pool(ams)));
1460 CHECKL(IsSubclassPoly(AMS2Pool(ams)->class, AMSPoolClassGet())); 1666 CHECKL(IsSubclassPoly(AMS2Pool(ams)->class, AMSPoolClassGet()));
1461 CHECKL(PoolAlignment(AMS2Pool(ams)) == ((Size)1 << ams->grainShift)); 1667 CHECKL(PoolAlignment(AMS2Pool(ams)) == ((Size)1 << ams->grainShift));
1462 CHECKL(PoolAlignment(AMS2Pool(ams)) == AMS2Pool(ams)->format->alignment); 1668 CHECKL(PoolAlignment(AMS2Pool(ams)) == AMS2Pool(ams)->format->alignment);
1463 CHECKD(Chain, ams->chain); 1669 CHECKD(Chain, ams->chain);
1464 CHECKD(PoolGen, &ams->pgen); 1670 CHECKD(PoolGen, &ams->pgen);
1465 CHECKL(SizeIsAligned(ams->size, ArenaAlign(PoolArena(AMS2Pool(ams))))); 1671 CHECKL(SizeIsAligned(ams->size, ArenaAlign(PoolArena(AMS2Pool(ams)))));
1466 CHECKL(ams->iterate != NULL); 1672 CHECKL(FUNCHECK(ams->segSize));
1467 CHECKL(RingCheck(&ams->segRing)); 1673 CHECKL(RingCheck(&ams->segRing));
1468 CHECKL(ams->allocRing != NULL); 1674 CHECKL(FUNCHECK(ams->allocRing));
1469 CHECKL(ams->segsDestroy != NULL); 1675 CHECKL(FUNCHECK(ams->segsDestroy));
1470 CHECKL(ams->segClass != NULL); 1676 CHECKL(FUNCHECK(ams->segClass));
1471 1677
1472 return TRUE; 1678 return TRUE;
1473} 1679}
1474
1475
1476/* mps_class_ams -- return the pool class descriptor to the client */
1477
1478mps_class_t mps_class_ams(void)
1479{
1480 return (mps_class_t)AMSPoolClassGet();
1481}
diff --git a/mps/code/poolams.h b/mps/code/poolams.h
index 498cc50b04e..7153953e08f 100644
--- a/mps/code/poolams.h
+++ b/mps/code/poolams.h
@@ -2,14 +2,17 @@
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 * .purpose: Internal interface to AMS functionality. 7 * .purpose: Internal interface to AMS functionality. */
7 */
8 8
9#ifndef poolams_h 9#ifndef poolams_h
10#define poolams_h 10#define poolams_h
11 11
12#include "mpm.h" 12#include "mpmtypes.h"
13#include "mpmst.h"
14#include "ring.h"
15#include "bt.h"
13#include <stdarg.h> 16#include <stdarg.h>
14 17
15 18
@@ -32,19 +35,6 @@ typedef void (*AMSSegsDestroyFunction)(AMS ams);
32typedef Res (*AMSSegSizePolicyFunction)(Size *sizeReturn, 35typedef Res (*AMSSegSizePolicyFunction)(Size *sizeReturn,
33 Pool pool, Size size, 36 Pool pool, Size size,
34 RankSet rankSet); 37 RankSet rankSet);
35/* AMSObjectFunction is the type of the method that an */
36/* AMSIterateFunction applies to each object in a segment. */
37typedef Res (*AMSObjectFunction)(
38 /* the segment */ Seg seg,
39 /* the object grain index */ Index i,
40 /* the address of the object */Addr p,
41 /* " " after the object */Addr next,
42 /* the iteration closure */ void *closure);
43
44#define AMSObjectFunctionCheck(f) \
45 ((f) != NULL) /* that's the best we can do */
46
47typedef Res (*AMSIterateFunction)(Seg seg, AMSObjectFunction f, void *closure);
48 38
49 39
50typedef struct AMSStruct { 40typedef struct AMSStruct {
@@ -53,12 +43,12 @@ typedef struct AMSStruct {
53 Chain chain; /* chain used by this pool */ 43 Chain chain; /* chain used by this pool */
54 PoolGenStruct pgen; /* generation representing the pool */ 44 PoolGenStruct pgen; /* generation representing the pool */
55 Size size; /* total segment size of the pool */ 45 Size size; /* total segment size of the pool */
56 AMSIterateFunction iterate; /* iterator function */
57 AMSSegSizePolicyFunction segSize; /* SegSize policy */ 46 AMSSegSizePolicyFunction segSize; /* SegSize policy */
58 RingStruct segRing; /* ring of segments in the pool */ 47 RingStruct segRing; /* ring of segments in the pool */
59 AMSRingFunction allocRing; /* fn to get the ring to allocate from */ 48 AMSRingFunction allocRing; /* fn to get the ring to allocate from */
60 AMSSegsDestroyFunction segsDestroy; 49 AMSSegsDestroyFunction segsDestroy;
61 AMSSegClassFunction segClass;/* fn to get the class for segments */ 50 AMSSegClassFunction segClass;/* fn to get the class for segments */
51 Bool shareAllocTable; /* the alloc table is also used as white table */
62 Sig sig; /* design.mps.pool.outer-structure.sig */ 52 Sig sig; /* design.mps.pool.outer-structure.sig */
63} AMSStruct; 53} AMSStruct;
64 54
@@ -70,15 +60,15 @@ typedef struct AMSSegStruct {
70 Count grains; /* number of grains */ 60 Count grains; /* number of grains */
71 Count free; /* number of free grains */ 61 Count free; /* number of free grains */
72 Count newAlloc; /* number of grains allocated since last GC */ 62 Count newAlloc; /* number of grains allocated since last GC */
73 Bool allocTableInUse; /* whether we use allocTable */ 63 Bool allocTableInUse; /* allocTable is used */
74 Index firstFree; /* 1st free grain, if allocTable is not used */ 64 Index firstFree; /* 1st free grain, if allocTable is not used */
75 BT allocTable; /* set if grain is allocated */ 65 BT allocTable; /* set if grain is allocated */
76 /* design.mps.poolams.colour.single */ 66 /* design.mps.poolams.colour.single */
77 Bool marksChanged; /* has been marked since last scan */ 67 Bool marksChanged; /* seg has been marked since last scan */
78 Bool ambiguousFixes; /* has been ambiguously marked since last scan */ 68 Bool ambiguousFixes; /* seg has been ambiguously marked since last scan */
79 Bool colourTablesInUse;/* whether we use the colour tables */ 69 Bool colourTablesInUse;/* the colour tables are in use */
80 BT nongreyTable; /* set if grain not grey */
81 BT nonwhiteTable; /* set if grain not white */ 70 BT nonwhiteTable; /* set if grain not white */
71 BT nongreyTable; /* set if not first grain of grey object */
82 Sig sig; 72 Sig sig;
83} AMSSegStruct; 73} AMSSegStruct;
84 74
@@ -110,59 +100,62 @@ typedef struct AMSSegStruct {
110 100
111/* colour ops */ 101/* colour ops */
112 102
113#define AMSIsWhite(seg, index) \ 103#define AMS_IS_WHITE(seg, index) \
114 (!BTGet(Seg2AMSSeg(seg)->nonwhiteTable, index)) 104 (!BTGet(Seg2AMSSeg(seg)->nonwhiteTable, index))
115 105
116#define AMSIsGrey(seg, index) \ 106#define AMS_IS_GREY(seg, index) \
117 (!BTGet(Seg2AMSSeg(seg)->nongreyTable, index)) 107 (!BTGet(Seg2AMSSeg(seg)->nongreyTable, index))
118 108
119#define AMSIsBlack(seg, index) \ 109#define AMS_IS_BLACK(seg, index) \
120 (!AMSIsGrey(seg, index) && !AMSIsWhite(seg, index)) 110 (!AMS_IS_GREY(seg, index) && !AMS_IS_WHITE(seg, index))
121 111
122#define AMSIsInvalidColor(seg, index) \ 112#define AMS_IS_INVALID_COLOUR(seg, index) \
123 (AMSIsGrey(seg, index) && AMSIsWhite(seg, index)) 113 (AMS_IS_GREY(seg, index) && AMS_IS_WHITE(seg, index))
124 114
125#define AMSGreyBlacken(seg, index) \ 115#define AMS_WHITE_GREYEN(seg, index) \
126 BEGIN \ 116 BEGIN \
127 BTSet(Seg2AMSSeg(seg)->nongreyTable, index); \ 117 BTSet(Seg2AMSSeg(seg)->nonwhiteTable, index); \
118 BTRes(Seg2AMSSeg(seg)->nongreyTable, index); \
128 END 119 END
129 120
130#define AMSWhiteGreyen(seg, index) \ 121#define AMS_GREY_BLACKEN(seg, index) \
131 BEGIN \ 122 BEGIN \
132 BTSet(Seg2AMSSeg(seg)->nonwhiteTable, index); \ 123 BTSet(Seg2AMSSeg(seg)->nongreyTable, index); \
133 BTRes(Seg2AMSSeg(seg)->nongreyTable, index); \
134 END 124 END
135 125
136#define AMSWhiteBlacken(seg, index) \ 126#define AMS_WHITE_BLACKEN(seg, index) \
137 BEGIN \ 127 BEGIN \
138 BTSet(Seg2AMSSeg(seg)->nonwhiteTable, index); \ 128 BTSet(Seg2AMSSeg(seg)->nonwhiteTable, index); \
139 END 129 END
140 130
141#define AMSRangeWhiteBlacken(seg, base, limit) \ 131#define AMS_RANGE_WHITE_BLACKEN(seg, base, limit) \
142 BEGIN \ 132 BEGIN \
143 BTSetRange(Seg2AMSSeg(seg)->nonwhiteTable, base, limit); \ 133 BTSetRange(Seg2AMSSeg(seg)->nonwhiteTable, base, limit); \
144 END 134 END
145 135
146#define AMSRangeWhiten(seg, base, limit) \ 136#define AMS_RANGE_BLACKEN(seg, base, limit) \
147 BEGIN \ 137 BEGIN \
148 BTResRange(Seg2AMSSeg(seg)->nonwhiteTable, base, limit); \ 138 BTSetRange(Seg2AMSSeg(seg)->nonwhiteTable, base, limit); \
149 BTSetRange(Seg2AMSSeg(seg)->nongreyTable, base, limit); \ 139 BTSetRange(Seg2AMSSeg(seg)->nongreyTable, base, limit); \
150 END 140 END
151 141
152#define AMSRangeBlacken(seg, base, limit) \ 142#define AMS_RANGE_WHITEN(seg, base, limit) \
153 BEGIN \ 143 BEGIN \
154 BTSetRange(Seg2AMSSeg(seg)->nonwhiteTable, base, limit); \ 144 BTResRange(Seg2AMSSeg(seg)->nonwhiteTable, base, limit); \
155 BTSetRange(Seg2AMSSeg(seg)->nongreyTable, base, limit); \ 145 BTSetRange(Seg2AMSSeg(seg)->nongreyTable, base, limit); \
156 END 146 END
157 147
158#define AMSFindGrey(pos, dummy, seg, base, limit) \ 148#define AMSFindGrey(pos, dummy, seg, base, limit) \
159 BTFindShortResRange(pos, dummy, Seg2AMSSeg(seg)->nongreyTable, \ 149 BTFindShortResRange(pos, dummy, Seg2AMSSeg(seg)->nongreyTable, \
160 base, limit, 1) \ 150 base, limit, 1)
161 151
162#define AMSFindWhite(pos, dummy, seg, base, limit) \ 152#define AMSFindWhite(pos, dummy, seg, base, limit) \
163 BTFindShortResRange(pos, dummy, Seg2AMSSeg(seg)->nonwhiteTable, \ 153 BTFindShortResRange(pos, dummy, Seg2AMSSeg(seg)->nonwhiteTable, \
164 base, limit, 1) \ 154 base, limit, 1)
165 155
156#define AMS_FIND_WHITE_RANGE(baseOut, limitOut, seg, base, limit) \
157 BTFindLongResRange(baseOut, limitOut, Seg2AMSSeg(seg)->nonwhiteTable, \
158 base, limit, 1)
166 159
167#define AMS_ALLOCED(seg, index) \ 160#define AMS_ALLOCED(seg, index) \
168 (Seg2AMSSeg(seg)->allocTableInUse \ 161 (Seg2AMSSeg(seg)->allocTableInUse \
@@ -172,25 +165,19 @@ typedef struct AMSSegStruct {
172 165
173/* the rest */ 166/* the rest */
174 167
175extern Res AMSInitInternal(AMS ams, Format format, Chain chain); 168extern Res AMSInitInternal(AMS ams, Format format, Chain chain,
169 Bool shareAllocTable);
176extern void AMSFinish(Pool pool); 170extern void AMSFinish(Pool pool);
177extern Bool AMSCheck(AMS ams); 171extern Bool AMSCheck(AMS ams);
178 172
179extern Res AMSBufferInit(Pool pool, Buffer buffer, va_list args);
180extern Res AMSBufferFill(Addr *baseReturn, Addr *limitReturn,
181 Pool pool, Buffer buffer, Size size,
182 Bool withReservoirPermit);
183extern void AMSBufferEmpty(Pool pool, Buffer buffer,
184 Addr init, Addr limit);
185
186extern Res AMSWhiten(Pool pool, Trace trace, Seg seg);
187extern Res AMSScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg); 173extern Res AMSScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg);
188extern Res AMSFix(Pool pool, ScanState ss, Seg seg, Ref *refIO);
189extern void AMSBlacken(Pool pool, TraceSet traceSet, Seg seg);
190extern void AMSReclaim(Pool pool, Trace trace, Seg seg);
191 174
192#define AMSChain(ams) ((ams)->chain) 175#define AMSChain(ams) ((ams)->chain)
193 176
177extern void AMSSegFreeWalk(AMSSeg amsseg, FreeBlockStepMethod f, void *p);
178
179extern void AMSSegFreeCheck(AMSSeg amsseg);
180
194 181
195typedef SegClass AMSSegClass; 182typedef SegClass AMSSegClass;
196typedef SegClassStruct AMSSegClassStruct; 183typedef SegClassStruct AMSSegClassStruct;
@@ -202,6 +189,7 @@ typedef PoolClass AMSPoolClass;
202typedef PoolClassStruct AMSPoolClassStruct; 189typedef PoolClassStruct AMSPoolClassStruct;
203 190
204extern AMSPoolClass AMSPoolClassGet(void); 191extern AMSPoolClass AMSPoolClassGet(void);
192extern AMSPoolClass AMSDebugPoolClassGet(void);
205 193
206 194
207#endif /* poolams_h */ 195#endif /* poolams_h */
diff --git a/mps/code/poolamsi.c b/mps/code/poolamsi.c
new file mode 100644
index 00000000000..c22236c0d7e
--- /dev/null
+++ b/mps/code/poolamsi.c
@@ -0,0 +1,28 @@
1/* impl.c.poolamsi: AUTOMATIC MARK & SWEEP POOL CLASS C INTERFACE
2 *
3 * $Id: poolamsi.c,v 1.2 2002/02/01 14:27:28 pekka Exp $
4 * $HopeName: MMsrc!poolamsi.c(trunk.2) $
5 * Copyright (C) 2002 Global Graphics Software.
6 */
7
8#include "mpscams.h"
9#include "mps.h"
10#include "poolams.h"
11
12SRCID(poolamsi, "$Id: poolamsi.c,v 1.2 2002/02/01 14:27:28 pekka Exp $");
13
14
15/* mps_class_ams -- return the AMS pool class descriptor */
16
17mps_class_t mps_class_ams(void)
18{
19 return (mps_class_t)AMSPoolClassGet();
20}
21
22
23/* mps_class_ams_debug -- return the AMS (debug) pool class descriptor */
24
25mps_class_t mps_class_ams_debug(void)
26{
27 return (mps_class_t)AMSDebugPoolClassGet();
28}
diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c
index d7f0992c40b..bcf799b0bc0 100644
--- a/mps/code/poolawl.c
+++ b/mps/code/poolawl.c
@@ -43,7 +43,6 @@
43#include "mpm.h" 43#include "mpm.h"
44#include "chain.h" 44#include "chain.h"
45 45
46
47SRCID(poolawl, "$Id$"); 46SRCID(poolawl, "$Id$");
48 47
49 48
diff --git a/mps/code/poolmfs.h b/mps/code/poolmfs.h
index ab145f2a70d..7d77e29dc87 100644
--- a/mps/code/poolmfs.h
+++ b/mps/code/poolmfs.h
@@ -1,6 +1,4 @@
1/* impl.h.poolmfs draft impl 1/* impl.h.poolmfs: MANUAL FIXED SMALL UNIT POOL
2 *
3 * MANUAL FIXED SMALL UNIT POOL
4 * 2 *
5 * $Id$ 3 * $Id$
6 * 4 *
diff --git a/mps/code/poolmrg.c b/mps/code/poolmrg.c
index f10933c2db8..c276794e1a8 100644
--- a/mps/code/poolmrg.c
+++ b/mps/code/poolmrg.c
@@ -2,7 +2,9 @@
2 * 2 *
3 * $Id$ 3 * $Id$
4 * Copyright (c) 2001 Ravenbrook Limited. 4 * Copyright (c) 2001 Ravenbrook Limited.
5 * 5 * Copyright (C) 2002 Global Graphics Software.
6 *
7 *
6 * DESIGN 8 * DESIGN
7 * 9 *
8 * .design: See design.mps.poolmrg. 10 * .design: See design.mps.poolmrg.
@@ -26,6 +28,7 @@
26 * and MRG pools, whatever that might be. 28 * and MRG pools, whatever that might be.
27 */ 29 */
28 30
31#include "ring.h"
29#include "mpm.h" 32#include "mpm.h"
30#include "poolmrg.h" 33#include "poolmrg.h"
31 34
@@ -34,12 +37,11 @@ SRCID(poolmrg, "$Id$");
34 37
35/* Types */ 38/* Types */
36 39
37/* enumerate the states of a Guardian */ 40/* enumerate the states of a guardian */
38enum { 41enum {
39 MRGGuardianFREE = 1, 42 MRGGuardianFREE = 1,
40 MRGGuardianPREFINAL, 43 MRGGuardianPREFINAL,
41 MRGGuardianFINAL, 44 MRGGuardianFINAL
42 MRGGuardianPOSTFINAL
43}; 45};
44 46
45 47
@@ -47,7 +49,7 @@ enum {
47 49
48typedef struct LinkStruct *Link; 50typedef struct LinkStruct *Link;
49typedef struct LinkStruct { 51typedef struct LinkStruct {
50 int state; /* Free, Prefinal, Final, Postfinal */ 52 int state; /* Free, Prefinal, Final */
51 union { 53 union {
52 MessageStruct messageStruct; /* state = Final */ 54 MessageStruct messageStruct; /* state = Final */
53 RingStruct linkRing; /* state one of {Free, Prefinal} */ 55 RingStruct linkRing; /* state one of {Free, Prefinal} */
@@ -323,9 +325,11 @@ static Count MRGGuardiansPerSeg(MRG mrg)
323 325
324/* design.mps.poolmrg.guardian.assoc */ 326/* design.mps.poolmrg.guardian.assoc */
325 327
328
326#define refPartOfIndex(refseg, index) \ 329#define refPartOfIndex(refseg, index) \
327 ((RefPart)SegBase(RefSeg2Seg(refseg)) + (index)) 330 ((RefPart)SegBase(RefSeg2Seg(refseg)) + (index))
328 331
332
329static RefPart MRGRefPartOfLink(Link link, Arena arena) 333static RefPart MRGRefPartOfLink(Link link, Arena arena)
330{ 334{
331 Seg seg; 335 Seg seg;
@@ -349,9 +353,12 @@ static RefPart MRGRefPartOfLink(Link link, Arena arena)
349 return refPartOfIndex(linkseg->refSeg, index); 353 return refPartOfIndex(linkseg->refSeg, index);
350} 354}
351 355
356
352#define linkOfIndex(linkseg, index) \ 357#define linkOfIndex(linkseg, index) \
353 ((Link)SegBase(LinkSeg2Seg(linkseg)) + (index)) 358 ((Link)SegBase(LinkSeg2Seg(linkseg)) + (index))
354 359
360
361#if 0
355static Link MRGLinkOfRefPart(RefPart refPart, Arena arena) 362static Link MRGLinkOfRefPart(RefPart refPart, Arena arena)
356{ 363{
357 Seg seg; 364 Seg seg;
@@ -374,6 +381,7 @@ static Link MRGLinkOfRefPart(RefPart refPart, Arena arena)
374 381
375 return linkOfIndex(refseg->linkSeg, index); 382 return linkOfIndex(refseg->linkSeg, index);
376} 383}
384#endif
377 385
378 386
379/* MRGGuardianInit -- Initialises both parts of a guardian */ 387/* MRGGuardianInit -- Initialises both parts of a guardian */
@@ -395,35 +403,26 @@ static void MRGGuardianInit(MRG mrg, Link link, RefPart refPart)
395/* MRGMessage* -- Implementation of MRG's MessageClass */ 403/* MRGMessage* -- Implementation of MRG's MessageClass */
396 404
397 405
398/* MRGMessageDelete -- deletes the message (frees up the memory) */ 406/* MRGMessageDelete -- deletes the message (frees up the guardian) */
399 407
400static void MRGMessageDelete(Message message) 408static void MRGMessageDelete(Message message)
401{ 409{
402 RefPart refPart;
403 Pool pool; 410 Pool pool;
404 Arena arena; 411 Arena arena;
405 Link link; 412 Link link;
413 Bool b;
406 414
407 AVERT(Message, message); 415 AVERT(Message, message);
408 416
409 arena = MessageArena(message); 417 arena = MessageArena(message);
410 418 b = PoolOfAddr(&pool, arena, (Addr)message);
411 { /* Calculate pool */ 419 AVER(b);
412 Bool b;
413 Seg seg;
414 b = SegOfAddr(&seg, arena, (Addr)message);
415 AVER(b);
416
417 pool = SegPool(seg);
418 }
419 AVER(pool->class == PoolClassMRG()); 420 AVER(pool->class == PoolClassMRG());
420 421
421 link = linkOfMessage(message); 422 link = linkOfMessage(message);
422 MessageFinish(message);
423 AVER(link->state == MRGGuardianFINAL); 423 AVER(link->state == MRGGuardianFINAL);
424 link->state = MRGGuardianPOSTFINAL; 424 MessageFinish(message);
425 refPart = MRGRefPartOfLink(link, arena); 425 MRGGuardianInit(Pool2MRG(pool), link, MRGRefPartOfLink(link, arena));
426 PoolFree(pool, (Addr)refPart, sizeof(RefPartStruct));
427} 426}
428 427
429 428
@@ -547,7 +546,7 @@ failLinkSegAlloc:
547} 546}
548 547
549 548
550/* MRGFinalise -- finalize the indexth guardian in the segment */ 549/* MRGFinalize -- finalize the indexth guardian in the segment */
551 550
552static void MRGFinalize(Arena arena, MRGLinkSeg linkseg, Index index) 551static void MRGFinalize(Arena arena, MRGLinkSeg linkseg, Index index)
553{ 552{
@@ -686,6 +685,8 @@ static void MRGFinish(Pool pool)
686} 685}
687 686
688 687
688/* MRGRegister -- register an object for finalization */
689
689Res MRGRegister(Pool pool, Ref ref) 690Res MRGRegister(Pool pool, Ref ref)
690{ 691{
691 Ring freeNode; 692 Ring freeNode;
@@ -707,7 +708,6 @@ Res MRGRegister(Pool pool, Ref ref)
707 708
708 /* design.mps.poolmrg.alloc.grow */ 709 /* design.mps.poolmrg.alloc.grow */
709 if (RingIsSingle(&mrg->freeRing)) { 710 if (RingIsSingle(&mrg->freeRing)) {
710 /* .refseg.useless: refseg isn't used */
711 /* @@@@ Should the client be able to use the reservoir for this? */ 711 /* @@@@ Should the client be able to use the reservoir for this? */
712 res = MRGSegPairCreate(&junk, mrg, /* withReservoirPermit */ FALSE); 712 res = MRGSegPairCreate(&junk, mrg, /* withReservoirPermit */ FALSE);
713 if (res != ResOK) 713 if (res != ResOK)
@@ -731,32 +731,49 @@ Res MRGRegister(Pool pool, Ref ref)
731} 731}
732 732
733 733
734/* MRGFree -- free a guardian */ 734/* MRGDeregister -- deregister (once) an object for finalization */
735 735
736static void MRGFree(Pool pool, Addr old, Size size) 736Res MRGDeregister(Pool pool, Ref obj)
737{ 737{
738 MRG mrg; 738 Ring node, nextNode;
739 Count nGuardians; /* guardians per seg */
739 Arena arena; 740 Arena arena;
740 Link link; 741 MRG mrg;
741 RefPart refPart;
742 742
743 AVERT(Pool, pool); 743 AVERT(Pool, pool);
744 AVER(old != (Addr)0); 744 /* Can't check obj */
745 AVER(size == sizeof(RefPartStruct));
746 745
747 mrg = Pool2MRG(pool); 746 mrg = Pool2MRG(pool);
748 AVERT(MRG, mrg); 747 AVERT(MRG, mrg);
749 748 nGuardians = MRGGuardiansPerSeg(mrg);
750 refPart = (RefPart)old;
751
752 arena = PoolArena(pool); 749 arena = PoolArena(pool);
753 AVERT(Arena, arena);
754 750
755 /* design.mps.poolmrg.guardian.ref.free */ 751 /* map over the segments */
756 link = MRGLinkOfRefPart(refPart, arena); 752 RING_FOR(node, &mrg->refRing, nextNode) {
757 AVER(link->state == MRGGuardianPOSTFINAL); 753 MRGRefSeg refSeg = RING_ELT(MRGRefSeg, mrgRing, node);
758 754 MRGLinkSeg linkSeg;
759 MRGGuardianInit(mrg, link, refPart); 755 Count i;
756 Link link;
757 RefPart refPart;
758
759 AVERT(MRGRefSeg, refSeg);
760 linkSeg = refSeg->linkSeg;
761 /* map over each guardian in the segment */
762 for(i = 0, link = (Link)SegBase(LinkSeg2Seg(linkSeg)),
763 refPart = (RefPart)SegBase(RefSeg2Seg(refSeg));
764 i < nGuardians;
765 ++i, ++link, ++refPart) {
766 /* check if it's allocated and points to obj */
767 if (link->state == MRGGuardianPREFINAL
768 && MRGRefPartRef(arena, refPart) == obj) {
769 RingRemove(&link->the.linkRing);
770 RingFinish(&link->the.linkRing);
771 MRGGuardianInit(mrg, link, refPart);
772 return ResOK;
773 }
774 }
775 }
776 return ResFAIL;
760} 777}
761 778
762 779
@@ -833,7 +850,6 @@ DEFINE_POOL_CLASS(MRGPoolClass, this)
833 this->attr |= (AttrSCAN | AttrFREE | AttrINCR_RB); 850 this->attr |= (AttrSCAN | AttrFREE | AttrINCR_RB);
834 this->init = MRGInit; 851 this->init = MRGInit;
835 this->finish = MRGFinish; 852 this->finish = MRGFinish;
836 this->free = MRGFree;
837 this->grey = PoolTrivGrey; 853 this->grey = PoolTrivGrey;
838 this->blacken = PoolTrivBlacken; 854 this->blacken = PoolTrivBlacken;
839 this->scan = MRGScan; 855 this->scan = MRGScan;
diff --git a/mps/code/poolmrg.h b/mps/code/poolmrg.h
index e6a937fc5fc..fc7b5378f0e 100644
--- a/mps/code/poolmrg.h
+++ b/mps/code/poolmrg.h
@@ -1,19 +1,20 @@
1/* impl.h.amc draft impl 1/* impl.h.poolmrg: MANUAL RANK GUARDIAN POOL CLASS INTERFACE
2 *
3 * MANUAL RANK GUARDIAN POOL CLASS
4 * 2 *
5 * $Id$ 3 * $Id$
6 * Copyright (c) 2001 Ravenbrook Limited. 4 *
5 * Copyright (c) 2001 Ravenbrook Limited.
6 * Copyright (c) 2002 Global Graphics Software.
7 */ 7 */
8 8
9#ifndef poolmrg_h 9#ifndef poolmrg_h
10#define poolmrg_h 10#define poolmrg_h
11 11
12#include "mpm.h" 12#include "mpmtypes.h"
13 13
14typedef struct MRGStruct *MRG; 14typedef struct MRGStruct *MRG;
15 15
16extern PoolClass PoolClassMRG(void); 16extern PoolClass PoolClassMRG(void);
17extern Res MRGRegister(Pool, Ref); 17extern Res MRGRegister(Pool, Ref);
18extern Res MRGDeregister(Pool, Ref);
18 19
19#endif /* poolmrg_h */ 20#endif /* poolmrg_h */
diff --git a/mps/code/poolmv.c b/mps/code/poolmv.c
index 7a9115eecd0..5bb92d5a799 100644
--- a/mps/code/poolmv.c
+++ b/mps/code/poolmv.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 * **** RESTRICTION: This pool may not allocate from the arena control 7 * **** RESTRICTION: This pool may not allocate from the arena control
7 * pool, since it is used to implement that pool. 8 * pool, since it is used to implement that pool.
@@ -37,14 +38,7 @@ SRCID(poolmv, "$Id$");
37#define mvSpanPool(mv) MFSPool(&(mv)->spanPoolStruct) 38#define mvSpanPool(mv) MFSPool(&(mv)->spanPoolStruct)
38 39
39 40
40#define PoolPoolMV(pool) PARENT(MVStruct, poolStruct, pool) 41#define Pool2MV(pool) PARENT(MVStruct, poolStruct, pool)
41
42
43Pool (MVPool)(MV mv)
44{
45 AVERT(MV, mv);
46 return &mv->poolStruct;
47}
48 42
49 43
50/* MVDebug -- MV Debug pool class */ 44/* MVDebug -- MV Debug pool class */
@@ -57,8 +51,8 @@ typedef struct MVDebugStruct {
57typedef MVDebugStruct *MVDebug; 51typedef MVDebugStruct *MVDebug;
58 52
59 53
60#define MVPoolMVDebug(mv) PARENT(MVDebugStruct, MVStruct, mv) 54#define MV2MVDebug(mv) PARENT(MVDebugStruct, MVStruct, mv)
61#define MVDebugPoolMV(mvd) (&((mvd)->MVStruct)) 55#define MVDebug2MV(mvd) (&((mvd)->MVStruct))
62 56
63 57
64/* MVBlockStruct -- block structure 58/* MVBlockStruct -- block structure
@@ -207,7 +201,7 @@ static Res MVInit(Pool pool, va_list arg)
207 AVER(maxSize > 0); 201 AVER(maxSize > 0);
208 AVER(extendBy <= maxSize); 202 AVER(extendBy <= maxSize);
209 203
210 mv = PoolPoolMV(pool); 204 mv = Pool2MV(pool);
211 arena = PoolArena(pool); 205 arena = PoolArena(pool);
212 206
213 /* At 100% fragmentation we will need one block descriptor for every other */ 207 /* At 100% fragmentation we will need one block descriptor for every other */
@@ -255,7 +249,7 @@ static void MVFinish(Pool pool)
255 MVSpan span; 249 MVSpan span;
256 250
257 AVERT(Pool, pool); 251 AVERT(Pool, pool);
258 mv = PoolPoolMV(pool); 252 mv = Pool2MV(pool);
259 AVERT(MV, mv); 253 AVERT(MV, mv);
260 254
261 /* Destroy all the spans attached to the pool. */ 255 /* Destroy all the spans attached to the pool. */
@@ -477,7 +471,7 @@ static Res MVAlloc(Addr *pReturn, Pool pool, Size size,
477 471
478 AVER(pReturn != NULL); 472 AVER(pReturn != NULL);
479 AVERT(Pool, pool); 473 AVERT(Pool, pool);
480 mv = PoolPoolMV(pool); 474 mv = Pool2MV(pool);
481 AVERT(MV, mv); 475 AVERT(MV, mv);
482 AVER(size > 0); 476 AVER(size > 0);
483 AVERT(Bool, withReservoirPermit); 477 AVERT(Bool, withReservoirPermit);
@@ -530,8 +524,10 @@ static Res MVAlloc(Addr *pReturn, Pool pool, Size size,
530 return res; 524 return res;
531 } 525 }
532 } 526 }
533
534 limit = AddrAdd(base, regionSize); 527 limit = AddrAdd(base, regionSize);
528
529 DebugPoolFreeSplat(pool, base, limit);
530
535 span->size = regionSize; 531 span->size = regionSize;
536 span->tract = TractOfBaseAddr(arena, base); 532 span->tract = TractOfBaseAddr(arena, base);
537 span->mv = mv; 533 span->mv = mv;
@@ -551,7 +547,6 @@ static Res MVAlloc(Addr *pReturn, Pool pool, Size size,
551 span->base.next = &span->limit; 547 span->base.next = &span->limit;
552 span->blocks = &span->base; 548 span->blocks = &span->base;
553 span->blockCount = 2; 549 span->blockCount = 2;
554
555 span->base.limit = AddrAdd(span->base.limit, size); 550 span->base.limit = AddrAdd(span->base.limit, size);
556 span->space -= size; 551 span->space -= size;
557 span->largest = span->space; 552 span->largest = span->space;
@@ -581,7 +576,7 @@ static void MVFree(Pool pool, Addr old, Size size)
581 Tract tract; 576 Tract tract;
582 577
583 AVERT(Pool, pool); 578 AVERT(Pool, pool);
584 mv = PoolPoolMV(pool); 579 mv = Pool2MV(pool);
585 AVERT(MV, mv); 580 AVERT(MV, mv);
586 581
587 AVER(old != (Addr)0); 582 AVER(old != (Addr)0);
@@ -632,10 +627,10 @@ static PoolDebugMixin MVDebugMixin(Pool pool)
632 MV mv; 627 MV mv;
633 628
634 AVERT(Pool, pool); 629 AVERT(Pool, pool);
635 mv = PoolPoolMV(pool); 630 mv = Pool2MV(pool);
636 AVERT(MV, mv); 631 AVERT(MV, mv);
637 /* Can't check MVDebug, because this is called during MVDebug init */ 632 /* Can't check MVDebug, because this is called during MVDebug init */
638 return &(MVPoolMVDebug(mv)->debug); 633 return &(MV2MVDebug(mv)->debug);
639} 634}
640 635
641 636
@@ -650,7 +645,7 @@ static Res MVDescribe(Pool pool, mps_lib_FILE *stream)
650 Ring spans, node = NULL, nextNode; /* gcc whinge stop */ 645 Ring spans, node = NULL, nextNode; /* gcc whinge stop */
651 646
652 if(!CHECKT(Pool, pool)) return ResFAIL; 647 if(!CHECKT(Pool, pool)) return ResFAIL;
653 mv = PoolPoolMV(pool); 648 mv = Pool2MV(pool);
654 if(!CHECKT(MV, mv)) return ResFAIL; 649 if(!CHECKT(MV, mv)) return ResFAIL;
655 if(stream == NULL) return ResFAIL; 650 if(stream == NULL) return ResFAIL;
656 651
@@ -808,7 +803,7 @@ size_t mps_mv_free_size(mps_pool_t mps_pool)
808 pool = (Pool)mps_pool; 803 pool = (Pool)mps_pool;
809 804
810 AVERT(Pool, pool); 805 AVERT(Pool, pool);
811 mv = PoolPoolMV(pool); 806 mv = Pool2MV(pool);
812 AVERT(MV, mv); 807 AVERT(MV, mv);
813 808
814 spans = &mv->spans; 809 spans = &mv->spans;
@@ -834,7 +829,7 @@ size_t mps_mv_size(mps_pool_t mps_pool)
834 pool = (Pool)mps_pool; 829 pool = (Pool)mps_pool;
835 830
836 AVERT(Pool, pool); 831 AVERT(Pool, pool);
837 mv = PoolPoolMV(pool); 832 mv = Pool2MV(pool);
838 AVERT(MV, mv); 833 AVERT(MV, mv);
839 arena = PoolArena(pool); 834 arena = PoolArena(pool);
840 835
diff --git a/mps/code/poolmv.h b/mps/code/poolmv.h
index 1ad7607f0ae..bc930c76167 100644
--- a/mps/code/poolmv.h
+++ b/mps/code/poolmv.h
@@ -1,7 +1,8 @@
1/* .impl.h.poolmv: MANUAL VARIABLE POOL 1/* impl.h.poolmv: MANUAL VARIABLE POOL
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 * .purpose: This is the interface to the manual-variable pool class. 7 * .purpose: This is the interface to the manual-variable pool class.
7 * 8 *
@@ -49,8 +50,7 @@ extern PoolClass PoolClassMV(void);
49 50
50extern Bool MVCheck(MV mv); 51extern Bool MVCheck(MV mv);
51 52
52#define MVPool(mv) (&(mv)->poolStruct) 53#define MV2Pool(mv) (&(mv)->poolStruct)
53extern Pool (MVPool)(MV mv);
54 54
55 55
56#endif /* poolmv_h */ 56#endif /* poolmv_h */
diff --git a/mps/code/poolmvff.c b/mps/code/poolmvff.c
index 5706d2db7dd..00f064c1c08 100644
--- a/mps/code/poolmvff.c
+++ b/mps/code/poolmvff.c
@@ -1,7 +1,8 @@
1/* impl.c.poolmvff: First Fit Manual Variable Pool 1/* impl.c.poolmvff: Manual Variable First Fit Pool
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 * .purpose: This is a pool class for manually managed objects of 7 * .purpose: This is a pool class for manually managed objects of
7 * variable size where address-ordered first fit is an appropriate 8 * variable size where address-ordered first fit is an appropriate
@@ -53,8 +54,8 @@ typedef struct MVFFStruct { /* MVFF pool outer structure */
53} MVFFStruct; 54} MVFFStruct;
54 55
55 56
56#define PoolPoolMVFF(pool) PARENT(MVFFStruct, poolStruct, pool) 57#define Pool2MVFF(pool) PARENT(MVFFStruct, poolStruct, pool)
57#define MVFFPool(mvff) (&((mvff)->poolStruct)) 58#define MVFF2Pool(mvff) (&((mvff)->poolStruct))
58#define CBSOfMVFF(mvff) (&((mvff)->cbsStruct)) 59#define CBSOfMVFF(mvff) (&((mvff)->cbsStruct))
59#define MVFFOfCBS(cbs) PARENT(MVFFStruct, cbsStruct, cbs) 60#define MVFFOfCBS(cbs) PARENT(MVFFStruct, cbsStruct, cbs)
60 61
@@ -71,8 +72,8 @@ typedef struct MVFFDebugStruct {
71typedef MVFFDebugStruct *MVFFDebug; 72typedef MVFFDebugStruct *MVFFDebug;
72 73
73 74
74#define MVFFPoolMVFFDebug(mvff) PARENT(MVFFDebugStruct, mvffStruct, mvff) 75#define MVFF2MVFFDebug(mvff) PARENT(MVFFDebugStruct, mvffStruct, mvff)
75#define MVFFDebugPoolMVFF(mvffd) (&((mvffd)->mvffStruct)) 76#define MVFFDebug2MVFF(mvffd) (&((mvffd)->mvffStruct))
76 77
77 78
78/* MVFFAddToFreeList -- Add given range to free list 79/* MVFFAddToFreeList -- Add given range to free list
@@ -126,7 +127,7 @@ static void MVFFFreeSegs(MVFF mvff, Addr base, Addr limit)
126 if (AddrOffset(base, limit) < mvff->minSegSize) 127 if (AddrOffset(base, limit) < mvff->minSegSize)
127 return; /* not large enough for entire segments */ 128 return; /* not large enough for entire segments */
128 129
129 arena = PoolArena(MVFFPool(mvff)); 130 arena = PoolArena(MVFF2Pool(mvff));
130 b = SegOfAddr(&seg, arena, base); 131 b = SegOfAddr(&seg, arena, base);
131 AVER(b); 132 AVER(b);
132 133
@@ -143,13 +144,13 @@ static void MVFFFreeSegs(MVFF mvff, Addr base, Addr limit)
143 mvff->total -= AddrOffset(segBase, segLimit); 144 mvff->total -= AddrOffset(segBase, segLimit);
144 SegFree(seg); 145 SegFree(seg);
145 } 146 }
146 147
147 /* Avoid calling SegNext if the next segment would fail */ 148 /* Avoid calling SegNext if the next segment would fail */
148 /* the loop test, mainly because there might not be a */ 149 /* the loop test, mainly because there might not be a */
149 /* next segment. */ 150 /* next segment. */
150 if (segLimit == limit) /* segment ends at end of range */ 151 if (segLimit == limit) /* segment ends at end of range */
151 break; 152 break;
152 153
153 b = SegNext(&seg, arena, segBase); 154 b = SegNext(&seg, arena, segBase);
154 AVER(b); 155 AVER(b);
155 segBase = SegBase(seg); 156 segBase = SegBase(seg);
@@ -181,7 +182,7 @@ static Res MVFFAddSeg(Seg *segReturn,
181 AVER(size > 0); 182 AVER(size > 0);
182 AVER(BoolCheck(withReservoirPermit)); 183 AVER(BoolCheck(withReservoirPermit));
183 184
184 pool = MVFFPool(mvff); 185 pool = MVFF2Pool(mvff);
185 arena = PoolArena(pool); 186 arena = PoolArena(pool);
186 align = ArenaAlign(arena); 187 align = ArenaAlign(arena);
187 188
@@ -211,6 +212,7 @@ static Res MVFFAddSeg(Seg *segReturn,
211 212
212 mvff->total += segSize; 213 mvff->total += segSize;
213 base = SegBase(seg); limit = AddrAdd(base, segSize); 214 base = SegBase(seg); limit = AddrAdd(base, segSize);
215 DebugPoolFreeSplat(pool, base, limit);
214 MVFFAddToFreeList(&base, &limit, mvff); 216 MVFFAddToFreeList(&base, &limit, mvff);
215 AVER(base <= SegBase(seg)); 217 AVER(base <= SegBase(seg));
216 if (mvff->minSegSize > segSize) mvff->minSegSize = segSize; 218 if (mvff->minSegSize > segSize) mvff->minSegSize = segSize;
@@ -242,7 +244,7 @@ static Bool MVFFFindFirstFree(Addr *baseReturn, Addr *limitReturn,
242 AVER(limitReturn != NULL); 244 AVER(limitReturn != NULL);
243 AVERT(MVFF, mvff); 245 AVERT(MVFF, mvff);
244 AVER(size > 0); 246 AVER(size > 0);
245 AVER(SizeIsAligned(size, PoolAlignment(MVFFPool(mvff)))); 247 AVER(SizeIsAligned(size, PoolAlignment(MVFF2Pool(mvff))));
246 248
247 findDelete = mvff->slotHigh ? CBSFindDeleteHIGH : CBSFindDeleteLOW; 249 findDelete = mvff->slotHigh ? CBSFindDeleteHIGH : CBSFindDeleteLOW;
248 250
@@ -268,7 +270,7 @@ static Res MVFFAlloc(Addr *aReturn, Pool pool, Size size,
268 Bool foundBlock; 270 Bool foundBlock;
269 271
270 AVERT(Pool, pool); 272 AVERT(Pool, pool);
271 mvff = PoolPoolMVFF(pool); 273 mvff = Pool2MVFF(pool);
272 AVERT(MVFF, mvff); 274 AVERT(MVFF, mvff);
273 275
274 AVER(aReturn != NULL); 276 AVER(aReturn != NULL);
@@ -313,7 +315,7 @@ static void MVFFFree(Pool pool, Addr old, Size size)
313 MVFF mvff; 315 MVFF mvff;
314 316
315 AVERT(Pool, pool); 317 AVERT(Pool, pool);
316 mvff = PoolPoolMVFF(pool); 318 mvff = Pool2MVFF(pool);
317 AVERT(MVFF, mvff); 319 AVERT(MVFF, mvff);
318 320
319 AVER(old != (Addr)0); 321 AVER(old != (Addr)0);
@@ -348,7 +350,7 @@ static Res MVFFBufferFill(Addr *baseReturn, Addr *limitReturn,
348 AVER(baseReturn != NULL); 350 AVER(baseReturn != NULL);
349 AVER(limitReturn != NULL); 351 AVER(limitReturn != NULL);
350 AVERT(Pool, pool); 352 AVERT(Pool, pool);
351 mvff = PoolPoolMVFF(pool); 353 mvff = Pool2MVFF(pool);
352 AVERT(MVFF, mvff); 354 AVERT(MVFF, mvff);
353 AVERT(Buffer, buffer); 355 AVERT(Buffer, buffer);
354 AVER(size > 0); 356 AVER(size > 0);
@@ -389,7 +391,7 @@ static void MVFFBufferEmpty(Pool pool, Buffer buffer,
389 MVFF mvff; 391 MVFF mvff;
390 392
391 AVERT(Pool, pool); 393 AVERT(Pool, pool);
392 mvff = PoolPoolMVFF(pool); 394 mvff = Pool2MVFF(pool);
393 AVERT(MVFF, mvff); 395 AVERT(MVFF, mvff);
394 AVERT(Buffer, buffer); 396 AVERT(Buffer, buffer);
395 AVER(BufferIsReady(buffer)); 397 AVER(BufferIsReady(buffer));
@@ -436,7 +438,7 @@ static Res MVFFInit(Pool pool, va_list arg)
436 AVER(BoolCheck(arenaHigh)); 438 AVER(BoolCheck(arenaHigh));
437 AVER(BoolCheck(firstFit)); 439 AVER(BoolCheck(firstFit));
438 440
439 mvff = PoolPoolMVFF(pool); 441 mvff = Pool2MVFF(pool);
440 arena = PoolArena(pool); 442 arena = PoolArena(pool);
441 443
442 mvff->extendBy = extendBy; 444 mvff->extendBy = extendBy;
@@ -452,7 +454,7 @@ static Res MVFFInit(Pool pool, va_list arg)
452 res = ControlAlloc(&p, arena, sizeof(SegPrefStruct), FALSE); 454 res = ControlAlloc(&p, arena, sizeof(SegPrefStruct), FALSE);
453 if (res != ResOK) 455 if (res != ResOK)
454 return res; 456 return res;
455 457
456 mvff->segPref = (SegPref)p; 458 mvff->segPref = (SegPref)p;
457 *mvff->segPref = *SegPrefDefault(); 459 *mvff->segPref = *SegPrefDefault();
458 SegPrefExpress(mvff->segPref, arenaHigh ? SegPrefHigh : SegPrefLow, NULL); 460 SegPrefExpress(mvff->segPref, arenaHigh ? SegPrefHigh : SegPrefLow, NULL);
@@ -463,14 +465,21 @@ static Res MVFFInit(Pool pool, va_list arg)
463 mvff->total = 0; 465 mvff->total = 0;
464 mvff->free = 0; 466 mvff->free = 0;
465 467
466 CBSInit(arena, CBSOfMVFF(mvff), (void *)mvff, NULL, NULL, NULL, NULL, 468 res = CBSInit(arena, CBSOfMVFF(mvff), (void *)mvff, NULL, NULL, NULL, NULL,
467 mvff->extendBy, align, TRUE, TRUE); 469 mvff->extendBy, align, TRUE, TRUE);
470
471 if (res != ResOK)
472 goto failInit;
468 473
469 mvff->sig = MVFFSig; 474 mvff->sig = MVFFSig;
470 AVERT(MVFF, mvff); 475 AVERT(MVFF, mvff);
471 EVENT_PPWWWUUU(PoolInitMVFF, pool, arena, extendBy, avgSize, align, 476 EVENT_PPWWWUUU(PoolInitMVFF, pool, arena, extendBy, avgSize, align,
472 slotHigh, arenaHigh, firstFit); 477 slotHigh, arenaHigh, firstFit);
473 return ResOK; 478 return ResOK;
479
480failInit:
481 ControlFree(arena, p, sizeof(SegPrefStruct));
482 return res;
474} 483}
475 484
476 485
@@ -484,7 +493,7 @@ static void MVFFFinish(Pool pool)
484 Ring ring, node, nextNode; 493 Ring ring, node, nextNode;
485 494
486 AVERT(Pool, pool); 495 AVERT(Pool, pool);
487 mvff = PoolPoolMVFF(pool); 496 mvff = Pool2MVFF(pool);
488 AVERT(MVFF, mvff); 497 AVERT(MVFF, mvff);
489 498
490 ring = PoolSegRing(pool); 499 ring = PoolSegRing(pool);
@@ -493,7 +502,7 @@ static void MVFFFinish(Pool pool)
493 AVER(SegPool(seg) == pool); 502 AVER(SegPool(seg) == pool);
494 SegFree(seg); 503 SegFree(seg);
495 } 504 }
496 505
497 /* Could maintain mvff->total here and check it falls to zero, */ 506 /* Could maintain mvff->total here and check it falls to zero, */
498 /* but that would just make the function slow. If only we had */ 507 /* but that would just make the function slow. If only we had */
499 /* a way to do operations only if AVERs are turned on. */ 508 /* a way to do operations only if AVERs are turned on. */
@@ -514,10 +523,10 @@ static PoolDebugMixin MVFFDebugMixin(Pool pool)
514 MVFF mvff; 523 MVFF mvff;
515 524
516 AVERT(Pool, pool); 525 AVERT(Pool, pool);
517 mvff = PoolPoolMVFF(pool); 526 mvff = Pool2MVFF(pool);
518 AVERT(MVFF, mvff); 527 AVERT(MVFF, mvff);
519 /* Can't check MVFFDebug, because this is called during init */ 528 /* Can't check MVFFDebug, because this is called during init */
520 return &(MVFFPoolMVFFDebug(mvff)->debug); 529 return &(MVFF2MVFFDebug(mvff)->debug);
521} 530}
522 531
523 532
@@ -529,7 +538,7 @@ static Res MVFFDescribe(Pool pool, mps_lib_FILE *stream)
529 MVFF mvff; 538 MVFF mvff;
530 539
531 if (!CHECKT(Pool, pool)) return ResFAIL; 540 if (!CHECKT(Pool, pool)) return ResFAIL;
532 mvff = PoolPoolMVFF(pool); 541 mvff = Pool2MVFF(pool);
533 if (!CHECKT(MVFF, mvff)) return ResFAIL; 542 if (!CHECKT(MVFF, mvff)) return ResFAIL;
534 if (stream == NULL) return ResFAIL; 543 if (stream == NULL) return ResFAIL;
535 544
@@ -551,7 +560,7 @@ static Res MVFFDescribe(Pool pool, mps_lib_FILE *stream)
551 560
552 res = WriteF(stream, "}\n", NULL); 561 res = WriteF(stream, "}\n", NULL);
553 562
554 return res; 563 return res;
555} 564}
556 565
557 566
@@ -613,9 +622,9 @@ size_t mps_mvff_free_size(mps_pool_t mps_pool)
613 622
614 pool = (Pool)mps_pool; 623 pool = (Pool)mps_pool;
615 AVERT(Pool, pool); 624 AVERT(Pool, pool);
616 mvff = PoolPoolMVFF(pool); 625 mvff = Pool2MVFF(pool);
617 AVERT(MVFF, mvff); 626 AVERT(MVFF, mvff);
618 627
619 return (size_t)mvff->free; 628 return (size_t)mvff->free;
620} 629}
621 630
@@ -628,7 +637,7 @@ size_t mps_mvff_size(mps_pool_t mps_pool)
628 637
629 pool = (Pool)mps_pool; 638 pool = (Pool)mps_pool;
630 AVERT(Pool, pool); 639 AVERT(Pool, pool);
631 mvff = PoolPoolMVFF(pool); 640 mvff = Pool2MVFF(pool);
632 AVERT(MVFF, mvff); 641 AVERT(MVFF, mvff);
633 642
634 return (size_t)mvff->total; 643 return (size_t)mvff->total;
@@ -640,16 +649,16 @@ size_t mps_mvff_size(mps_pool_t mps_pool)
640static Bool MVFFCheck(MVFF mvff) 649static Bool MVFFCheck(MVFF mvff)
641{ 650{
642 CHECKS(MVFF, mvff); 651 CHECKS(MVFF, mvff);
643 CHECKD(Pool, MVFFPool(mvff)); 652 CHECKD(Pool, MVFF2Pool(mvff));
644 CHECKL(IsSubclassPoly(MVFFPool(mvff)->class, MVFFPoolClassGet())); 653 CHECKL(IsSubclassPoly(MVFF2Pool(mvff)->class, MVFFPoolClassGet()));
645 CHECKD(SegPref, mvff->segPref); 654 CHECKD(SegPref, mvff->segPref);
646 CHECKL(mvff->extendBy > 0); /* see .arg.check */ 655 CHECKL(mvff->extendBy > 0); /* see .arg.check */
647 CHECKL(mvff->minSegSize >= ArenaAlign(PoolArena(MVFFPool(mvff)))); 656 CHECKL(mvff->minSegSize >= ArenaAlign(PoolArena(MVFF2Pool(mvff))));
648 CHECKL(mvff->avgSize > 0); /* see .arg.check */ 657 CHECKL(mvff->avgSize > 0); /* see .arg.check */
649 CHECKL(mvff->avgSize <= mvff->extendBy); /* see .arg.check */ 658 CHECKL(mvff->avgSize <= mvff->extendBy); /* see .arg.check */
650 CHECKL(mvff->total >= mvff->free); 659 CHECKL(mvff->total >= mvff->free);
651 CHECKL(SizeIsAligned(mvff->free, PoolAlignment(MVFFPool(mvff)))); 660 CHECKL(SizeIsAligned(mvff->free, PoolAlignment(MVFF2Pool(mvff))));
652 CHECKL(SizeIsAligned(mvff->total, ArenaAlign(PoolArena(MVFFPool(mvff))))); 661 CHECKL(SizeIsAligned(mvff->total, ArenaAlign(PoolArena(MVFF2Pool(mvff)))));
653 CHECKD(CBS, CBSOfMVFF(mvff)); 662 CHECKD(CBS, CBSOfMVFF(mvff));
654 CHECKL(BoolCheck(mvff->slotHigh)); 663 CHECKL(BoolCheck(mvff->slotHigh));
655 CHECKL(BoolCheck(mvff->firstFit)); 664 CHECKL(BoolCheck(mvff->firstFit));
@@ -673,7 +682,7 @@ void mps_mvff_stat(mps_pool_t mps_pool)
673 682
674 pool = (Pool)mps_pool; 683 pool = (Pool)mps_pool;
675 AVERT(Pool, pool); 684 AVERT(Pool, pool);
676 mvff = PoolPoolMVFF(pool); 685 mvff = Pool2MVFF(pool);
677 AVERT(MVFF, mvff); 686 AVERT(MVFF, mvff);
678 687
679 METER_EMIT(&CBSOfMVFF(mvff)->splaySearch); 688 METER_EMIT(&CBSOfMVFF(mvff)->splaySearch);
diff --git a/mps/code/poolncv.c b/mps/code/poolncv.c
index 6257a0a9db6..e26caad86b0 100644
--- a/mps/code/poolncv.c
+++ b/mps/code/poolncv.c
@@ -25,7 +25,7 @@ static Bool testit(ArenaClass class, ...)
25 25
26 die(PoolCreate(&pool, arena, PoolClassN()), "PoolNCreate"); 26 die(PoolCreate(&pool, arena, PoolClassN()), "PoolNCreate");
27 res = PoolAlloc(&p, pool, 1, /* withReservoirPermit */ FALSE); 27 res = PoolAlloc(&p, pool, 1, /* withReservoirPermit */ FALSE);
28 if(res == ResOK) { 28 if (res == ResOK) {
29 fprintf(stderr, 29 fprintf(stderr,
30 "Error: Unexpectedly succeeded in" 30 "Error: Unexpectedly succeeded in"
31 "allocating block from PoolN\n"); 31 "allocating block from PoolN\n");
@@ -40,7 +40,7 @@ static Bool testit(ArenaClass class, ...)
40 40
41int main(void) 41int main(void)
42{ 42{
43 if(testit((ArenaClass)mps_arena_class_vm(), (Size)200000)) { 43 if (testit((ArenaClass)mps_arena_class_vm(), (Size)600000)) {
44 fprintf(stderr, "Conclusion: Defects found.\n"); 44 fprintf(stderr, "Conclusion: Defects found.\n");
45 } else { 45 } else {
46 fprintf(stderr, "Conclusion: Failed to find any defects.\n"); 46 fprintf(stderr, "Conclusion: Failed to find any defects.\n");
diff --git a/mps/code/poolsnc.c b/mps/code/poolsnc.c
index a954639f07e..f3e81ca242a 100644
--- a/mps/code/poolsnc.c
+++ b/mps/code/poolsnc.c
@@ -21,7 +21,6 @@
21#include "mpscsnc.h" 21#include "mpscsnc.h"
22#include "mpm.h" 22#include "mpm.h"
23 23
24
25SRCID(poolsnc, "$Id$"); 24SRCID(poolsnc, "$Id$");
26 25
27 26
diff --git a/mps/code/proddw.bat b/mps/code/proddw.bat
deleted file mode 100644
index 9318e5b55c5..00000000000
--- a/mps/code/proddw.bat
+++ /dev/null
@@ -1,41 +0,0 @@
1@rem impl.bat.proddw
2@rem Script that automates building and collating a dylan product
3rem $Id$
4rem Copyright (c) 2001 Ravenbrook Limited.
5nmake /f w3i3mv.nmk VARIETY=ci mmdw.lib mpsplan.lib
6nmake /f w3i3mv.nmk VARIETY=hi mmdw.lib mpsplan.lib
7nmake /f w3i3mv.nmk VARIETY=he mmdw.lib mpsplan.lib
8nmake /f w3i3mv.nmk VARIETY=wi mmdw.lib mpsplan.lib
9rmdir /Q/S dylan
10mkdir dylan
11mkdir dylan\mps
12mkdir dylan\mps\include
13mkdir dylan\mps\lib
14mkdir dylan\mps\lib\w3i3
15mkdir dylan\mps\lib\w3i3\ci
16mkdir dylan\mps\lib\w3i3\hi
17mkdir dylan\mps\lib\w3i3\he
18mkdir dylan\mps\lib\w3i3\wi
19mkdir dylan\mps\src
20copy mps.h dylan\mps\include
21copy mpsavm.h dylan\mps\include
22copy mpscamc.h dylan\mps\include
23copy mpscawl.h dylan\mps\include
24copy mpsclo.h dylan\mps\include
25copy mpscsnc.h dylan\mps\include
26copy mpscmv.h dylan\mps\include
27copy mpsio.h dylan\mps\include
28copy mpslib.h dylan\mps\include
29copy mpstd.h dylan\mps\include
30copy mpsw3.h dylan\mps\include
31copy mpswin.h dylan\mps\include
32copy w3i3mv\ci\mmdw.lib dylan\mps\lib\w3i3\ci
33copy w3i3mv\hi\mmdw.lib dylan\mps\lib\w3i3\hi
34copy w3i3mv\he\mmdw.lib dylan\mps\lib\w3i3\he
35copy w3i3mv\wi\mmdw.lib dylan\mps\lib\w3i3\wi
36copy w3i3mv\ci\mpsplan.lib dylan\mps\lib\w3i3\ci
37copy w3i3mv\hi\mpsplan.lib dylan\mps\lib\w3i3\hi
38copy w3i3mv\he\mpsplan.lib dylan\mps\lib\w3i3\he
39copy w3i3mv\wi\mpsplan.lib dylan\mps\lib\w3i3\wi
40copy mpsliban.c dylan\mps\src
41copy mpsioan.c dylan\mps\src
diff --git a/mps/code/protli.c b/mps/code/protli.c
index c6b283f961c..fa4192dd8b6 100644
--- a/mps/code/protli.c
+++ b/mps/code/protli.c
@@ -2,7 +2,6 @@
2 * 2 *
3 * $Id$ 3 * $Id$
4 * Copyright (c) 2001 Ravenbrook Limited. 4 * Copyright (c) 2001 Ravenbrook Limited.
5 *
6 */ 5 */
7 6
8#include "mpm.h" 7#include "mpm.h"
diff --git a/mps/code/protocol.c b/mps/code/protocol.c
index ead6730c01a..aa83001d7a4 100644
--- a/mps/code/protocol.c
+++ b/mps/code/protocol.c
@@ -10,7 +10,6 @@
10 10
11#include "mpm.h" 11#include "mpm.h"
12 12
13
14SRCID(protocol, "$Id$"); 13SRCID(protocol, "$Id$");
15 14
16 15
diff --git a/mps/code/protso.c b/mps/code/protso.c
index 1628fde99f3..467b0460c7b 100644
--- a/mps/code/protso.c
+++ b/mps/code/protso.c
@@ -2,7 +2,6 @@
2 * 2 *
3 * $Id$ 3 * $Id$
4 * Copyright (c) 2001 Ravenbrook Limited. 4 * Copyright (c) 2001 Ravenbrook Limited.
5 *
6 */ 5 */
7 6
8#include "mpm.h" 7#include "mpm.h"
diff --git a/mps/code/reserv.c b/mps/code/reserv.c
index 72d52241aa9..e8060a43a14 100644
--- a/mps/code/reserv.c
+++ b/mps/code/reserv.c
@@ -347,7 +347,7 @@ void ReservoirSetLimit(Reservoir reservoir, Size size)
347 if (needed > reservoir->reservoirSize) { 347 if (needed > reservoir->reservoirSize) {
348 /* Try to grow the reservoir */ 348 /* Try to grow the reservoir */
349 reservoir->reservoirLimit = needed; 349 reservoir->reservoirLimit = needed;
350 ReservoirEnsureFull(reservoir); 350 (void)ReservoirEnsureFull(reservoir);
351 } else { 351 } else {
352 /* Shrink the reservoir */ 352 /* Shrink the reservoir */
353 reservoirShrink(reservoir, needed); 353 reservoirShrink(reservoir, needed);
@@ -372,7 +372,7 @@ Size ReservoirLimit(Reservoir reservoir)
372Size ReservoirAvailable(Reservoir reservoir) 372Size ReservoirAvailable(Reservoir reservoir)
373{ 373{
374 AVERT(Reservoir, reservoir); 374 AVERT(Reservoir, reservoir);
375 ReservoirEnsureFull(reservoir); 375 (void)ReservoirEnsureFull(reservoir);
376 return reservoir->reservoirSize; 376 return reservoir->reservoirSize;
377} 377}
378 378
diff --git a/mps/code/ring.c b/mps/code/ring.c
index 4bd6e924c21..9eae9aa00bd 100644
--- a/mps/code/ring.c
+++ b/mps/code/ring.c
@@ -16,7 +16,6 @@
16#include "check.h" 16#include "check.h"
17#include "misc.h" 17#include "misc.h"
18 18
19
20SRCID(ring, "$Id$"); 19SRCID(ring, "$Id$");
21 20
22 21
diff --git a/mps/code/ring.h b/mps/code/ring.h
index feb61e5d276..6821355fcd7 100644
--- a/mps/code/ring.h
+++ b/mps/code/ring.h
@@ -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) 2001 Global Graphics Software.
5 */ 6 */
6 7
7 8
@@ -96,7 +97,7 @@ extern Ring (RingNext)(Ring ring);
96 97
97/* .ring.elt: See design.mps.ring.elt */ 98/* .ring.elt: See design.mps.ring.elt */
98#define RING_ELT(type, field, node) \ 99#define RING_ELT(type, field, node) \
99 ((type)((char *)(node) - (size_t)(&((type)0)->field))) 100 ((type)(void *)((char *)(node) - (size_t)(&((type)0)->field)))
100 101
101/* .ring.for: See design.mps.ring.for */ 102/* .ring.for: See design.mps.ring.for */
102#define RING_FOR(node, ring, next) \ 103#define RING_FOR(node, ring, next) \
diff --git a/mps/code/sacss.c b/mps/code/sacss.c
index dda4199bd54..56ed1649565 100644
--- a/mps/code/sacss.c
+++ b/mps/code/sacss.c
@@ -2,9 +2,9 @@
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
8#include "mpscmv.h" 8#include "mpscmv.h"
9#include "mpscmvff.h" 9#include "mpscmvff.h"
10#include "mpslib.h" 10#include "mpslib.h"
@@ -37,6 +37,8 @@ struct itimerspec; /* stop complaints from time.h */
37#define classCOUNT 4 37#define classCOUNT 4
38 38
39 39
40/* make -- allocate an object */
41
40static mps_res_t make(mps_addr_t *p, mps_sac_t sac, size_t size) 42static mps_res_t make(mps_addr_t *p, mps_sac_t sac, size_t size)
41{ 43{
42 mps_res_t res; 44 mps_res_t res;
@@ -46,9 +48,11 @@ static mps_res_t make(mps_addr_t *p, mps_sac_t sac, size_t size)
46} 48}
47 49
48 50
49static mps_res_t stress(mps_class_t class, mps_arena_t arena, 51/* stress -- create a pool of the requested type and allocate in it */
52
53static mps_res_t stress(mps_class_t class,
50 size_t classes_count, mps_sac_classes_s *classes, 54 size_t classes_count, mps_sac_classes_s *classes,
51 size_t (*size)(int i), ...) 55 size_t (*size)(int i), mps_arena_t arena, ...)
52{ 56{
53 mps_res_t res; 57 mps_res_t res;
54 mps_pool_t pool; 58 mps_pool_t pool;
@@ -58,7 +62,7 @@ static mps_res_t stress(mps_class_t class, mps_arena_t arena,
58 int *ps[testSetSIZE]; 62 int *ps[testSetSIZE];
59 size_t ss[testSetSIZE]; 63 size_t ss[testSetSIZE];
60 64
61 va_start(arg, size); 65 va_start(arg, arena);
62 res = mps_pool_create_v(&pool, arena, class, arg); 66 res = mps_pool_create_v(&pool, arena, class, arg);
63 va_end(arg); 67 va_end(arg);
64 if (res != MPS_RES_OK) 68 if (res != MPS_RES_OK)
@@ -129,6 +133,8 @@ static mps_res_t stress(mps_class_t class, mps_arena_t arena,
129#define max(a, b) (((a) > (b)) ? (a) : (b)) 133#define max(a, b) (((a) > (b)) ? (a) : (b))
130 134
131 135
136/* randomSize8 -- produce sizes both latge and small */
137
132static size_t randomSize8(int i) 138static size_t randomSize8(int i)
133{ 139{
134 size_t maxSize = 2 * 160 * 0x2000; 140 size_t maxSize = 2 * 160 * 0x2000;
@@ -140,7 +146,10 @@ static size_t randomSize8(int i)
140} 146}
141 147
142 148
143static mps_pool_debug_option_s debugOptions = { (void *)"postpost", 8 }; 149/* testInArena -- test all the pool classes in the given arena */
150
151static mps_pool_debug_option_s debugOptions =
152 { (void *)"postpost", 8, NULL, 0 };
144 153
145static mps_sac_classes_s classes[4] = { {8, 1, 1}, {16, 1, 2}, {136, 9, 5}, 154static mps_sac_classes_s classes[4] = { {8, 1, 1}, {16, 1, 2}, {136, 9, 5},
146 {topClassSIZE, 9, 4} }; 155 {topClassSIZE, 9, 4} };
@@ -148,15 +157,15 @@ static mps_sac_classes_s classes[4] = { {8, 1, 1}, {16, 1, 2}, {136, 9, 5},
148static int testInArena(mps_arena_t arena) 157static int testInArena(mps_arena_t arena)
149{ 158{
150 printf("MVFF\n\n"); 159 printf("MVFF\n\n");
151 die(stress(mps_class_mvff(), arena, classCOUNT, classes, randomSize8, 160 die(stress(mps_class_mvff(), classCOUNT, classes, randomSize8, arena,
152 (size_t)65536, (size_t)32, (size_t)4, TRUE, TRUE, TRUE), 161 (size_t)65536, (size_t)32, (size_t)4, TRUE, TRUE, TRUE),
153 "stress MVFF"); 162 "stress MVFF");
154 printf("MV debug\n\n"); 163 printf("MV debug\n\n");
155 die(stress(mps_class_mv_debug(), arena, classCOUNT, classes, randomSize8, 164 die(stress(mps_class_mv_debug(), classCOUNT, classes, randomSize8, arena,
156 &debugOptions, (size_t)65536, (size_t)32, (size_t)65536), 165 &debugOptions, (size_t)65536, (size_t)32, (size_t)65536),
157 "stress MV debug"); 166 "stress MV debug");
158 printf("MV\n\n"); 167 printf("MV\n\n");
159 die(stress(mps_class_mv(), arena, classCOUNT, classes, randomSize8, 168 die(stress(mps_class_mv(), classCOUNT, classes, randomSize8, arena,
160 (size_t)65536, (size_t)32, (size_t)65536), 169 (size_t)65536, (size_t)32, (size_t)65536),
161 "stress MV"); 170 "stress MV");
162 return 0; 171 return 0;
diff --git a/mps/code/seg.c b/mps/code/seg.c
index 95e8110bb6d..14839e2a6cb 100644
--- a/mps/code/seg.c
+++ b/mps/code/seg.c
@@ -637,7 +637,7 @@ Bool SegCheck(Seg seg)
637 637
638 /* Each tract of the segment must agree about white traces */ 638 /* Each tract of the segment must agree about white traces */
639 TRACT_TRACT_FOR(tract, addr, arena, seg->firstTract, seg->limit) { 639 TRACT_TRACT_FOR(tract, addr, arena, seg->firstTract, seg->limit) {
640 Seg trseg; 640 Seg trseg = NULL; /* suppress compiler warning */
641 641
642 UNUSED(trseg); /* @@@@ unused in hot varieties */ 642 UNUSED(trseg); /* @@@@ unused in hot varieties */
643 CHECKL(TractCheck(tract)); /* design.mps.check.type.no-sig */ 643 CHECKL(TractCheck(tract)); /* design.mps.check.type.no-sig */
@@ -1241,9 +1241,9 @@ static void gcSegSetWhite(Seg seg, TraceSet white)
1241 limit = SegLimit(seg); 1241 limit = SegLimit(seg);
1242 /* Each tract of the segment records white traces */ 1242 /* Each tract of the segment records white traces */
1243 TRACT_TRACT_FOR(tract, addr, arena, seg->firstTract, limit) { 1243 TRACT_TRACT_FOR(tract, addr, arena, seg->firstTract, limit) {
1244 Seg trseg; 1244 Seg trseg = NULL; /* suppress compiler warning */
1245 1245
1246 UNUSED(trseg); /* @@@@ hack: unused in hot varieties */ 1246 UNUSED(trseg); /* @@@@ unused in hot varieties */
1247 AVER_CRITICAL(TractCheck(tract)); /* design.mps.check.type.no-sig */ 1247 AVER_CRITICAL(TractCheck(tract)); /* design.mps.check.type.no-sig */
1248 AVER_CRITICAL(TRACT_SEG(&trseg, tract) && (trseg == seg)); 1248 AVER_CRITICAL(TRACT_SEG(&trseg, tract) && (trseg == seg));
1249 TractSetWhite(tract, white); 1249 TractSetWhite(tract, white);
diff --git a/mps/code/segsmss.c b/mps/code/segsmss.c
index 590195a193c..bb8222d0738 100644
--- a/mps/code/segsmss.c
+++ b/mps/code/segsmss.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 * .design: Adapted from amsss.c (because AMS already supports 7 * .design: Adapted from amsss.c (because AMS already supports
7 * a protocol for subclassing AMS segments). Defines a new pool 8 * a protocol for subclassing AMS segments). Defines a new pool
@@ -343,7 +344,7 @@ static Res AMSTInit(Pool pool, va_list args)
343 res = ChainCreate(&chain, pool->arena, 1, &genParam); 344 res = ChainCreate(&chain, pool->arena, 1, &genParam);
344 if (res != ResOK) 345 if (res != ResOK)
345 return res; 346 return res;
346 res = AMSInitInternal(Pool2AMS(pool), format, chain); 347 res = AMSInitInternal(Pool2AMS(pool), format, chain, FALSE);
347 if (res != ResOK) 348 if (res != ResOK)
348 return res; 349 return res;
349 amst = Pool2AMST(pool); 350 amst = Pool2AMST(pool);
@@ -704,6 +705,8 @@ static mps_class_t mps_class_amst(void)
704} 705}
705 706
706 707
708/* AMS collection parameters */
709
707#define exactRootsCOUNT 50 710#define exactRootsCOUNT 50
708#define ambigRootsCOUNT 100 711#define ambigRootsCOUNT 100
709#define sizeScale 4 712#define sizeScale 4
@@ -717,6 +720,8 @@ static mps_class_t mps_class_amst(void)
717#define stressTestFREQ 40 720#define stressTestFREQ 40
718 721
719 722
723/* static variables for the test */
724
720static mps_pool_t pool; 725static mps_pool_t pool;
721static mps_ap_t ap; 726static mps_ap_t ap;
722static mps_addr_t exactRoots[exactRootsCOUNT]; 727static mps_addr_t exactRoots[exactRootsCOUNT];
@@ -724,6 +729,8 @@ static mps_addr_t ambigRoots[ambigRootsCOUNT];
724static size_t totalSize = 0; 729static size_t totalSize = 0;
725 730
726 731
732/* make -- object allocation and init */
733
727static mps_addr_t make(void) 734static mps_addr_t make(void)
728{ 735{
729 size_t length = rnd() % 20, size = (length+2) * sizeof(mps_word_t); 736 size_t length = rnd() % 20, size = (length+2) * sizeof(mps_word_t);
@@ -744,6 +751,8 @@ static mps_addr_t make(void)
744} 751}
745 752
746 753
754/* test -- the actual stress test */
755
747static void *test(void *arg, size_t s) 756static void *test(void *arg, size_t s)
748{ 757{
749 mps_arena_t arena; 758 mps_arena_t arena;
diff --git a/mps/code/spi3.asm b/mps/code/spi3.asm
deleted file mode 100644
index b19c5b1d45f..00000000000
--- a/mps/code/spi3.asm
+++ /dev/null
@@ -1,27 +0,0 @@
1; impl.asm.spi3: STACK PROBE
2;
3; $Id$
4; Copyright (c) 2001 Ravenbrook Limited.
5;
6; This function reads a location that is probeDepth words beyond
7; the current stack pointer. On intel platforms the stack grows
8; downwards so this means reading from a location with a lesser address.
9;
10; The registers edi, esi, ebx are the registers defined to be preserved
11; across function calls, so we do not use those.
12
13.386
14.model flat
15.code
16
17_StackProbe proc public ; (Size probeDepth)
18 push ebp ; frame pointer
19 mov ebp,esp
20 mov eax, [ebp+08]
21 neg eax
22 mov eax, [esp+eax*4] ; do the actual probe
23 leave
24 ret ; return
25_StackProbe endp
26
27end
diff --git a/mps/code/spi3.c b/mps/code/spi3.c
new file mode 100644
index 00000000000..72554d3f6ea
--- /dev/null
+++ b/mps/code/spi3.c
@@ -0,0 +1,24 @@
1/* impl.c.spi3: STACK PROBE
2 *
3 * $Id: spi3.c,v 1.2 2002/02/01 13:56:52 pekka Exp $
4 * $HopeName: MMsrc!spi3.c(trunk.2) $
5 * Copyright (c) 2001 Ravenbrook Limited.
6 * Copyright (C) 2001 Global Graphics Software.
7 *
8 * This function reads a location that is probeDepth words beyond
9 * the current stack pointer. On intel platforms the stack grows
10 * downwards so this means reading from a location with a lesser address.
11 */
12
13
14#include "mpm.h"
15
16
17void StackProbe(Size depth)
18{
19 __asm {
20 mov eax, depth
21 neg eax
22 mov eax, [esp+eax*4] /* do the actual probe */
23 }
24}
diff --git a/mps/code/splay.c b/mps/code/splay.c
index 4d30a062de1..ba1057115ba 100644
--- a/mps/code/splay.c
+++ b/mps/code/splay.c
@@ -17,10 +17,11 @@
17#include "splay.h" 17#include "splay.h"
18#include "mpm.h" 18#include "mpm.h"
19 19
20
21SRCID(splay, "$Id$"); 20SRCID(splay, "$Id$");
22 21
22
23/* Basic getter and setter methods */ 23/* Basic getter and setter methods */
24
24#define SplayTreeRoot(t) RVALUE((t)->root) 25#define SplayTreeRoot(t) RVALUE((t)->root)
25#define SplayTreeSetRoot(t, r) BEGIN ((t)->root = (r)); END 26#define SplayTreeSetRoot(t, r) BEGIN ((t)->root = (r)); END
26#define SplayNodeLeftChild(n) RVALUE((n)->left) 27#define SplayNodeLeftChild(n) RVALUE((n)->left)
@@ -30,9 +31,11 @@ SRCID(splay, "$Id$");
30#define SplayNodeSetRightChild(n, child) \ 31#define SplayNodeSetRightChild(n, child) \
31 BEGIN ((n)->right = (child)); END 32 BEGIN ((n)->right = (child)); END
32 33
34
33#define SplayCompare(tree, key, node) \ 35#define SplayCompare(tree, key, node) \
34 (((tree)->compare)((key), (node))) 36 (((tree)->compare)((key), (node)))
35 37
38
36Bool SplayTreeCheck(SplayTree tree) 39Bool SplayTreeCheck(SplayTree tree)
37{ 40{
38 UNUSED(tree); 41 UNUSED(tree);
@@ -42,6 +45,7 @@ Bool SplayTreeCheck(SplayTree tree)
42 return TRUE; 45 return TRUE;
43} 46}
44 47
48
45Bool SplayNodeCheck(SplayNode node) 49Bool SplayNodeCheck(SplayNode node)
46{ 50{
47 UNUSED(node); 51 UNUSED(node);
@@ -64,6 +68,7 @@ void SplayTreeInit(SplayTree tree, SplayCompareMethod compare,
64 AVERT(SplayTree, tree); 68 AVERT(SplayTree, tree);
65} 69}
66 70
71
67void SplayNodeInit(SplayNode node) 72void SplayNodeInit(SplayNode node)
68{ 73{
69 AVER(node != NULL); 74 AVER(node != NULL);
@@ -75,6 +80,7 @@ void SplayNodeInit(SplayNode node)
75 AVERT(SplayNode, node); 80 AVERT(SplayNode, node);
76} 81}
77 82
83
78void SplayNodeFinish(SplayNode node) 84void SplayNodeFinish(SplayNode node)
79{ 85{
80 AVERT(SplayNode, node); 86 AVERT(SplayNode, node);
@@ -84,6 +90,7 @@ void SplayNodeFinish(SplayNode node)
84 SplayNodeSetRightChild(node, NULL); 90 SplayNodeSetRightChild(node, NULL);
85} 91}
86 92
93
87void SplayTreeFinish(SplayTree tree) 94void SplayTreeFinish(SplayTree tree)
88{ 95{
89 AVERT(SplayTree, tree); 96 AVERT(SplayTree, tree);
@@ -91,6 +98,7 @@ void SplayTreeFinish(SplayTree tree)
91 tree->compare = NULL; 98 tree->compare = NULL;
92} 99}
93 100
101
94static void SplayNodeUpdate(SplayTree tree, SplayNode node) 102static void SplayNodeUpdate(SplayTree tree, SplayNode node)
95{ 103{
96 AVERT(SplayTree, tree); 104 AVERT(SplayTree, tree);
@@ -130,6 +138,7 @@ static void SplayLinkRight(SplayNode *topIO, SplayNode *rightIO)
130 SplayNodeSetLeftChild(*rightIO, NULL); 138 SplayNodeSetLeftChild(*rightIO, NULL);
131} 139}
132 140
141
133/* SplayLinkLeft -- Move top to right child of top 142/* SplayLinkLeft -- Move top to right child of top
134 * 143 *
135 * Link the current top node into the right child of the left tree, 144 * Link the current top node into the right child of the left tree,
@@ -156,6 +165,7 @@ static void SplayLinkLeft(SplayNode *topIO, SplayNode *leftIO) {
156 SplayNodeSetRightChild(*leftIO, NULL); 165 SplayNodeSetRightChild(*leftIO, NULL);
157} 166}
158 167
168
159/* SplayRotateLeft -- Rotate right child edge of node 169/* SplayRotateLeft -- Rotate right child edge of node
160 * 170 *
161 * Rotates node, right child of node, and left child of right 171 * Rotates node, right child of node, and left child of right
@@ -177,7 +187,7 @@ static void SplayRotateLeft(SplayNode *nodeIO, SplayTree tree) {
177 SplayNodeSetLeftChild(nodeRight, *nodeIO); 187 SplayNodeSetLeftChild(nodeRight, *nodeIO);
178 *nodeIO = nodeRight; 188 *nodeIO = nodeRight;
179 189
180 if(tree->updateNode != NULL) { 190 if (tree->updateNode != NULL) {
181 SplayNodeUpdate(tree, SplayNodeLeftChild(nodeRight)); 191 SplayNodeUpdate(tree, SplayNodeLeftChild(nodeRight));
182 /* Don't need to update new root because we know that we will */ 192 /* Don't need to update new root because we know that we will */
183 /* do either a link or an assemble next, and that will sort it */ 193 /* do either a link or an assemble next, and that will sort it */
@@ -187,6 +197,7 @@ static void SplayRotateLeft(SplayNode *nodeIO, SplayTree tree) {
187 return; 197 return;
188} 198}
189 199
200
190/* SplayRotateRight -- Rotate left child edge of node 201/* SplayRotateRight -- Rotate left child edge of node
191 * 202 *
192 * Rotates node, left child of node, and right child of left 203 * Rotates node, left child of node, and right child of left
@@ -208,7 +219,7 @@ static void SplayRotateRight(SplayNode *nodeIO, SplayTree tree) {
208 SplayNodeSetRightChild(nodeLeft, *nodeIO); 219 SplayNodeSetRightChild(nodeLeft, *nodeIO);
209 *nodeIO = nodeLeft; 220 *nodeIO = nodeLeft;
210 221
211 if(tree->updateNode != NULL) { 222 if (tree->updateNode != NULL) {
212 SplayNodeUpdate(tree, SplayNodeRightChild(nodeLeft)); 223 SplayNodeUpdate(tree, SplayNodeRightChild(nodeLeft));
213 /* Don't need to update new root because we know that we will */ 224 /* Don't need to update new root because we know that we will */
214 /* do either a link or an assemble next, and that will sort it */ 225 /* do either a link or an assemble next, and that will sort it */
@@ -218,6 +229,7 @@ static void SplayRotateRight(SplayNode *nodeIO, SplayTree tree) {
218 return; 229 return;
219} 230}
220 231
232
221/* SplayAssemble -- Assemble left right and top trees into one 233/* SplayAssemble -- Assemble left right and top trees into one
222 * 234 *
223 * We do this by moving the children of the top tree to the last and 235 * We do this by moving the children of the top tree to the last and
@@ -241,11 +253,11 @@ static void SplayAssemble(SplayTree tree, SplayNode top,
241 AVER(rightTop == NULL || 253 AVER(rightTop == NULL ||
242 (SplayNodeCheck(rightTop) && SplayNodeCheck(rightFirst))); 254 (SplayNodeCheck(rightTop) && SplayNodeCheck(rightFirst)));
243 255
244 if(leftTop != NULL) { 256 if (leftTop != NULL) {
245 SplayNodeSetRightChild(leftLast, SplayNodeLeftChild(top)); 257 SplayNodeSetRightChild(leftLast, SplayNodeLeftChild(top));
246 SplayNodeSetLeftChild(top, leftTop); 258 SplayNodeSetLeftChild(top, leftTop);
247 259
248 if(tree->updateNode != NULL) { 260 if (tree->updateNode != NULL) {
249 /* Update client property using pointer reversal (Ugh!). */ 261 /* Update client property using pointer reversal (Ugh!). */
250 SplayNode node, parent, rightChild; 262 SplayNode node, parent, rightChild;
251 263
@@ -274,11 +286,11 @@ static void SplayAssemble(SplayTree tree, SplayNode top,
274 } 286 }
275 /* otherwise leave top->left alone */ 287 /* otherwise leave top->left alone */
276 288
277 if(rightTop != NULL) { 289 if (rightTop != NULL) {
278 SplayNodeSetLeftChild(rightFirst, SplayNodeRightChild(top)); 290 SplayNodeSetLeftChild(rightFirst, SplayNodeRightChild(top));
279 SplayNodeSetRightChild(top, rightTop); 291 SplayNodeSetRightChild(top, rightTop);
280 292
281 if(tree->updateNode != NULL) { 293 if (tree->updateNode != NULL) {
282 /* Update client property using pointer reversal (Ugh!). */ 294 /* Update client property using pointer reversal (Ugh!). */
283 SplayNode node, parent, leftChild; 295 SplayNode node, parent, leftChild;
284 296
@@ -307,10 +319,11 @@ static void SplayAssemble(SplayTree tree, SplayNode top,
307 } 319 }
308 /* otherwise leave top->right alone */ 320 /* otherwise leave top->right alone */
309 321
310 if(tree->updateNode != NULL) 322 if (tree->updateNode != NULL)
311 SplayNodeUpdate(tree, top); 323 SplayNodeUpdate(tree, top);
312} 324}
313 325
326
314/* SplaySplay -- Splay the tree (top-down) around a given key 327/* SplaySplay -- Splay the tree (top-down) around a given key
315 * 328 *
316 * If the key is not found, splays around an arbitrary neighbour. 329 * If the key is not found, splays around an arbitrary neighbour.
@@ -324,7 +337,7 @@ static Bool SplaySplay(SplayNode *nodeReturn, SplayTree tree,
324 void *key, SplayCompareMethod compareMethod) { 337 void *key, SplayCompareMethod compareMethod) {
325 /* The sides structure avoids a boundary case in SplayLink* */ 338 /* The sides structure avoids a boundary case in SplayLink* */
326 SplayNodeStruct sides; /* rightTop and leftTop */ 339 SplayNodeStruct sides; /* rightTop and leftTop */
327 SplayNode top, leftLast, rightFirst; 340 SplayNode top, leftLast, rightFirst;
328 Bool found; 341 Bool found;
329 Compare compareTop; 342 Compare compareTop;
330 343
@@ -334,14 +347,14 @@ static Bool SplaySplay(SplayNode *nodeReturn, SplayTree tree,
334 347
335 top = SplayTreeRoot(tree); /* will be copied back at end */ 348 top = SplayTreeRoot(tree); /* will be copied back at end */
336 349
337 if(top == NULL) { 350 if (top == NULL) {
338 *nodeReturn = NULL; 351 *nodeReturn = NULL;
339 return FALSE; 352 return FALSE;
340 } 353 }
341 354
342 /* short-circuit case where node is already top */ 355 /* short-circuit case where node is already top */
343 compareTop = (*compareMethod)(key, top); 356 compareTop = (*compareMethod)(key, top);
344 if(compareTop == CompareEQUAL) { 357 if (compareTop == CompareEQUAL) {
345 *nodeReturn = top; 358 *nodeReturn = top;
346 return TRUE; 359 return TRUE;
347 } 360 }
@@ -356,7 +369,7 @@ static Bool SplaySplay(SplayNode *nodeReturn, SplayTree tree,
356 369
357 case CompareLESS: { 370 case CompareLESS: {
358 SplayNode topLeft = SplayNodeLeftChild(top); 371 SplayNode topLeft = SplayNodeLeftChild(top);
359 if(topLeft == NULL) { 372 if (topLeft == NULL) {
360 found = FALSE; 373 found = FALSE;
361 goto assemble; 374 goto assemble;
362 } else { 375 } else {
@@ -371,14 +384,14 @@ static Bool SplaySplay(SplayNode *nodeReturn, SplayTree tree,
371 } /* break; */ 384 } /* break; */
372 385
373 case CompareLESS: { /* zig-zig */ 386 case CompareLESS: { /* zig-zig */
374 if(SplayNodeLeftChild(topLeft) == NULL) 387 if (SplayNodeLeftChild(topLeft) == NULL)
375 goto terminalZig; 388 goto terminalZig;
376 SplayRotateRight(&top, tree); 389 SplayRotateRight(&top, tree);
377 SplayLinkRight(&top, &rightFirst); 390 SplayLinkRight(&top, &rightFirst);
378 } break; 391 } break;
379 392
380 case CompareGREATER: { /* zig-zag */ 393 case CompareGREATER: { /* zig-zag */
381 if(SplayNodeRightChild(topLeft) == NULL) 394 if (SplayNodeRightChild(topLeft) == NULL)
382 goto terminalZig; 395 goto terminalZig;
383 SplayLinkRight(&top, &rightFirst); 396 SplayLinkRight(&top, &rightFirst);
384 SplayLinkLeft(&top, &leftLast); 397 SplayLinkLeft(&top, &leftLast);
@@ -393,7 +406,7 @@ static Bool SplaySplay(SplayNode *nodeReturn, SplayTree tree,
393 406
394 case CompareGREATER: { 407 case CompareGREATER: {
395 SplayNode topRight = SplayNodeRightChild(top); 408 SplayNode topRight = SplayNodeRightChild(top);
396 if(topRight == NULL) { 409 if (topRight == NULL) {
397 found = FALSE; 410 found = FALSE;
398 goto assemble; 411 goto assemble;
399 } else { 412 } else {
@@ -408,14 +421,14 @@ static Bool SplaySplay(SplayNode *nodeReturn, SplayTree tree,
408 } /* break; */ 421 } /* break; */
409 422
410 case CompareGREATER: { /* zag-zag */ 423 case CompareGREATER: { /* zag-zag */
411 if(SplayNodeRightChild(topRight) == NULL) 424 if (SplayNodeRightChild(topRight) == NULL)
412 goto terminalZag; 425 goto terminalZag;
413 SplayRotateLeft(&top, tree); 426 SplayRotateLeft(&top, tree);
414 SplayLinkLeft(&top, &leftLast); 427 SplayLinkLeft(&top, &leftLast);
415 } break; 428 } break;
416 429
417 case CompareLESS: { /* zag-zig */ 430 case CompareLESS: { /* zag-zig */
418 if(SplayNodeLeftChild(topRight) == NULL) 431 if (SplayNodeLeftChild(topRight) == NULL)
419 goto terminalZag; 432 goto terminalZag;
420 SplayLinkLeft(&top, &leftLast); 433 SplayLinkLeft(&top, &leftLast);
421 SplayLinkRight(&top, &rightFirst); 434 SplayLinkRight(&top, &rightFirst);
@@ -439,7 +452,7 @@ static Bool SplaySplay(SplayNode *nodeReturn, SplayTree tree,
439 } 452 }
440 compareTop = (*compareMethod)(key, top); 453 compareTop = (*compareMethod)(key, top);
441 } /* end while(TRUE) */ 454 } /* end while(TRUE) */
442 455
443terminalZig: 456terminalZig:
444 SplayLinkRight(&top, &rightFirst); 457 SplayLinkRight(&top, &rightFirst);
445 found = FALSE; 458 found = FALSE;
@@ -476,9 +489,9 @@ Res SplayTreeInsert(SplayTree tree, SplayNode node, void *key) {
476 AVER(SplayNodeLeftChild(node) == NULL); 489 AVER(SplayNodeLeftChild(node) == NULL);
477 AVER(SplayNodeRightChild(node) == NULL); 490 AVER(SplayNodeRightChild(node) == NULL);
478 491
479 if(SplayTreeRoot(tree) == NULL) { 492 if (SplayTreeRoot(tree) == NULL) {
480 SplayTreeSetRoot(tree, node); 493 SplayTreeSetRoot(tree, node);
481 } else if(SplaySplay(&neighbour, tree, key, tree->compare)) { 494 } else if (SplaySplay(&neighbour, tree, key, tree->compare)) {
482 return ResFAIL; 495 return ResFAIL;
483 } else { 496 } else {
484 AVER(SplayTreeRoot(tree) == neighbour); 497 AVER(SplayTreeRoot(tree) == neighbour);
@@ -504,7 +517,7 @@ Res SplayTreeInsert(SplayTree tree, SplayNode node, void *key) {
504 } break; 517 } break;
505 } 518 }
506 519
507 if(tree->updateNode != NULL) { 520 if (tree->updateNode != NULL) {
508 SplayNodeUpdate(tree, neighbour); 521 SplayNodeUpdate(tree, neighbour);
509 SplayNodeUpdate(tree, node); 522 SplayNodeUpdate(tree, node);
510 } 523 }
@@ -530,21 +543,21 @@ Res SplayTreeDelete(SplayTree tree, SplayNode node, void *key) {
530 found = SplaySplay(&del, tree, key, tree->compare); 543 found = SplaySplay(&del, tree, key, tree->compare);
531 AVER(!found || del == node); 544 AVER(!found || del == node);
532 545
533 if(!found) { 546 if (!found) {
534 return ResFAIL; 547 return ResFAIL;
535 } else if(SplayNodeLeftChild(node) == NULL) { 548 } else if (SplayNodeLeftChild(node) == NULL) {
536 SplayTreeSetRoot(tree, SplayNodeRightChild(node)); 549 SplayTreeSetRoot(tree, SplayNodeRightChild(node));
537 } else if(SplayNodeRightChild(node) == NULL) { 550 } else if (SplayNodeRightChild(node) == NULL) {
538 SplayTreeSetRoot(tree, SplayNodeLeftChild(node)); 551 SplayTreeSetRoot(tree, SplayNodeLeftChild(node));
539 } else { 552 } else {
540 rightHalf = SplayNodeRightChild(node); 553 rightHalf = SplayNodeRightChild(node);
541 SplayTreeSetRoot(tree, SplayNodeLeftChild(node)); 554 SplayTreeSetRoot(tree, SplayNodeLeftChild(node));
542 if(SplaySplay(&leftLast, tree, key, tree->compare)) { 555 if (SplaySplay(&leftLast, tree, key, tree->compare)) {
543 return ResFAIL; 556 return ResFAIL;
544 } else { 557 } else {
545 AVER(SplayNodeRightChild(leftLast) == NULL); 558 AVER(SplayNodeRightChild(leftLast) == NULL);
546 SplayNodeSetRightChild(leftLast, rightHalf); 559 SplayNodeSetRightChild(leftLast, rightHalf);
547 if(tree->updateNode != NULL) { 560 if (tree->updateNode != NULL) {
548 SplayNodeUpdate(tree, leftLast); 561 SplayNodeUpdate(tree, leftLast);
549 } 562 }
550 } 563 }
@@ -562,14 +575,13 @@ Res SplayTreeDelete(SplayTree tree, SplayNode node, void *key) {
562 * design.mps.splay.impl.search. 575 * design.mps.splay.impl.search.
563 */ 576 */
564 577
565
566Res SplayTreeSearch(SplayNode *nodeReturn, SplayTree tree, void *key) { 578Res SplayTreeSearch(SplayNode *nodeReturn, SplayTree tree, void *key) {
567 SplayNode node; 579 SplayNode node;
568 580
569 AVERT(SplayTree, tree); 581 AVERT(SplayTree, tree);
570 AVER(nodeReturn != NULL); 582 AVER(nodeReturn != NULL);
571 583
572 if(SplaySplay(&node, tree, key, tree->compare)) { 584 if (SplaySplay(&node, tree, key, tree->compare)) {
573 *nodeReturn = node; 585 *nodeReturn = node;
574 } else { 586 } else {
575 return ResFAIL; 587 return ResFAIL;
@@ -593,20 +605,20 @@ static SplayNode SplayTreePredecessor(SplayTree tree, void *key) {
593 oldRoot = SplayTreeRoot(tree); 605 oldRoot = SplayTreeRoot(tree);
594 AVERT(SplayNode, oldRoot); 606 AVERT(SplayNode, oldRoot);
595 607
596 if(SplayNodeLeftChild(oldRoot) == NULL) { 608 if (SplayNodeLeftChild(oldRoot) == NULL) {
597 newRoot = NULL; /* No predecessor */ 609 newRoot = NULL; /* No predecessor */
598 } else { 610 } else {
599 /* temporarily chop off the right half-tree, inclusive of root */ 611 /* temporarily chop off the right half-tree, inclusive of root */
600 SplayTreeSetRoot(tree, SplayNodeLeftChild(oldRoot)); 612 SplayTreeSetRoot(tree, SplayNodeLeftChild(oldRoot));
601 SplayNodeSetLeftChild(oldRoot, NULL); 613 SplayNodeSetLeftChild(oldRoot, NULL);
602 if(SplaySplay(&newRoot, tree, key, tree->compare)) { 614 if (SplaySplay(&newRoot, tree, key, tree->compare)) {
603 NOTREACHED; /* Another matching node found */ 615 NOTREACHED; /* Another matching node found */
604 } else { 616 } else {
605 AVER(SplayNodeRightChild(newRoot) == NULL); 617 AVER(SplayNodeRightChild(newRoot) == NULL);
606 SplayNodeSetRightChild(newRoot, oldRoot); 618 SplayNodeSetRightChild(newRoot, oldRoot);
607 } 619 }
608 620
609 if(tree->updateNode != NULL) { 621 if (tree->updateNode != NULL) {
610 SplayNodeUpdate(tree, oldRoot); 622 SplayNodeUpdate(tree, oldRoot);
611 SplayNodeUpdate(tree, newRoot); 623 SplayNodeUpdate(tree, newRoot);
612 } 624 }
@@ -630,20 +642,20 @@ static SplayNode SplayTreeSuccessor(SplayTree tree, void *key) {
630 oldRoot = SplayTreeRoot(tree); 642 oldRoot = SplayTreeRoot(tree);
631 AVERT(SplayNode, oldRoot); 643 AVERT(SplayNode, oldRoot);
632 644
633 if(SplayNodeRightChild(oldRoot) == NULL) { 645 if (SplayNodeRightChild(oldRoot) == NULL) {
634 newRoot = NULL; /* No successor */ 646 newRoot = NULL; /* No successor */
635 } else { 647 } else {
636 /* temporarily chop off the left half-tree, inclusive of root */ 648 /* temporarily chop off the left half-tree, inclusive of root */
637 SplayTreeSetRoot(tree, SplayNodeRightChild(oldRoot)); 649 SplayTreeSetRoot(tree, SplayNodeRightChild(oldRoot));
638 SplayNodeSetRightChild(oldRoot, NULL); 650 SplayNodeSetRightChild(oldRoot, NULL);
639 if(SplaySplay(&newRoot, tree, key, tree->compare)) { 651 if (SplaySplay(&newRoot, tree, key, tree->compare)) {
640 NOTREACHED; /* Another matching node found */ 652 NOTREACHED; /* Another matching node found */
641 } else { 653 } else {
642 AVER(SplayNodeLeftChild(newRoot) == NULL); 654 AVER(SplayNodeLeftChild(newRoot) == NULL);
643 SplayNodeSetLeftChild(newRoot, oldRoot); 655 SplayNodeSetLeftChild(newRoot, oldRoot);
644 } 656 }
645 657
646 if(tree->updateNode != NULL) { 658 if (tree->updateNode != NULL) {
647 SplayNodeUpdate(tree, oldRoot); 659 SplayNodeUpdate(tree, oldRoot);
648 SplayNodeUpdate(tree, newRoot); 660 SplayNodeUpdate(tree, newRoot);
649 } 661 }
@@ -670,9 +682,9 @@ Res SplayTreeNeighbours(SplayNode *leftReturn, SplayNode *rightReturn,
670 AVER(leftReturn != NULL); 682 AVER(leftReturn != NULL);
671 AVER(rightReturn != NULL); 683 AVER(rightReturn != NULL);
672 684
673 if(SplaySplay(&neighbour, tree, key, tree->compare)) { 685 if (SplaySplay(&neighbour, tree, key, tree->compare)) {
674 return ResFAIL; 686 return ResFAIL;
675 } else if(neighbour == NULL) { 687 } else if (neighbour == NULL) {
676 *leftReturn = *rightReturn = NULL; 688 *leftReturn = *rightReturn = NULL;
677 } else { 689 } else {
678 switch(SplayCompare(tree, key, neighbour)) { 690 switch(SplayCompare(tree, key, neighbour)) {
@@ -700,7 +712,7 @@ Res SplayTreeNeighbours(SplayNode *leftReturn, SplayNode *rightReturn,
700/* SplayTreeFirst, SplayTreeNext -- Iterators 712/* SplayTreeFirst, SplayTreeNext -- Iterators
701 * 713 *
702 * SplayTreeFirst receives a key that must precede all 714 * SplayTreeFirst receives a key that must precede all
703 * nodes in the tree. It returns NULL if the tree is empty. 715 * nodes in the tree. It returns NULL if the tree is empty.
704 * Otherwise, it splays the tree to the first node, and returns the 716 * Otherwise, it splays the tree to the first node, and returns the
705 * new root. See design.mps.splay.function.splay.tree.first. 717 * new root. See design.mps.splay.function.splay.tree.first.
706 * 718 *
@@ -714,9 +726,9 @@ SplayNode SplayTreeFirst(SplayTree tree, void *zeroKey) {
714 SplayNode node; 726 SplayNode node;
715 AVERT(SplayTree, tree); 727 AVERT(SplayTree, tree);
716 728
717 if(SplayTreeRoot(tree) == NULL) { 729 if (SplayTreeRoot(tree) == NULL) {
718 node = NULL; 730 node = NULL;
719 } else if(SplaySplay(&node, tree, zeroKey, tree->compare)) { 731 } else if (SplaySplay(&node, tree, zeroKey, tree->compare)) {
720 NOTREACHED; 732 NOTREACHED;
721 } else { 733 } else {
722 AVER(SplayNodeLeftChild(node) == NULL); 734 AVER(SplayNodeLeftChild(node) == NULL);
@@ -751,44 +763,40 @@ static Res SplayNodeDescribe(SplayNode node, mps_lib_FILE *stream,
751 SplayNodeDescribeMethod nodeDescribe) { 763 SplayNodeDescribeMethod nodeDescribe) {
752 Res res; 764 Res res;
753 765
754 AVERT(SplayNode, node); 766#if defined(CHECK)
767 if (!SplayNodeCheck(node)) return ResFAIL;
755 /* stream and nodeDescribe checked by SplayTreeDescribe */ 768 /* stream and nodeDescribe checked by SplayTreeDescribe */
769#endif
756 770
757 res = WriteF(stream, "( ", NULL); 771 res = WriteF(stream, "( ", NULL);
758 if(res != ResOK) 772 if (res != ResOK) return res;
759 return res;
760 773
761 if(SplayNodeLeftChild(node) != NULL) { 774 if (SplayNodeLeftChild(node) != NULL) {
762 res = SplayNodeDescribe(SplayNodeLeftChild(node), stream, nodeDescribe); 775 res = SplayNodeDescribe(SplayNodeLeftChild(node), stream, nodeDescribe);
763 if(res != ResOK) 776 if (res != ResOK) return res;
764 return res;
765 777
766 res = WriteF(stream, " / ", NULL); 778 res = WriteF(stream, " / ", NULL);
767 if(res != ResOK) 779 if (res != ResOK) return res;
768 return res;
769 } 780 }
770 781
771 res = (*nodeDescribe)(node, stream); 782 res = (*nodeDescribe)(node, stream);
772 if(res != ResOK) 783 if (res != ResOK) return res;
773 return res;
774 784
775 if(SplayNodeRightChild(node) != NULL) { 785 if (SplayNodeRightChild(node) != NULL) {
776 res = WriteF(stream, " \\ ", NULL); 786 res = WriteF(stream, " \\ ", NULL);
777 if(res != ResOK) 787 if (res != ResOK) return res;
778 return res;
779 788
780 res = SplayNodeDescribe(SplayNodeRightChild(node), stream, nodeDescribe); 789 res = SplayNodeDescribe(SplayNodeRightChild(node), stream, nodeDescribe);
781 if(res != ResOK) 790 if (res != ResOK) return res;
782 return res;
783 } 791 }
784 792
785 res = WriteF(stream, " )", NULL); 793 res = WriteF(stream, " )", NULL);
786 if(res != ResOK) 794 if (res != ResOK) return res;
787 return res;
788 795
789 return ResOK; 796 return ResOK;
790} 797}
791 798
799
792typedef struct { 800typedef struct {
793 SplayTestNodeMethod testNode; 801 SplayTestNodeMethod testNode;
794 SplayTestTreeMethod testTree; 802 SplayTestTreeMethod testTree;
@@ -816,10 +824,10 @@ static Compare SplayFindFirstCompare(void *key, SplayNode node)
816 testTree = closure->testTree; 824 testTree = closure->testTree;
817 tree = closure->tree; 825 tree = closure->tree;
818 826
819 if(SplayNodeLeftChild(node) != NULL && 827 if (SplayNodeLeftChild(node) != NULL &&
820 (*testTree)(tree, SplayNodeLeftChild(node), closureP, closureS)) { 828 (*testTree)(tree, SplayNodeLeftChild(node), closureP, closureS)) {
821 return CompareLESS; 829 return CompareLESS;
822 } else if((*testNode)(tree, node, closureP, closureS)) { 830 } else if ((*testNode)(tree, node, closureP, closureS)) {
823 return CompareEQUAL; 831 return CompareEQUAL;
824 } else { 832 } else {
825 AVER(SplayNodeRightChild(node) != NULL && 833 AVER(SplayNodeRightChild(node) != NULL &&
@@ -847,10 +855,10 @@ static Compare SplayFindLastCompare(void *key, SplayNode node)
847 testTree = closure->testTree; 855 testTree = closure->testTree;
848 tree = closure->tree; 856 tree = closure->tree;
849 857
850 if(SplayNodeRightChild(node) != NULL && 858 if (SplayNodeRightChild(node) != NULL &&
851 (*testTree)(tree, SplayNodeRightChild(node), closureP, closureS)) { 859 (*testTree)(tree, SplayNodeRightChild(node), closureP, closureS)) {
852 return CompareGREATER; 860 return CompareGREATER;
853 } else if((*testNode)(tree, node, closureP, closureS)) { 861 } else if ((*testNode)(tree, node, closureP, closureS)) {
854 return CompareEQUAL; 862 return CompareEQUAL;
855 } else { 863 } else {
856 AVER(SplayNodeLeftChild(node) != NULL && 864 AVER(SplayNodeLeftChild(node) != NULL &&
@@ -887,7 +895,7 @@ Bool SplayFindFirst(SplayNode *nodeReturn, SplayTree tree,
887 895
888 node = SplayTreeRoot(tree); 896 node = SplayTreeRoot(tree);
889 897
890 if(node == NULL || !(*testTree)(tree, node, closureP, closureS)) 898 if (node == NULL || !(*testTree)(tree, node, closureP, closureS))
891 return FALSE; /* no suitable nodes in tree */ 899 return FALSE; /* no suitable nodes in tree */
892 900
893 closureStruct.p = closureP; 901 closureStruct.p = closureP;
@@ -896,8 +904,8 @@ Bool SplayFindFirst(SplayNode *nodeReturn, SplayTree tree,
896 closureStruct.testTree = testTree; 904 closureStruct.testTree = testTree;
897 closureStruct.tree = tree; 905 closureStruct.tree = tree;
898 906
899 if(SplaySplay(&node, tree, (void *)&closureStruct, 907 if (SplaySplay(&node, tree, (void *)&closureStruct,
900 &SplayFindFirstCompare)) { 908 &SplayFindFirstCompare)) {
901 *nodeReturn = node; 909 *nodeReturn = node;
902 return TRUE; 910 return TRUE;
903 } else { 911 } else {
@@ -923,7 +931,7 @@ Bool SplayFindLast(SplayNode *nodeReturn, SplayTree tree,
923 931
924 node = SplayTreeRoot(tree); 932 node = SplayTreeRoot(tree);
925 933
926 if(node == NULL || !(*testTree)(tree, node, closureP, closureS)) 934 if (node == NULL || !(*testTree)(tree, node, closureP, closureS))
927 return FALSE; /* no suitable nodes in tree */ 935 return FALSE; /* no suitable nodes in tree */
928 936
929 closureStruct.p = closureP; 937 closureStruct.p = closureP;
@@ -932,8 +940,8 @@ Bool SplayFindLast(SplayNode *nodeReturn, SplayTree tree,
932 closureStruct.testTree = testTree; 940 closureStruct.testTree = testTree;
933 closureStruct.tree = tree; 941 closureStruct.tree = tree;
934 942
935 if(SplaySplay(&node, tree, (void *)&closureStruct, 943 if (SplaySplay(&node, tree, (void *)&closureStruct,
936 &SplayFindLastCompare)) { 944 &SplayFindLastCompare)) {
937 *nodeReturn = node; 945 *nodeReturn = node;
938 return TRUE; 946 return TRUE;
939 } else { 947 } else {
@@ -952,7 +960,7 @@ Bool SplayRoot(SplayNode *nodeReturn, SplayTree tree)
952 AVERT(SplayTree, tree); 960 AVERT(SplayTree, tree);
953 961
954 node = SplayTreeRoot(tree); 962 node = SplayTreeRoot(tree);
955 if(node == NULL) 963 if (node == NULL)
956 return FALSE; 964 return FALSE;
957 else { 965 else {
958 *nodeReturn = node; 966 *nodeReturn = node;
@@ -997,21 +1005,21 @@ Res SplayTreeDescribe(SplayTree tree, mps_lib_FILE *stream,
997 SplayNodeDescribeMethod nodeDescribe) { 1005 SplayNodeDescribeMethod nodeDescribe) {
998 Res res; 1006 Res res;
999 1007
1000 if(!SplayTreeCheck(tree)) return ResFAIL; 1008#if defined(CHECK)
1001 if(stream == NULL) return ResFAIL; 1009 if (!SplayTreeCheck(tree)) return ResFAIL;
1002 if(!FUNCHECK(nodeDescribe)) return ResFAIL; 1010 if (stream == NULL) return ResFAIL;
1011 if (!FUNCHECK(nodeDescribe)) return ResFAIL;
1012#endif
1003 1013
1004 res = WriteF(stream, 1014 res = WriteF(stream,
1005 "Splay $P {\n", (WriteFP)tree, 1015 "Splay $P {\n", (WriteFP)tree,
1006 " compare $F\n", (WriteFF)tree->compare, 1016 " compare $F\n", (WriteFF)tree->compare,
1007 NULL); 1017 NULL);
1008 if(res != ResOK) 1018 if (res != ResOK) return res;
1009 return res;
1010 1019
1011 if(SplayTreeRoot(tree) != NULL) { 1020 if (SplayTreeRoot(tree) != NULL) {
1012 res = SplayNodeDescribe(SplayTreeRoot(tree), stream, nodeDescribe); 1021 res = SplayNodeDescribe(SplayTreeRoot(tree), stream, nodeDescribe);
1013 if(res != ResOK) 1022 if (res != ResOK) return res;
1014 return res;
1015 } 1023 }
1016 1024
1017 res = WriteF(stream, "\n}\n", NULL); 1025 res = WriteF(stream, "\n}\n", NULL);
diff --git a/mps/code/ss.h b/mps/code/ss.h
index 9b30efcb46a..84d9719c43b 100644
--- a/mps/code/ss.h
+++ b/mps/code/ss.h
@@ -1,5 +1,4 @@
1/* impl.h.ss 1/* impl.h.ss: STACK SCANNING
2 * STACK SCANNING
3 * 2 *
4 * $Id$ 3 * $Id$
5 * 4 *
diff --git a/mps/code/sslii3.c b/mps/code/sslii3.c
index c9c12c13119..7219ab33c20 100644
--- a/mps/code/sslii3.c
+++ b/mps/code/sslii3.c
@@ -34,6 +34,7 @@
34 34
35SRCID(sslii3, "$Id$"); 35SRCID(sslii3, "$Id$");
36 36
37
37/* .assume.asm.order */ 38/* .assume.asm.order */
38#define ASMV(x) __asm__ volatile (x) 39#define ASMV(x) __asm__ volatile (x)
39 40
diff --git a/mps/code/sssos8.s b/mps/code/sssos8.s
index 7457635b09e..73c86b6f3c0 100644
--- a/mps/code/sssos8.s
+++ b/mps/code/sssos8.s
@@ -1,6 +1,5 @@
1! impl.s.sssos8 1! impl.s.sssos8: STACK SCANNING
2! 2!
3! STACK SCANNING
4! 3!
5! $Id$ 4! $Id$
6! 5!
diff --git a/mps/code/sssus8.c b/mps/code/sssus8.c
new file mode 100644
index 00000000000..a53d5c779e9
--- /dev/null
+++ b/mps/code/sssus8.c
@@ -0,0 +1,63 @@
1/* impl.c.sssus8: SPARC STACK SCANNING
2 *
3 * $HopeName: MMsrc!sssus8.c(trunk.1) $
4 * $Id: sssus8.c,v 1.1 2002/02/15 19:12:02 pekka Exp $
5 * Copyright (c) 2001 Ravenbrook Limited.
6 * Copyright (c) 2002 Global Graphics Software.
7 *
8 * This scans the stack and fixes the registers which may contain
9 * roots. See design.mps.thread-manager.
10 *
11 * .roots: The non-global registers are preserved into the stackframe
12 * by the "ta 3" instruction. This leaves the global registers.
13 * According to the Sparc Architecture Manual:
14 * %g1 is assumed to be volatile across procedure calls
15 * %g2...%g4 are "reserved for use by application programmer"
16 * %g5...%g7 are "nonvolatile and reserved for (as-yet-undefined)
17 * use by the execution environment"
18 * To be safe %g2 to %g7 are pushed onto the stack before scanning
19 * it just in case.
20 *
21 * ASSUMPTIONS
22 *
23 * .assume.align: The stack pointer is assumed to be aligned on a word
24 * boundary.
25 *
26 * .assume.asm.stack: The compiler must not do wacky things with the
27 * stack pointer around a call since we need to ensure that the
28 * callee-save regs are visible during TraceScanArea.
29 *
30 * .assume.asm.order: The volatile modifier should prevent movement
31 * of code, which might break .assume.asm.stack.
32 */
33
34#include "mpm.h"
35#include <alloca.h>
36
37SRCID(sssus8, "$Id: sssus8.c,v 1.1 2002/02/15 19:12:02 pekka Exp $");
38
39
40/* .assume.asm.order */
41#define ASMV(x) __asm__ volatile (x)
42
43
44Res StackScan(ScanState ss, Addr *stackBot)
45{
46 Addr *stackTop;
47 Res res;
48 void *globals;
49
50 /* We expect C will save the caller's window, but we don't really care, */
51 /* because it's bound to be an MPS window. */
52 globals = alloca(24); /* for 6 globals */
53 ASMV("std %%g2, [%0]" : : "r" (globals)); /* double stores */
54 ASMV("std %%g4, [%0 + 8]" : : "r" (globals));
55 ASMV("std %%g6, [%0 + 16]" : : "r" (globals));
56 ASMV("ta 3"); /* flushes register windows onto stack */
57 ASMV("mov %%sp, %0" : "=r" (stackTop)); /* stackTop = sp */
58
59 AVER(AddrIsAligned((Addr)stackTop, sizeof(Addr))); /* .assume.align */
60 res = TraceScanArea(ss, stackTop, stackBot);
61
62 return res;
63}
diff --git a/mps/code/sssus8.s b/mps/code/sssus8.s
index a20d9225552..198b491ad02 100644
--- a/mps/code/sssus8.s
+++ b/mps/code/sssus8.s
@@ -1,6 +1,4 @@
1! impl.s.sssus8 1! impl.s.sssus8: STACK SCANNING
2!
3! STACK SCANNING
4! 2!
5! $Id$ 3! $Id$
6! 4!
diff --git a/mps/code/sus8lc.gmk b/mps/code/sus8lc.gmk
deleted file mode 100644
index 215046b2f94..00000000000
--- a/mps/code/sus8lc.gmk
+++ /dev/null
@@ -1,14 +0,0 @@
1# impl.gmk.sus8lc: BUILD FOR SUNOS/SPARC V8/LCC PLATFORM
2#
3# $Id$
4# Copyright (c) 2001 Ravenbrook Limited.
5#
6# This is the GNU makefile for platform.sus8lc.
7
8PFM = sus8lc
9
10MPMPF = mpsliban.c mpsioan.c lockan.c than.c vmsu.c \
11 protsu.c prmcan.c span.c
12MPMS = sssus8.s
13
14include lc.gmk
diff --git a/mps/code/teletest.c b/mps/code/teletest.c
index 3d39e9a186e..cc8c38992bf 100644
--- a/mps/code/teletest.c
+++ b/mps/code/teletest.c
@@ -13,7 +13,6 @@
13 13
14#include <stdlib.h> 14#include <stdlib.h>
15 15
16
17SRCID(teletest, "$Id$"); 16SRCID(teletest, "$Id$");
18 17
19 18
diff --git a/mps/code/testlib.c b/mps/code/testlib.c
index c59d3fa717a..e747e2cc7f4 100644
--- a/mps/code/testlib.c
+++ b/mps/code/testlib.c
@@ -2,15 +2,17 @@
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 * .purpose: A library of functions that may be of use to unit tests. 7 * .purpose: A library of functions that may be of use to unit tests.
7 */ 8 */
8 9
9#include "testlib.h" 10#include "testlib.h"
10#include "mps.h" 11#include "mps.h"
11#include "mpm.h" 12#include "misc.h" /* for NOOP */
12#include <math.h> 13#include <math.h>
13#include <stdlib.h> 14#include <stdlib.h>
15#include <limits.h>
14#ifdef MPS_OS_IA 16#ifdef MPS_OS_IA
15struct itimerspec; /* stop complaints from time.h */ 17struct itimerspec; /* stop complaints from time.h */
16#endif 18#endif
@@ -19,16 +21,16 @@ struct itimerspec; /* stop complaints from time.h */
19 21
20/* rnd -- a random number generator 22/* rnd -- a random number generator
21 * 23 *
22 * I nabbed it from "ML for the Working Programmer" 24 * I nabbed it from "ML for the Working Programmer", originally from:
23 * Originally from:
24 * Stephen K Park & Keith W Miller (1988). Random number generators: 25 * Stephen K Park & Keith W Miller (1988). Random number generators:
25 * good one are to find. Communications of the ACM, 31:1192-1201 26 * good one are to find. Communications of the ACM, 31:1192-1201.
26 */ 27 */
27 28
28unsigned long rnd(void) 29unsigned long rnd(void)
29{ 30{
30 static unsigned long seed = 1; 31 static unsigned long seed = 1;
31 double s; 32 double s;
33
32 s = seed; 34 s = seed;
33 s *= 16807.0; 35 s *= 16807.0;
34 s = fmod(s, 2147483647.0); /* 2^31 - 1 */ 36 s = fmod(s, 2147483647.0); /* 2^31 - 1 */
@@ -37,13 +39,32 @@ unsigned long rnd(void)
37} 39}
38 40
39 41
42/* rnd_addr -- a random address generator
43 *
44 * rnd gives 31 random bits, we run it repeatedly to get enough bits.
45 */
46
47#define ADDR_BITS (sizeof(mps_addr_t) * CHAR_BIT)
48
49mps_addr_t rnd_addr(void)
50{
51 mps_word_t res;
52 unsigned bits;
53
54 for (bits = 0, res = 0; bits < ADDR_BITS;
55 bits += 31, res = res << 31 | (mps_word_t)rnd())
56 NOOP;
57 return (mps_addr_t)res;
58}
59
60
40/* randomize -- randomize the generator, or initialize to replay */ 61/* randomize -- randomize the generator, or initialize to replay */
41 62
42void randomize(int argc, char **argv) 63void randomize(int argc, char **argv)
43{ 64{
44 int i, k, n; 65 int i, k, n;
45 66
46 if(argc > 1) { 67 if (argc > 1) {
47 n = sscanf(argv[1], "%d", &k); 68 n = sscanf(argv[1], "%d", &k);
48 die((n == 1) ? MPS_RES_OK : MPS_RES_FAIL, "randomize"); 69 die((n == 1) ? MPS_RES_OK : MPS_RES_FAIL, "randomize");
49 } else { 70 } else {
diff --git a/mps/code/testlib.h b/mps/code/testlib.h
index 6245ef46a2c..3a461be8505 100644
--- a/mps/code/testlib.h
+++ b/mps/code/testlib.h
@@ -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 * .purpose: A library of functions that may be of use to unit tests. 7 * .purpose: A library of functions that may be of use to unit tests.
7 */ 8 */
@@ -14,6 +15,9 @@
14 15
15/* Include system header hackery. */ 16/* Include system header hackery. */
16#include "mpstd.h" 17#include "mpstd.h"
18#ifdef MPS_OS_W3
19#include "mpswin.h"
20#endif
17#ifdef MPS_OS_SU 21#ifdef MPS_OS_SU
18#include "ossu.h" 22#include "ossu.h"
19#endif 23#endif
@@ -52,12 +56,12 @@
52#pragma warning(disable: 4701) 56#pragma warning(disable: 4701)
53#endif 57#endif
54 58
55/* In white-hot versions, absolutely no checking is done. This leads to 59
56 * many spurious warnings because parameters are suddenly unused, etc. 60/* Non-checking varieties give many spurious warnings because parameters
57 * We aren't interested in these. 61 * are suddenly unused, etc. We aren't interested in these.
58 */ 62 */
59 63
60#if defined(CONFIG_VAR_WI) 64#if defined(CHECK_NONE)
61 65
62/* "unreferenced formal parameter" */ 66/* "unreferenced formal parameter" */
63#pragma warning(disable: 4100) 67#pragma warning(disable: 4100)
@@ -140,6 +144,14 @@ extern void verror(const char *format, va_list args);
140extern unsigned long rnd(void); 144extern unsigned long rnd(void);
141 145
142 146
147/* rnd_addr -- random number generator
148 *
149 * rnd_addr() generates a sequence of addresses all over the address space.
150 */
151
152extern mps_addr_t rnd_addr(void);
153
154
143/* randomize -- randomize the generator, or initialize to replay 155/* randomize -- randomize the generator, or initialize to replay
144 * 156 *
145 * randomize(argc, argv) randomizes the rnd generator (using time(3)) 157 * randomize(argc, argv) randomizes the rnd generator (using time(3))
diff --git a/mps/code/trace.c b/mps/code/trace.c
index 44acc32b0df..5012d3ce027 100644
--- a/mps/code/trace.c
+++ b/mps/code/trace.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 * .design: design.mps.trace. */ 7 * .design: design.mps.trace. */
7 8
@@ -1543,7 +1544,9 @@ Bool TracePoll(Globals globals)
1543 1544
1544 res = TraceCreate(&trace, arena); 1545 res = TraceCreate(&trace, arena);
1545 AVER(res == ResOK); /* succeeds because no other trace is busy */ 1546 AVER(res == ResOK); /* succeeds because no other trace is busy */
1546 traceCondemnAll(trace); 1547 res = traceCondemnAll(trace);
1548 if (res != ResOK) /* should try some other trace, really @@@@ */
1549 goto failCondemn;
1547 finishingTime = ArenaAvail(arena) 1550 finishingTime = ArenaAvail(arena)
1548 - trace->condemned * (1.0 - TraceTopGenMortality); 1551 - trace->condemned * (1.0 - TraceTopGenMortality);
1549 if (finishingTime < 0) 1552 if (finishingTime < 0)
@@ -1574,7 +1577,7 @@ Bool TracePoll(Globals globals)
1574 res = TraceCreate(&trace, arena); 1577 res = TraceCreate(&trace, arena);
1575 AVER(res == ResOK); 1578 AVER(res == ResOK);
1576 res = ChainCondemnAuto(&mortality, firstChain, trace); 1579 res = ChainCondemnAuto(&mortality, firstChain, trace);
1577 if (res != ResOK) 1580 if (res != ResOK) /* should try some other trace, really @@@@ */
1578 goto failCondemn; 1581 goto failCondemn;
1579 trace->chain = firstChain; 1582 trace->chain = firstChain;
1580 ChainStartGC(firstChain, trace); 1583 ChainStartGC(firstChain, trace);
diff --git a/mps/code/tract.c b/mps/code/tract.c
index 546f68803b4..3f697e41800 100644
--- a/mps/code/tract.c
+++ b/mps/code/tract.c
@@ -11,6 +11,7 @@
11 11
12#include "tract.h" 12#include "tract.h"
13#include "boot.h" 13#include "boot.h"
14#include "bt.h"
14#include "mpm.h" 15#include "mpm.h"
15 16
16SRCID(tract, "$Id$"); 17SRCID(tract, "$Id$");
diff --git a/mps/code/tract.h b/mps/code/tract.h
index 92db6991721..aa525825098 100644
--- a/mps/code/tract.h
+++ b/mps/code/tract.h
@@ -10,6 +10,7 @@
10 10
11#include "mpmtypes.h" 11#include "mpmtypes.h"
12#include "ring.h" 12#include "ring.h"
13#include "bt.h"
13 14
14 15
15/* TractStruct -- tract structure 16/* TractStruct -- tract structure
@@ -231,11 +232,11 @@ extern Index IndexOfAddr(Chunk chunk, Addr addr);
231 AddrAdd((chunk)->base, ChunkPagesToSize(chunk, i)) 232 AddrAdd((chunk)->base, ChunkPagesToSize(chunk, i))
232 233
233 234
234/* TractIsContiguousRange -- do base and limit define a contiguous range */ 235/* TractAverContiguousRange -- verify that range is contiguous */
235 236
236#define AverTractIsContiguousRange(arena, rangeBase, rangeLimit) \ 237#define TractAverContiguousRange(arena, rangeBase, rangeLimit) \
237 BEGIN \ 238 BEGIN \
238 Chunk _ch; \ 239 Chunk _ch = NULL; \
239 \ 240 \
240 UNUSED(_ch); \ 241 UNUSED(_ch); \
241 AVER(ChunkOfAddr(&_ch, arena, rangeBase) && (rangeLimit) <= _ch->limit); \ 242 AVER(ChunkOfAddr(&_ch, arena, rangeBase) && (rangeLimit) <= _ch->limit); \
@@ -255,7 +256,7 @@ extern Bool TractNext(Tract *tractReturn, Arena arena, Addr addr);
255 256
256#define TRACT_TRACT_FOR(tract, addr, arena, firstTract, limit) \ 257#define TRACT_TRACT_FOR(tract, addr, arena, firstTract, limit) \
257 tract = (firstTract); addr = TractBase(tract); \ 258 tract = (firstTract); addr = TractBase(tract); \
258 AverTractIsContiguousRange(arena, addr, limit); \ 259 TractAverContiguousRange(arena, addr, limit); \
259 for(; tract != NULL; \ 260 for(; tract != NULL; \
260 (addr = AddrAdd(addr, (arena)->alignment)), \ 261 (addr = AddrAdd(addr, (arena)->alignment)), \
261 (addr < (limit) ? \ 262 (addr < (limit) ? \
diff --git a/mps/code/version.c b/mps/code/version.c
index 066d157cdc7..963c5ebad6e 100644
--- a/mps/code/version.c
+++ b/mps/code/version.c
@@ -10,14 +10,12 @@
10 * 10 *
11 * DESIGN 11 * DESIGN
12 * 12 *
13 * .design: See design.mps.version-library, but to let you in on a 13 * .design: See design.mps.version-library, but - to let you in on a
14 * secret it works by declaring a string with all the necessary info 14 * secret - it works by declaring a string with all the necessary info
15 * in. 15 * in. */
16 */
17 16
18#include "mpm.h" 17#include "mpm.h"
19 18
20
21SRCID(version, "$Id$"); 19SRCID(version, "$Id$");
22 20
23 21
@@ -28,7 +26,7 @@ SRCID(version, "$Id$");
28 * whatever. 26 * whatever.
29 */ 27 */
30 28
31#define MPS_RELEASE "$Id$ *** DEVELOPMENT ONLY ***" 29#define MPS_RELEASE "release.epcore.chub"
32 30
33 31
34/* MPSCopyrightNotice -- copyright notice for the binary 32/* MPSCopyrightNotice -- copyright notice for the binary
@@ -38,7 +36,7 @@ SRCID(version, "$Id$");
38 */ 36 */
39 37
40char MPSCopyrightNotice[] = 38char MPSCopyrightNotice[] =
41 "Copyright (c) 2001 Ravenbrook Limited."; 39 "Copyright (c) 2002 Ravenbrook Limited and Global Graphics Software.";
42 40
43 41
44/* MPSVersion -- return version string 42/* MPSVersion -- return version string
diff --git a/mps/code/vman.c b/mps/code/vman.c
index 1d3959d0aee..a92d4bef7b4 100644
--- a/mps/code/vman.c
+++ b/mps/code/vman.c
@@ -195,7 +195,7 @@ void VMUnmap(VM vm, Addr base, Addr limit)
195 AVER(AddrIsAligned(limit, VMANPageALIGNMENT)); 195 AVER(AddrIsAligned(limit, VMANPageALIGNMENT));
196 196
197 size = AddrOffset(base, limit); 197 size = AddrOffset(base, limit);
198 memset((void *)base, VM_JUNKBYTE, size); 198 memset((void *)base, 0xCD, size);
199 199
200 AVER(vm->mapped >= size); 200 AVER(vm->mapped >= size);
201 vm->mapped -= size; 201 vm->mapped -= size;
diff --git a/mps/code/vmso.c b/mps/code/vmso.c
index 68e6e2131a5..3c205eb9599 100644
--- a/mps/code/vmso.c
+++ b/mps/code/vmso.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 * DESIGN 7 * DESIGN
7 * 8 *
@@ -44,6 +45,7 @@
44 45
45/* Open sesame magic */ 46/* Open sesame magic */
46#define _POSIX_SOURCE 47#define _POSIX_SOURCE
48#define _XOPEN_SOURCE 500
47 49
48#include <sys/types.h> 50#include <sys/types.h>
49#include <sys/mman.h> 51#include <sys/mman.h>
@@ -56,12 +58,6 @@
56SRCID(vmso, "$Id$"); 58SRCID(vmso, "$Id$");
57 59
58 60
59/* Fix up unprototyped system calls. */
60
61extern int close(int fd);
62extern int munmap(caddr_t addr, size_t len);
63
64
65/* VMStruct -- virtual memory structure */ 61/* VMStruct -- virtual memory structure */
66 62
67#define VMSig ((Sig)0x519B3999) /* SIGnature VM */ 63#define VMSig ((Sig)0x519B3999) /* SIGnature VM */
@@ -78,6 +74,8 @@ typedef struct VMStruct {
78} VMStruct; 74} VMStruct;
79 75
80 76
77/* VMAlign -- return the page size */
78
81Align VMAlign(VM vm) 79Align VMAlign(VM vm)
82{ 80{
83 AVERT(VM, vm); 81 AVERT(VM, vm);
@@ -85,6 +83,8 @@ Align VMAlign(VM vm)
85} 83}
86 84
87 85
86/* VMCheck -- check a VM structure */
87
88Bool VMCheck(VM vm) 88Bool VMCheck(VM vm)
89{ 89{
90 CHECKS(VM, vm); 90 CHECKS(VM, vm);
@@ -102,9 +102,11 @@ Bool VMCheck(VM vm)
102} 102}
103 103
104 104
105/* VMCreate -- reserve some virtual address space, and create a VM structure */
106
105Res VMCreate(VM *vmReturn, Size size) 107Res VMCreate(VM *vmReturn, Size size)
106{ 108{
107 caddr_t addr; 109 void *addr;
108 Align align; 110 Align align;
109 int zero_fd; 111 int zero_fd;
110 int none_fd; 112 int none_fd;
@@ -137,7 +139,7 @@ Res VMCreate(VM *vmReturn, Size size)
137 } 139 }
138 140
139 /* Map in a page to store the descriptor on. */ 141 /* Map in a page to store the descriptor on. */
140 addr = mmap((caddr_t)0, (size_t)SizeAlignUp(sizeof(VMStruct), align), 142 addr = mmap((void *)0, (size_t)SizeAlignUp(sizeof(VMStruct), align),
141 PROT_READ | PROT_WRITE, MAP_PRIVATE, 143 PROT_READ | PROT_WRITE, MAP_PRIVATE,
142 zero_fd, (off_t)0); 144 zero_fd, (off_t)0);
143 if(addr == MAP_FAILED) { 145 if(addr == MAP_FAILED) {
@@ -152,7 +154,7 @@ Res VMCreate(VM *vmReturn, Size size)
152 vm->align = align; 154 vm->align = align;
153 155
154 /* .map.reserve: See .assume.not-last. */ 156 /* .map.reserve: See .assume.not-last. */
155 addr = mmap((caddr_t)0, (size_t)size, PROT_NONE, MAP_SHARED, 157 addr = mmap((void *)0, (size_t)size, PROT_NONE, MAP_SHARED,
156 none_fd, (off_t)0); 158 none_fd, (off_t)0);
157 if(addr == MAP_FAILED) { 159 if(addr == MAP_FAILED) {
158 AVER(errno == ENOMEM); /* .assume.mmap.err */ 160 AVER(errno == ENOMEM); /* .assume.mmap.err */
@@ -175,7 +177,7 @@ Res VMCreate(VM *vmReturn, Size size)
175 return ResOK; 177 return ResOK;
176 178
177failReserve: 179failReserve:
178 (void)munmap((caddr_t)vm, (size_t)SizeAlignUp(sizeof(VMStruct), align)); 180 (void)munmap((void *)vm, (size_t)SizeAlignUp(sizeof(VMStruct), align));
179failVMMap: 181failVMMap:
180 (void)close(none_fd); /* see .close.fail */ 182 (void)close(none_fd); /* see .close.fail */
181failNoneOpen: 183failNoneOpen:
@@ -184,6 +186,8 @@ failNoneOpen:
184} 186}
185 187
186 188
189/* VMDestroy -- destroy the VM structure */
190
187void VMDestroy(VM vm) 191void VMDestroy(VM vm)
188{ 192{
189 int r; 193 int r;
@@ -199,9 +203,9 @@ void VMDestroy(VM vm)
199 vm->sig = SigInvalid; 203 vm->sig = SigInvalid;
200 204
201 zero_fd = vm->zero_fd; none_fd = vm->none_fd; 205 zero_fd = vm->zero_fd; none_fd = vm->none_fd;
202 r = munmap((caddr_t)vm->base, (size_t)AddrOffset(vm->base, vm->limit)); 206 r = munmap((void *)vm->base, (size_t)AddrOffset(vm->base, vm->limit));
203 AVER(r == 0); 207 AVER(r == 0);
204 r = munmap((caddr_t)vm, 208 r = munmap((void *)vm,
205 (size_t)SizeAlignUp(sizeof(VMStruct), vm->align)); 209 (size_t)SizeAlignUp(sizeof(VMStruct), vm->align));
206 AVER(r == 0); 210 AVER(r == 0);
207 /* .close.fail: We ignore failure from close() as there's very */ 211 /* .close.fail: We ignore failure from close() as there's very */
@@ -213,12 +217,17 @@ void VMDestroy(VM vm)
213} 217}
214 218
215 219
220/* VMBase -- return the base address of the memory reserved */
221
216Addr VMBase(VM vm) 222Addr VMBase(VM vm)
217{ 223{
218 AVERT(VM, vm); 224 AVERT(VM, vm);
219 return vm->base; 225 return vm->base;
220} 226}
221 227
228
229/* VMLimit -- return the limit address of the memory reserved */
230
222Addr VMLimit(VM vm) 231Addr VMLimit(VM vm)
223{ 232{
224 AVERT(VM, vm); 233 AVERT(VM, vm);
@@ -226,12 +235,17 @@ Addr VMLimit(VM vm)
226} 235}
227 236
228 237
238/* VMReserved -- return the amount of address space reserved */
239
229Size VMReserved(VM vm) 240Size VMReserved(VM vm)
230{ 241{
231 AVERT(VM, vm); 242 AVERT(VM, vm);
232 return vm->reserved; 243 return vm->reserved;
233} 244}
234 245
246
247/* VMMapped -- return the amount of memory actually mapped */
248
235Size VMMapped(VM vm) 249Size VMMapped(VM vm)
236{ 250{
237 AVERT(VM, vm); 251 AVERT(VM, vm);
@@ -239,10 +253,12 @@ Size VMMapped(VM vm)
239} 253}
240 254
241 255
256/* VMMap -- map the given range of memory */
257
242Res VMMap(VM vm, Addr base, Addr limit) 258Res VMMap(VM vm, Addr base, Addr limit)
243{ 259{
244 Size size; 260 Size size;
245 caddr_t addr; 261 void *addr;
246 262
247 AVERT(VM, vm); 263 AVERT(VM, vm);
248 AVER(base < limit); 264 AVER(base < limit);
@@ -258,7 +274,7 @@ Res VMMap(VM vm, Addr base, Addr limit)
258 /* Check it won't lose any bits. */ 274 /* Check it won't lose any bits. */
259 AVER(size <= (Size)(size_t)-1); 275 AVER(size <= (Size)(size_t)-1);
260 276
261 addr = mmap((caddr_t)base, (size_t)size, 277 addr = mmap((void *)base, (size_t)size,
262 PROT_READ | PROT_WRITE | PROT_EXEC, 278 PROT_READ | PROT_WRITE | PROT_EXEC,
263 MAP_PRIVATE | MAP_FIXED, 279 MAP_PRIVATE | MAP_FIXED,
264 vm->zero_fd, (off_t)0); 280 vm->zero_fd, (off_t)0);
@@ -266,7 +282,7 @@ Res VMMap(VM vm, Addr base, Addr limit)
266 AVER(errno == EAGAIN); /* .assume.mmap.err */ 282 AVER(errno == EAGAIN); /* .assume.mmap.err */
267 return ResMEMORY; 283 return ResMEMORY;
268 } 284 }
269 AVER(addr == (caddr_t)base); 285 AVER(addr == (void *)base);
270 286
271 vm->mapped += size; 287 vm->mapped += size;
272 288
@@ -275,10 +291,12 @@ Res VMMap(VM vm, Addr base, Addr limit)
275} 291}
276 292
277 293
294/* VMUnmap -- unmap the given range of memory */
295
278void VMUnmap(VM vm, Addr base, Addr limit) 296void VMUnmap(VM vm, Addr base, Addr limit)
279{ 297{
280 Size size; 298 Size size;
281 caddr_t addr; 299 void *addr;
282 300
283 AVERT(VM, vm); 301 AVERT(VM, vm);
284 AVER(base < limit); 302 AVER(base < limit);
@@ -296,10 +314,10 @@ void VMUnmap(VM vm, Addr base, Addr limit)
296 size = AddrOffset(base, limit); 314 size = AddrOffset(base, limit);
297 /* Check it won't lose any bits. */ 315 /* Check it won't lose any bits. */
298 AVER(size <= (Size)(size_t)-1); 316 AVER(size <= (Size)(size_t)-1);
299 addr = mmap((caddr_t)base, (size_t)size, 317 addr = mmap((void *)base, (size_t)size,
300 PROT_NONE, MAP_SHARED | MAP_FIXED, 318 PROT_NONE, MAP_SHARED | MAP_FIXED,
301 vm->none_fd, (off_t)AddrOffset(vm->base, base)); 319 vm->none_fd, (off_t)AddrOffset(vm->base, base));
302 AVER(addr == (caddr_t)base); 320 AVER(addr == (void *)base);
303 321
304 vm->mapped -= size; 322 vm->mapped -= size;
305 323
diff --git a/mps/code/w3almv.nmk b/mps/code/w3almv.nmk
index e045ead0a60..f20180c31da 100644
--- a/mps/code/w3almv.nmk
+++ b/mps/code/w3almv.nmk
@@ -10,29 +10,29 @@ DONGLELIB = $(RAINBOWPATH)\spromeps.lib
10 10
11PFMDEFS = /DWIN32 /D_WINDOWS /I$(RAINBOWPATH) 11PFMDEFS = /DWIN32 /D_WINDOWS /I$(RAINBOWPATH)
12 12
13MPM = <assert> <ring> <mpm> <bt> <protocol> <boot> \ 13MPM = <ring> <mpm> <bt> <protocol> <boot> \
14 <arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \ 14 <arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \
15 <pool> <poolabs> <poolmfs> <poolmv> \ 15 <pool> <poolabs> <poolmfs> <poolmv> \
16 <root> <format> <buffer> <walk> <lockw3> \ 16 <root> <format> <buffer> <walk> <lockw3> \
17 <ref> <trace> <protw3> <prmcan> <shield> <vmw3> \ 17 <ref> <trace> <protw3> <prmcan> <shield> <vmw3> \
18 <than> <ssan> <mpsi> <mpsiw3> <ld> <span> \ 18 <than> <ssan> <mpsi> <mpsiw3> <ld> <span> \
19 <event> <action> <seg> <sac> <poolmrg> <message> <dbgpool> \ 19 <event> <seg> <sac> <poolmrg> <message> <dbgpool> <dbgpooli> \
20 <ref> <trace> <protw3> <prmcan> <shield> \ 20 <ref> <trace> <protw3> <prmcan> <shield> \
21 <than> <ssan> <mpsi> <mpsiw3> <ld> <vmw3> \ 21 <than> <ssan> <mpsi> <mpsiw3> <ld> <vmw3> \
22 <event> <action> <seg> <poolmrg> <message> <span> \ 22 <event> <seg> <poolmrg> <message> <span> \
23 <abq> <meter> <cbs> <poolmv2> <splay> <version> <poolmvff> 23 <abq> <meter> <cbs> <poolmv2> <splay> <version> <poolmvff>
24SW = <assert> <ring> <mpm> <bt> <protocol> \ 24SW = <ring> <mpm> <bt> <protocol> \
25 <arenavm> <arenacl> <arena> <tract> <walk> <reserv> \ 25 <arenavm> <arenacl> <arena> <tract> <walk> <reserv> \
26 <pool> <poolabs> <poolmfs> \ 26 <pool> <poolabs> <poolmfs> \
27 <poolmv> <root> <format> <buffer> \ 27 <poolmv> <root> <format> <buffer> \
28 <ref> <trace> <protsw> <prmcan> <shield> <vmw3> \ 28 <ref> <trace> <protsw> <prmcan> <shield> <vmw3> \
29 <than> <ssan> <mpsi> <ld> \ 29 <than> <ssan> <mpsi> <ld> \
30 <event> <action> <seg> <sac> <poolmrg> <message> <mpsioan> \ 30 <event> <seg> <sac> <poolmrg> <message> <mpsioan> \
31 <poolepdl> <poolepvm> <poolams> <dbgpool> \ 31 <poolams> <poolamsi> <dbgpool> <dbgpooli> \
32 <abq> <meter> <cbs> <poolmv2> <splay> <version> <poolmvff> 32 <abq> <meter> <cbs> <poolmv2> <splay> <version> <poolmvff>
33PLINTH = <mpsliban> <mpsioan> 33PLINTH = <mpsliban> <mpsioan>
34AMC = <poolamc> 34AMC = <poolamc>
35AMS = <poolams> 35AMS = <poolams> <poolamsi>
36AWL = <poolawl> 36AWL = <poolawl>
37LO = <poollo> 37LO = <poollo>
38DW = <fmtdy> <fmtno> 38DW = <fmtdy> <fmtno>
diff --git a/mps/code/w3i3mv.nmk b/mps/code/w3i3mv.nmk
index 9add7193248..add22d2a8f7 100644
--- a/mps/code/w3i3mv.nmk
+++ b/mps/code/w3i3mv.nmk
@@ -10,34 +10,34 @@ DONGLELIB = $(RAINBOWPATH)\spromeps.lib
10 10
11PFMDEFS = /DWIN32 /D_WINDOWS /I$(RAINBOWPATH) 11PFMDEFS = /DWIN32 /D_WINDOWS /I$(RAINBOWPATH)
12 12
13MPM = <assert> <ring> <mpm> <bt> <protocol> <boot> \ 13MPM = <ring> <mpm> <bt> <protocol> <boot> \
14 <arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \ 14 <arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \
15 <pool> <poolabs> <poolmfs> <poolmv> \ 15 <pool> <poolabs> <poolmfs> <poolmv> \
16 <root> <format> <buffer> <walk> <lockw3> \ 16 <root> <format> <buffer> <walk> <lockw3> \
17 <ref> <trace> <protw3> <proti3> <prmci3w3> <shield> <vmw3> \ 17 <ref> <trace> <protw3> <proti3> <prmci3w3> <shield> <vmw3> \
18 <thw3i3> <ssw3i3> <mpsi> <mpsiw3> <ld> <spi3> \ 18 <thw3i3> <ssw3i3> <mpsi> <mpsiw3> <ld> <spi3> \
19 <event> <action> <seg> <sac> <poolmrg> <message> <dbgpool> \ 19 <event> <seg> <sac> <poolmrg> <message> <dbgpool> <dbgpooli> \
20 <abq> <meter> <cbs> <poolmv2> <splay> <version> 20 <abq> <meter> <cbs> <poolmv2> <splay> <version>
21SW = <assert> <ring> <mpm> <bt> <protocol> <boot> \ 21SW = <ring> <mpm> <bt> <protocol> <boot> \
22 <arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \ 22 <arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \
23 <pool> <poolabs> <poolmfs> <poolmv> \ 23 <pool> <poolabs> <poolmfs> <poolmv> \
24 <root> <format> <buffer> <walk> \ 24 <root> <format> <buffer> <walk> \
25 <ref> <trace> <protsw> <prmcan> <shield> <vmw3> \ 25 <ref> <trace> <protsw> <prmcan> <shield> <vmw3> \
26 <thw3i3> <ssan> <mpsi> <ld> \ 26 <thw3i3> <ssan> <mpsi> <ld> \
27 <event> <action> <seg> <sac> <poolmrg> <message> <mpsioan> \ 27 <event> <seg> <sac> <poolmrg> <message> <mpsioan> \
28 <poolepdl> <poolepvm> <poolams> <dbgpool> \ 28 <poolams> <poolamsi> <dbgpool> <dbgpooli> \
29 <abq> <meter> <cbs> <poolmv2> <splay> <version> <poolmvff> 29 <abq> <meter> <cbs> <poolmv2> <splay> <version> <poolmvff>
30CONFIGURA = <assert> <ring> <mpm> <bt> <protocol> <boot> \ 30CONFIGURA = <ring> <mpm> <bt> <protocol> <boot> \
31 <arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \ 31 <arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \
32 <pool> <poolabs> <poolmfs> <poolmv> \ 32 <pool> <poolabs> <poolmfs> <poolmv> \
33 <root> <format> <buffer> <walk> \ 33 <root> <format> <buffer> <walk> \
34 <ref> <trace> <protw3> <proti3> <prmci3w3> <shield> <vmw3> \ 34 <ref> <trace> <protw3> <proti3> <prmci3w3> <shield> <vmw3> \
35 <thw3i3> <ssw3i3> <mpsi> <mpsiw3> <ld> <spi3> \ 35 <thw3i3> <ssw3i3> <mpsi> <mpsiw3> <ld> <spi3> \
36 <event> <action> <seg> <sac> <poolmrg> <message> <dbgpool> \ 36 <event> <seg> <sac> <poolmrg> <message> <dbgpool> <dbgpooli> \
37 <abq> <meter> <cbs> <splay> <version> <poolmvff> 37 <abq> <meter> <cbs> <splay> <version> <poolmvff>
38PLINTH = <mpsliban> <mpsioan> 38PLINTH = <mpsliban> <mpsioan>
39AMC = <poolamc> 39AMC = <poolamc>
40AMS = <poolams> 40AMS = <poolams> <poolamsi>
41AWL = <poolawl> 41AWL = <poolawl>
42LO = <poollo> 42LO = <poollo>
43SNC = <poolsnc> 43SNC = <poolsnc>
diff --git a/mps/code/w3ppmv.nmk b/mps/code/w3ppmv.nmk
index c9d41fb90a0..fd9898b1545 100644
--- a/mps/code/w3ppmv.nmk
+++ b/mps/code/w3ppmv.nmk
@@ -10,26 +10,26 @@ DONGLELIB = $(RAINBOWPATH)\spromeps.lib
10 10
11PFMDEFS = /DWIN32 /D_WINDOWS /I$(RAINBOWPATH) 11PFMDEFS = /DWIN32 /D_WINDOWS /I$(RAINBOWPATH)
12 12
13MPM = <assert> <ring> <mpm> <bt> <protocol> <boot> \ 13MPM = <ring> <mpm> <bt> <protocol> <boot> \
14 <arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \ 14 <arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \
15 <pool> <poolabs> <poolmfs> <poolmv> \ 15 <pool> <poolabs> <poolmfs> <poolmv> \
16 <root> <format> <buffer> <walk> <lockw3> \ 16 <root> <format> <buffer> <walk> <lockw3> \
17 <ref> <trace> <protw3> <prmcan> <shield> <vmw3> \ 17 <ref> <trace> <protw3> <prmcan> <shield> <vmw3> \
18 <than> <ssan> <mpsi> <mpsiw3> <ld> <span> \ 18 <than> <ssan> <mpsi> <mpsiw3> <ld> <span> \
19 <event> <action> <seg> <sac> <poolmrg> <message> <dbgpool> \ 19 <event> <seg> <sac> <poolmrg> <message> <dbgpool> <dbgpooli> \
20 <abq> <meter> <cbs> <poolmv2> <splay> <version> 20 <abq> <meter> <cbs> <poolmv2> <splay> <version>
21SW = <assert> <ring> <mpm> <bt> <protocol> <boot> \ 21SW = <ring> <mpm> <bt> <protocol> <boot> \
22 <arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \ 22 <arenavm> <arenacl> <locus> <arena> <global> <tract> <reserv> \
23 <pool> <poolabs> <poolmfs> <poolmv> \ 23 <pool> <poolabs> <poolmfs> <poolmv> \
24 <root> <format> <buffer> <walk> \ 24 <root> <format> <buffer> <walk> \
25 <ref> <trace> <protsw> <prmcan> <shield> <vmw3> \ 25 <ref> <trace> <protsw> <prmcan> <shield> <vmw3> \
26 <than> <ssan> <mpsi> <ld> \ 26 <than> <ssan> <mpsi> <ld> \
27 <event> <action> <seg> <sac> <poolmrg> <message> <mpsioan> \ 27 <event> <seg> <sac> <poolmrg> <message> <mpsioan> \
28 <poolepdl> <poolepvm> <poolams> <dbgpool> \ 28 <poolams> <poolamsi> <dbgpool> <dbgpooli> \
29 <abq> <meter> <cbs> <poolmv2> <splay> <version> <poolmvff> 29 <abq> <meter> <cbs> <poolmv2> <splay> <version> <poolmvff>
30PLINTH = <mpsliban> <mpsioan> 30PLINTH = <mpsliban> <mpsioan>
31AMC = <poolamc> 31AMC = <poolamc>
32AMS = <poolams> 32AMS = <poolams> <poolamsi>
33AWL = <poolawl> 33AWL = <poolawl>
34LO = <poollo> 34LO = <poollo>
35DW = <fmtdy> <fmtno> 35DW = <fmtdy> <fmtno>