diff options
| author | Nick Barnes | 2002-06-18 14:14:55 +0100 |
|---|---|---|
| committer | Nick Barnes | 2002-06-18 14:14:55 +0100 |
| commit | 6a1a360814506ddbcf856f41c089a10550f31ae5 (patch) | |
| tree | 732fc720ec58b9badf2ce1eef392ada522130a03 /mps/code | |
| parent | 63e5f529159927bb42b58a97507f4467d6413973 (diff) | |
| download | emacs-6a1a360814506ddbcf856f41c089a10550f31ae5.tar.gz emacs-6a1a360814506ddbcf856f41c089a10550f31ae5.zip | |
Integrate changes from global graphics.
Copied from Perforce
Change: 30250
ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
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 | |||
| 9 | SRCID(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 | ||
| 33 | static mps_gen_param_s testChain[genCOUNT] = { | 36 | static mps_gen_param_s testChain[genCOUNT] = { |
| 34 | { 150, 0.85 }, { 170, 0.45 } }; | 37 | { gen1SIZE, 0.85 }, { gen2SIZE, 0.45 } }; |
| 35 | 38 | ||
| 36 | 39 | ||
| 37 | /* objNULL needs to be odd so that it's ignored in exactRoots. */ | 40 | /* objNULL needs to be odd so that it's ignored in exactRoots. */ |
| 38 | #define objNULL ((mps_addr_t)0xDECEA5ED) | 41 | #define objNULL ((mps_addr_t)0xDECEA5ED) |
| 39 | 42 | ||
| 43 | |||
| 40 | static mps_pool_t pool; | 44 | static mps_pool_t pool; |
| 41 | static mps_ap_t ap; | 45 | static mps_ap_t ap; |
| 42 | static mps_addr_t exactRoots[exactRootsCOUNT]; | 46 | static mps_addr_t exactRoots[exactRootsCOUNT]; |
| 43 | static mps_addr_t ambigRoots[ambigRootsCOUNT]; | 47 | static mps_addr_t ambigRoots[ambigRootsCOUNT]; |
| 44 | 48 | ||
| 45 | 49 | ||
| 46 | static void enable(mps_arena_t arena) | 50 | /* report - report statistics from any terminated GCs */ |
| 47 | { | ||
| 48 | mps_message_type_enable(arena, mps_message_type_gc()); | ||
| 49 | } | ||
| 50 | 51 | ||
| 51 | static void report(mps_arena_t arena) | 52 | static void report(mps_arena_t arena) |
| 52 | { | 53 | { |
| 53 | mps_message_t message; | 54 | mps_message_t message; |
| 54 | 55 | static int nCollections = 0; | |
| 55 | while (mps_message_get(&message, arena, mps_message_type_gc())) { | 56 | |
| 56 | size_t live, condemned, not_condemned; | 57 | while (mps_message_get(&message, arena, mps_message_type_gc())) { |
| 58 | size_t live, condemned, not_condemned; | ||
| 59 | |||
| 60 | live = mps_message_gc_live_size(arena, message); | ||
| 61 | condemned = mps_message_gc_condemned_size(arena, message); | ||
| 62 | not_condemned = mps_message_gc_not_condemned_size(arena, message); | ||
| 63 | |||
| 64 | printf("\nCollection %d finished:\n", ++nCollections); | ||
| 65 | printf("live %lu\n", (unsigned long)live); | ||
| 66 | printf("condemned %lu\n", (unsigned long)condemned); | ||
| 67 | printf("not_condemned %lu\n", (unsigned long)not_condemned); | ||
| 68 | |||
| 69 | mps_message_discard(arena, message); | ||
| 70 | |||
| 71 | if (condemned > (gen1SIZE + gen2SIZE + (size_t)128) * 1024) | ||
| 72 | /* When condemned size is larger than could happen in a gen 2 | ||
| 73 | * collection (discounting ramps, natch), guess that was a dynamic | ||
| 74 | * collection, and reset the commit limit, so it doesn't run out. */ | ||
| 75 | die(mps_arena_commit_limit_set(arena, 2 * testArenaSIZE), "set limit"); | ||
| 76 | } | ||
| 77 | } | ||
| 57 | 78 | ||
| 58 | live = mps_message_gc_live_size(arena, message); | ||
| 59 | condemned = mps_message_gc_condemned_size(arena, message); | ||
| 60 | not_condemned = mps_message_gc_not_condemned_size(arena, message); | ||
| 61 | 79 | ||
| 62 | mps_message_discard(arena, message); | 80 | /* make -- create one new object */ |
| 63 | |||
| 64 | printf("live %lu\n", (unsigned long)live); | ||
| 65 | printf("condemned %lu\n", (unsigned long)condemned); | ||
| 66 | printf("not_condemned %lu\n", (unsigned long)not_condemned); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | 81 | ||
| 70 | static mps_addr_t make(void) | 82 | static mps_addr_t make(void) |
| 71 | { | 83 | { |
| @@ -76,10 +88,10 @@ static mps_addr_t make(void) | |||
| 76 | 88 | ||
| 77 | do { | 89 | do { |
| 78 | MPS_RESERVE_BLOCK(res, p, ap, size); | 90 | MPS_RESERVE_BLOCK(res, p, ap, size); |
| 79 | if(res) | 91 | if (res) |
| 80 | die(res, "MPS_RESERVE_BLOCK"); | 92 | die(res, "MPS_RESERVE_BLOCK"); |
| 81 | res = dylan_init(p, size, exactRoots, exactRootsCOUNT); | 93 | res = dylan_init(p, size, exactRoots, exactRootsCOUNT); |
| 82 | if(res) | 94 | if (res) |
| 83 | die(res, "dylan_init"); | 95 | die(res, "dylan_init"); |
| 84 | } while(!mps_commit(ap, p, size)); | 96 | } while(!mps_commit(ap, p, size)); |
| 85 | 97 | ||
| @@ -87,6 +99,8 @@ static mps_addr_t make(void) | |||
| 87 | } | 99 | } |
| 88 | 100 | ||
| 89 | 101 | ||
| 102 | /* test_stepper -- stepping function for walk */ | ||
| 103 | |||
| 90 | static void test_stepper(mps_addr_t object, mps_fmt_t fmt, mps_pool_t pol, | 104 | static void test_stepper(mps_addr_t object, mps_fmt_t fmt, mps_pool_t pol, |
| 91 | void *p, size_t s) | 105 | void *p, size_t s) |
| 92 | { | 106 | { |
| @@ -126,7 +140,7 @@ static void *test(void *arg, size_t s) | |||
| 126 | for(i = 0; i < exactRootsCOUNT; ++i) | 140 | for(i = 0; i < exactRootsCOUNT; ++i) |
| 127 | exactRoots[i] = objNULL; | 141 | exactRoots[i] = objNULL; |
| 128 | for(i = 0; i < ambigRootsCOUNT; ++i) | 142 | for(i = 0; i < ambigRootsCOUNT; ++i) |
| 129 | ambigRoots[i] = (mps_addr_t)rnd(); | 143 | ambigRoots[i] = rnd_addr(); |
| 130 | 144 | ||
| 131 | die(mps_root_create_table_masked(&exactRoot, arena, | 145 | die(mps_root_create_table_masked(&exactRoot, arena, |
| 132 | MPS_RANK_EXACT, (mps_rm_t)0, | 146 | MPS_RANK_EXACT, (mps_rm_t)0, |
| @@ -143,74 +157,81 @@ static void *test(void *arg, size_t s) | |||
| 143 | 157 | ||
| 144 | collections = 0; | 158 | collections = 0; |
| 145 | rampSwitch = rampSIZE; | 159 | rampSwitch = rampSIZE; |
| 146 | mps_ap_alloc_pattern_begin(ap, ramp); | 160 | die(mps_ap_alloc_pattern_begin(ap, ramp), "pattern begin (ap)"); |
| 147 | mps_ap_alloc_pattern_begin(busy_ap, ramp); | 161 | die(mps_ap_alloc_pattern_begin(busy_ap, ramp), "pattern begin (busy_ap)"); |
| 148 | ramping = 1; | 162 | ramping = 1; |
| 149 | objs = 0; | 163 | objs = 0; |
| 150 | while(collections < collectionsCOUNT) { | 164 | while (collections < collectionsCOUNT) { |
| 151 | unsigned long c; | 165 | unsigned long c; |
| 152 | size_t r; | 166 | size_t r; |
| 167 | size_t hitRatio; | ||
| 153 | 168 | ||
| 154 | c = mps_collections(arena); | 169 | c = mps_collections(arena); |
| 155 | 170 | ||
| 156 | if(collections != c) { | 171 | if (collections != c) { |
| 157 | collections = c; | 172 | collections = c; |
| 158 | printf("\nCollection %lu, %lu objects.\n", | 173 | printf("\nCollection %lu started, %lu objects.\n", c, objs); |
| 159 | c, objs); | 174 | |
| 160 | do { | 175 | /* test mps_arena_has_addr */ |
| 161 | mps_addr_t p = (mps_addr_t)rnd(); | 176 | hitRatio = ((size_t)-1 / mps_arena_committed(arena)); |
| 162 | if (mps_arena_has_addr(arena, p)) { | 177 | /* That's roughly how often a random addr should hit the arena. */ |
| 163 | printf("0x%08x is in arena\n", (int)p); | 178 | for (i = 0; i < 4 * hitRatio ; i++) { |
| 164 | break; | 179 | mps_addr_t p = rnd_addr(); |
| 165 | } | 180 | if (mps_arena_has_addr(arena, p)) { |
| 166 | } while(1); | 181 | printf("%p is in the arena\n", p); |
| 182 | } | ||
| 183 | } | ||
| 167 | 184 | ||
| 168 | report(arena); | 185 | report(arena); |
| 169 | for(r = 0; r < exactRootsCOUNT; ++r) | 186 | for (i = 0; i < exactRootsCOUNT; ++i) |
| 170 | cdie(exactRoots[r] == objNULL || | 187 | cdie(exactRoots[i] == objNULL |
| 171 | (dylan_check(exactRoots[r]) && | 188 | || (dylan_check(exactRoots[i]) |
| 172 | mps_arena_has_addr(arena, exactRoots[r])), | 189 | && mps_arena_has_addr(arena, exactRoots[i])), |
| 173 | "all roots check"); | 190 | "all roots check"); |
| 174 | cdie(!mps_arena_has_addr(arena, NULL), | 191 | cdie(!mps_arena_has_addr(arena, NULL), |
| 175 | "NULL in arena"); | 192 | "NULL in arena"); |
| 176 | 193 | ||
| 177 | if(collections == collectionsCOUNT / 2) { | 194 | if (collections == collectionsCOUNT / 2) { |
| 178 | unsigned long object_count = 0; | 195 | unsigned long object_count = 0; |
| 179 | mps_arena_park(arena); | 196 | mps_arena_park(arena); |
| 180 | mps_arena_formatted_objects_walk(arena, test_stepper, &object_count, 0); | 197 | mps_arena_formatted_objects_walk(arena, test_stepper, &object_count, 0); |
| 181 | mps_arena_release(arena); | 198 | mps_arena_release(arena); |
| 182 | printf("stepped on %lu objects.\n", object_count); | 199 | printf("stepped on %lu objects.\n", object_count); |
| 183 | } | 200 | } |
| 184 | if(collections == rampSwitch) { | 201 | if (collections == rampSwitch) { |
| 202 | int begin_ramp = !ramping | ||
| 203 | || /* Every other time, switch back immediately. */ (collections & 1); | ||
| 204 | |||
| 185 | rampSwitch += rampSIZE; | 205 | rampSwitch += rampSIZE; |
| 186 | if(ramping) { | 206 | if (ramping) { |
| 187 | mps_ap_alloc_pattern_end(ap, ramp); | 207 | die(mps_ap_alloc_pattern_end(ap, ramp), "pattern end (ap)"); |
| 188 | mps_ap_alloc_pattern_end(busy_ap, ramp); | 208 | die(mps_ap_alloc_pattern_end(busy_ap, ramp), "pattern end (busy_ap)"); |
| 209 | ramping = 0; | ||
| 189 | /* kill half of the roots */ | 210 | /* kill half of the roots */ |
| 190 | for(i = 0; i < exactRootsCOUNT; i += 2) { | 211 | for(i = 0; i < exactRootsCOUNT; i += 2) { |
| 191 | if(exactRoots[i] != objNULL) { | 212 | if (exactRoots[i] != objNULL) { |
| 192 | cdie(dylan_check(exactRoots[i]), "ramp kill check"); | 213 | cdie(dylan_check(exactRoots[i]), "ramp kill check"); |
| 193 | exactRoots[i] = objNULL; | 214 | exactRoots[i] = objNULL; |
| 194 | } | 215 | } |
| 195 | } | 216 | } |
| 196 | /* Every other time, switch back immediately. */ | ||
| 197 | if(collections & 1) ramping = 0; | ||
| 198 | } | 217 | } |
| 199 | if(!ramping) { | 218 | if (begin_ramp) { |
| 200 | mps_ap_alloc_pattern_begin(ap, ramp); | 219 | die(mps_ap_alloc_pattern_begin(ap, ramp), |
| 201 | mps_ap_alloc_pattern_begin(busy_ap, ramp); | 220 | "pattern rebegin (ap)"); |
| 221 | die(mps_ap_alloc_pattern_begin(busy_ap, ramp), | ||
| 222 | "pattern rebegin (busy_ap)"); | ||
| 202 | ramping = 1; | 223 | ramping = 1; |
| 203 | } | 224 | } |
| 204 | } | 225 | } |
| 205 | } | 226 | } |
| 206 | 227 | ||
| 207 | r = (size_t)rnd(); | 228 | r = (size_t)rnd(); |
| 208 | if(r & 1) { | 229 | if (r & 1) { |
| 209 | i = (r >> 1) % exactRootsCOUNT; | 230 | i = (r >> 1) % exactRootsCOUNT; |
| 210 | if(exactRoots[i] != objNULL) | 231 | if (exactRoots[i] != objNULL) |
| 211 | cdie(dylan_check(exactRoots[i]), "dying root check"); | 232 | cdie(dylan_check(exactRoots[i]), "dying root check"); |
| 212 | exactRoots[i] = make(); | 233 | exactRoots[i] = make(); |
| 213 | if(exactRoots[(exactRootsCOUNT-1) - i] != objNULL) | 234 | if (exactRoots[(exactRootsCOUNT-1) - i] != objNULL) |
| 214 | dylan_write(exactRoots[(exactRootsCOUNT-1) - i], | 235 | dylan_write(exactRoots[(exactRootsCOUNT-1) - i], |
| 215 | exactRoots, exactRootsCOUNT); | 236 | exactRoots, exactRootsCOUNT); |
| 216 | } else { | 237 | } else { |
| @@ -220,10 +241,11 @@ static void *test(void *arg, size_t s) | |||
| 220 | ambigRoots[i] = (mps_addr_t)((char *)(ambigRoots[i/2]) + 1); | 241 | ambigRoots[i] = (mps_addr_t)((char *)(ambigRoots[i/2]) + 1); |
| 221 | } | 242 | } |
| 222 | 243 | ||
| 223 | if(r % initTestFREQ == 0) | 244 | if (r % initTestFREQ == 0) |
| 224 | *(int*)busy_init = -1; /* check that the buffer is still there */ | 245 | *(int*)busy_init = -1; /* check that the buffer is still there */ |
| 225 | 246 | ||
| 226 | if(objs % 1024 == 0) { | 247 | if (objs % 1024 == 0) { |
| 248 | report(arena); | ||
| 227 | putchar('.'); | 249 | putchar('.'); |
| 228 | fflush(stdout); | 250 | fflush(stdout); |
| 229 | } | 251 | } |
| @@ -253,7 +275,7 @@ int main(int argc, char **argv) | |||
| 253 | 275 | ||
| 254 | die(mps_arena_create(&arena, mps_arena_class_vm(), 2*testArenaSIZE), | 276 | die(mps_arena_create(&arena, mps_arena_class_vm(), 2*testArenaSIZE), |
| 255 | "arena_create"); | 277 | "arena_create"); |
| 256 | enable(arena); | 278 | mps_message_type_enable(arena, mps_message_type_gc()); |
| 257 | die(mps_arena_commit_limit_set(arena, testArenaSIZE), "set limit"); | 279 | die(mps_arena_commit_limit_set(arena, testArenaSIZE), "set limit"); |
| 258 | die(mps_thread_reg(&thread, arena), "thread_reg"); | 280 | die(mps_thread_reg(&thread, arena), "thread_reg"); |
| 259 | mps_tramp(&r, test, arena, 0); | 281 | mps_tramp(&r, test, arena, 0); |
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 | ||
| 34 | static mps_gen_param_s testChain[genCOUNT] = { | 39 | static 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 | |||
| 78 | static 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 | ||
| 73 | static void *test(void *arg, size_t s) | 108 | static 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 | ||
| 38 | static mps_gen_param_s testChain[genCOUNT] = { | 36 | static 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; | |||
| 54 | unsigned long objs = 0; | 52 | unsigned long objs = 0; |
| 55 | 53 | ||
| 56 | 54 | ||
| 55 | /* report - report statistics from any terminated GCs */ | ||
| 56 | |||
| 57 | static 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 | |||
| 57 | static mps_addr_t make(mps_ap_t ap) | 87 | static 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 | ||
| 77 | static void test_stepper(mps_addr_t object, void *p, size_t s) | 107 | /* test_stepper -- stepping function for walk */ |
| 108 | |||
| 109 | static 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 | ||
| 36 | static mps_gen_param_s testChain[1] = { { 160, 0.90 } }; | 37 | static mps_gen_param_s testChain[1] = { { 160, 0.90 } }; |
| 37 | 38 | ||
| 38 | 39 | ||
| 39 | static mps_pool_t pool; | 40 | static mps_arena_t arena; |
| 40 | static mps_ap_t ap; | 41 | static mps_ap_t ap; |
| 41 | static mps_addr_t exactRoots[exactRootsCOUNT]; | 42 | static mps_addr_t exactRoots[exactRootsCOUNT]; |
| 42 | static mps_addr_t ambigRoots[ambigRootsCOUNT]; | 43 | static mps_addr_t ambigRoots[ambigRootsCOUNT]; |
| 43 | static size_t totalSize = 0; | 44 | static size_t totalSize = 0; |
| 44 | 45 | ||
| 45 | 46 | ||
| 47 | /* make -- object allocation and init */ | ||
| 48 | |||
| 46 | static mps_addr_t make(void) | 49 | static 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 | ||
| 66 | static void *test(void *arg, size_t s) | 69 | /* test -- the actual stress test */ |
| 70 | |||
| 71 | static mps_pool_debug_option_s freecheckOptions = | ||
| 72 | { NULL, 0, (void *)"Dead", 4 }; | ||
| 73 | |||
| 74 | static 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 | ||
| 157 | int main(int argc, char **argv) | 160 | int 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 | |||
| 24 | static mps_res_t make(mps_addr_t *p, mps_ap_t ap, size_t size) | 27 | static 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 | ||
| 38 | static 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 | |
| 43 | static 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 | |||
| 110 | static size_t randomSize8(int i) | 118 | static 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 | ||
| 118 | static mps_pool_debug_option_s debugOptions = { (void *)"postpost", 8 }; | 126 | /* testInArena -- test all the pool classes in the given arena */ |
| 127 | |||
| 128 | static mps_pool_debug_option_s bothOptions = | ||
| 129 | { (void *)"postpost", 8, (void *)"DEAD", 4 }; | ||
| 130 | |||
| 131 | static mps_pool_debug_option_s fenceOptions = | ||
| 132 | { (void *)"\0XXX ''\"\"'' XXX\0", 16, NULL, 0 }; | ||
| 119 | 133 | ||
| 120 | static void testInArena(mps_arena_t arena) | 134 | static 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 | |||
| 19 | SRCID(arenavmx, "$Id$"); | ||
| 20 | |||
| 21 | |||
| 22 | mps_arena_class_t mps_arena_class_vm(void) | ||
| 23 | { | ||
| 24 | NOTREACHED; | ||
| 25 | return (mps_arena_class_t)NULL; | ||
| 26 | } | ||
| 27 | |||
| 28 | mps_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 | |||
| 14 | SRCID(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 | |||
| 23 | unsigned CheckLevel = CheckSHALLOW; | ||
| 24 | |||
| 25 | |||
| 26 | static 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 | |||
| 44 | static AssertHandler handler = &AssertLib; | ||
| 45 | |||
| 46 | |||
| 47 | AssertHandler AssertDefault(void) | ||
| 48 | { | ||
| 49 | return &AssertLib; | ||
| 50 | } | ||
| 51 | |||
| 52 | |||
| 53 | AssertHandler 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 | */ | ||
| 67 | void 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 | |||
| 18 | SRCID(bt, "$Id$"); | 20 | SRCID(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 | |||
| 1007 | Count 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 */ | ||
| 16 | extern 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 */ | ||
| 21 | extern 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 */ | ||
| 28 | extern 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 */ | ||
| 35 | extern 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 | |||
| 43 | extern Res BTCreate(BT *btReturn, Arena arena, Count length); | ||
| 44 | extern void BTDestroy(BT bt, Arena arena, Count length); | ||
| 45 | |||
| 46 | extern void BTSetRange(BT bt, Index base, Index limit); | ||
| 47 | extern Bool BTIsSetRange(BT bt, Index base, Index limit); | ||
| 48 | extern void BTResRange(BT bt, Index base, Index limit); | ||
| 49 | extern Bool BTIsResRange(BT bt, Index base, Index limit); | ||
| 50 | |||
| 51 | extern Bool BTFindShortResRange(Index *baseReturn, Index *limitReturn, | ||
| 52 | BT bt, Index searchBase, Index searchLimit, | ||
| 53 | unsigned long length); | ||
| 54 | extern Bool BTFindShortResRangeHigh(Index *baseReturn, Index *limitReturn, | ||
| 55 | BT bt, Index searchBase, Index searchLimit, | ||
| 56 | unsigned long length); | ||
| 57 | extern Bool BTFindLongResRange(Index *baseReturn, Index *limitReturn, | ||
| 58 | BT bt, Index searchBase, Index searchLimit, | ||
| 59 | unsigned long length); | ||
| 60 | extern Bool BTFindLongResRangeHigh(Index *baseReturn, Index *limitReturn, | ||
| 61 | BT bt, Index searchBase, Index searchLimit, | ||
| 62 | unsigned long length); | ||
| 63 | |||
| 64 | extern Bool BTRangesSame(BT BTx, BT BTy, Index base, Index limit); | ||
| 65 | |||
| 66 | extern void BTCopyInvertRange(BT fromBT, BT toBT, Index base, Index limit); | ||
| 67 | extern void BTCopyRange(BT fromBT, BT toBT, Index base, Index limit); | ||
| 68 | extern void BTCopyOffsetRange(BT fromBT, BT toBT, | ||
| 69 | Index fromBase, Index fromLimit, | ||
| 70 | Index toBase, Index toLimit); | ||
| 71 | |||
| 72 | extern 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 | |||
| 22 | SRCID(bttest, "$Id$"); | 21 | SRCID(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 | |||
| 22 | SRCID(cbs, "$Id$"); | 21 | SRCID(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 | ||
| 31 | extern unsigned CheckLevel; | 32 | extern 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 | |||
| 79 | typedef void (*AssertHandler)(const char *cond, const char *id, | ||
| 80 | const char *file, unsigned line); | ||
| 81 | extern AssertHandler AssertInstall(AssertHandler handler); | ||
| 82 | extern AssertHandler AssertDefault(void); | ||
| 83 | |||
| 84 | |||
| 85 | /* internals for actually asserting */ | 75 | /* internals for actually asserting */ |
| 86 | 76 | ||
| 87 | extern 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 | |||
| 99 | ifeq ($(TARGET),mmsw.a) | 99 | ifeq ($(TARGET),mmsw.a) |
| 100 | CFLAGSTARGET = -DCONFIG_PROD_EPCORE | 100 | CFLAGSTARGET = -DCONFIG_PROD_EPCORE |
| 101 | else | 101 | else |
| 102 | ifeq ($(TARGET),epvmss) | ||
| 103 | CFLAGSTARGET = -DCONFIG_PROD_EPCORE | ||
| 104 | else | ||
| 105 | ifeq ($(TARGET),replaysw) | 102 | ifeq ($(TARGET),replaysw) |
| 106 | CFLAGSTARGET = -DCONFIG_PROD_EPCORE | 103 | CFLAGSTARGET = -DCONFIG_PROD_EPCORE |
| 107 | else | 104 | else |
| 108 | ifeq ($(TARGET),epdss) | ||
| 109 | CFLAGSTARGET = -DCONFIG_PROD_EPCORE | ||
| 110 | else | ||
| 111 | ifeq ($(TARGET),mmdw.a) | 105 | ifeq ($(TARGET),mmdw.a) |
| 112 | CFLAGSTARGET = -DCONFIG_PROD_DYLAN | 106 | CFLAGSTARGET = -DCONFIG_PROD_DYLAN |
| 113 | else | 107 | else |
| @@ -120,8 +114,6 @@ endif | |||
| 120 | endif | 114 | endif |
| 121 | endif | 115 | endif |
| 122 | endif | 116 | endif |
| 123 | endif | ||
| 124 | endif | ||
| 125 | 117 | ||
| 126 | # These flags are included in all compilations. | 118 | # These flags are included in all compilations. |
| 127 | CFLAGSCOMMON = $(PFMDEFS) $(CFLAGSTARGET) $(CFLAGSCOMPILER) | 119 | CFLAGSCOMMON = $(PFMDEFS) $(CFLAGSTARGET) $(CFLAGSCOMPILER) |
| @@ -184,7 +176,7 @@ ARFLAGS=rc$(ARFLAGSPFM) | |||
| 184 | # platforms. | 176 | # platforms. |
| 185 | 177 | ||
| 186 | AMC = poolamc.c | 178 | AMC = poolamc.c |
| 187 | AMS = poolams.c | 179 | AMS = poolams.c poolamsi.c |
| 188 | AWL = poolawl.c | 180 | AWL = poolawl.c |
| 189 | LO = poollo.c | 181 | LO = poollo.c |
| 190 | SNC = poolsnc.c | 182 | SNC = poolsnc.c |
| @@ -200,16 +192,16 @@ EVENTPROC = eventcnv.c eventpro.c table.c | |||
| 200 | MPMCOMMON = mpsi.c mpm.c arenavm.c arenacl.c arena.c global.c locus.c \ | 192 | MPMCOMMON = 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 |
| 206 | MPM = $(MPMCOMMON) $(MPMPF) | 198 | MPM = $(MPMCOMMON) $(MPMPF) |
| 207 | SWCOMMON = mpsi.c mpm.c arenavm.c arenacl.c arena.c global.c locus.c \ | 199 | SWCOMMON = 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 |
| 214 | SW = $(SWCOMMON) $(SWPF) | 206 | SW = $(SWCOMMON) $(SWPF) |
| 215 | 207 | ||
| @@ -246,9 +238,6 @@ ifdef TARGET | |||
| 246 | ifeq ($(TARGET),mmsw.a) | 238 | ifeq ($(TARGET),mmsw.a) |
| 247 | SWDEP = $(SW:%.c=$(PFM)/$(VARIETY)/%.d) | 239 | SWDEP = $(SW:%.c=$(PFM)/$(VARIETY)/%.d) |
| 248 | else | 240 | else |
| 249 | ifeq ($(TARGET),epvmss) | ||
| 250 | SWDEP = $(SW:%.c=$(PFM)/$(VARIETY)/%.d) | ||
| 251 | else | ||
| 252 | ifeq ($(TARGET),depend) | 241 | ifeq ($(TARGET),depend) |
| 253 | SWDEP = $(SW:%.c=$(PFM)/$(VARIETY)/%.d) | 242 | SWDEP = $(SW:%.c=$(PFM)/$(VARIETY)/%.d) |
| 254 | else | 243 | else |
| @@ -256,7 +245,6 @@ SWDEP = | |||
| 256 | endif | 245 | endif |
| 257 | endif | 246 | endif |
| 258 | endif | 247 | endif |
| 259 | endif | ||
| 260 | 248 | ||
| 261 | TESTLIBOBJ = $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.o) | 249 | TESTLIBOBJ = $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.o) |
| 262 | TESTLIBDEP = $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.d) | 250 | TESTLIBDEP = $(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 | ||
| 287 | swall: mmsw.a epvmss replaysw epdss | 275 | swall: 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 | ||
| 299 | testrunep: 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 | ||
| 308 | mpmss sacss amcss amcssth amcsshe amsss amssshe segsmss awlut awlutth \ | 291 | mpmss 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 | ||
| 24 | swall: mmsw.lib epvmss.exe replaysw.exe | 24 | swall: 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 | ||
| 32 | mpmss.exe amcss.exe amcsshe.exe amsss.exe amssshe.exe segsmss.exe awlut.exe awluthe.exe dwstress.exe \ | 32 | mpmss.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 | ||
| 17 | SRCID(dbgpool, "$Id$"); | 16 | SRCID(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 | ||
| 40 | static void TagTrivInit(void* tag, va_list args) | 38 | static 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 | |||
| 222 | static 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 | |||
| 255 | static 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 | |||
| 288 | done: | ||
| 289 | if (inSeg) { | ||
| 290 | ShieldCover(arena, seg); | ||
| 291 | } | ||
| 292 | return res; | ||
| 293 | } | ||
| 294 | |||
| 295 | |||
| 296 | /* freeCheckAlloc -- allocation wrapper for free-checking */ | ||
| 297 | |||
| 298 | static 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 | |||
| 320 | static 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 | ||
| 214 | static Res FenceAlloc(Addr *aReturn, PoolDebugMixin debug, Pool pool, | 345 | static 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 | ||
| 251 | static Bool FenceCheck(PoolDebugMixin debug, Pool pool, | 377 | static 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 | ||
| 273 | static void FenceFree(PoolDebugMixin debug, | 399 | static 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 | ||
| 293 | static Res TagAlloc(PoolDebugMixin debug, | 414 | static 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 | ||
| 323 | static void TagFree(PoolDebugMixin debug, Pool pool, Addr old, Size size) | 441 | static 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 | ||
| 353 | static Res DebugPoolAlloc(Addr *aReturn, | 471 | static 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 | ||
| 379 | tagFail: | 502 | tagFail: |
| 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 | ||
| 406 | typedef void (*ObjectsStepMethod)(Addr addr, Size size, Format fmt, | 534 | typedef 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 | ||
| 439 | static void FenceCheckingStep(Addr addr, Size size, Format fmt, | 567 | static 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 | ||
| 451 | static void DebugPoolCheckFences(Pool pool) | 579 | void 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 | ||
| 467 | void PoolClassMixInDebug(PoolClass class) | 596 | void 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 | ||
| 479 | void mps_pool_check_fenceposts(mps_pool_t mps_pool) | 615 | void 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 | |||
| 635 | static 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 | |||
| 645 | void 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); | 662 | void 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); | |||
| 25 | typedef struct PoolDebugOptionsStruct { | 26 | typedef 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 | ||
| 51 | extern Bool PoolDebugMixinCheck(PoolDebugMixin dbg); | 56 | extern Bool PoolDebugMixinCheck(PoolDebugMixin dbg); |
| 52 | 57 | ||
| 53 | |||
| 54 | extern void PoolClassMixInDebug(PoolClass class); | 58 | extern void PoolClassMixInDebug(PoolClass class); |
| 55 | 59 | ||
| 60 | extern void DebugPoolCheckFences(Pool pool); | ||
| 61 | extern void DebugPoolCheckFreeSpace(Pool pool); | ||
| 62 | |||
| 63 | extern void DebugPoolFreeSplat(Pool pool, Addr base, Addr limit); | ||
| 64 | extern 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 | |||
| 14 | SRCID(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 | |||
| 19 | void 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 | |||
| 39 | void 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 | ||
| 83 | enum { | ||
| 84 | rootSTATE, | ||
| 85 | deadSTATE, | ||
| 86 | finalizableSTATE, | ||
| 87 | finalizedSTATE | ||
| 88 | }; | ||
| 89 | |||
| 90 | |||
| 79 | static void *test(void *arg, size_t s) | 91 | static 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 | |||
| 370 | extern mps_res_t dylan_scan1(mps_ss_t mps_ss, mps_addr_t *object_io) | 362 | extern 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 | ||
| 694 | static mps_addr_t dylan_isfwd(mps_addr_t object) | 688 | static 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 | |||
| 111 | void FormatDestroy(Format format) | 115 | void 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 | |||
| 126 | Arena FormatArena(Format format) | 133 | Arena 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 | |||
| 134 | Res FormatDescribe(Format format, mps_lib_FILE *stream) | 143 | Res 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 | |||
| 6 | rmdir /s w3i3mv | ||
| 7 | nmake /f w3i3mv.nmk VARIETY=we mps_conf.lib mpsplan.lib | ||
| 8 | nmake /f w3i3mv.nmk VARIETY=wi mps_conf.lib mpsplan.lib | ||
| 9 | nmake /f w3i3mv.nmk VARIETY=ce mps_conf.lib mpsplan.lib | ||
| 10 | nmake /f w3i3mv.nmk VARIETY=ci mps_conf.lib mpsplan.lib | ||
| 11 | mkdir release | ||
| 12 | mkdir release\include | ||
| 13 | mkdir release\lib | ||
| 14 | mkdir release\lib\w3i3 | ||
| 15 | mkdir release\lib\w3i3\release | ||
| 16 | mkdir release\lib\w3i3\debug | ||
| 17 | mkdir release\src | ||
| 18 | copy mps.h release\include | ||
| 19 | copy mpsavm.h release\include | ||
| 20 | copy mpsacl.h release\include | ||
| 21 | copy mpscamc.h release\include | ||
| 22 | copy mpscams.h release\include | ||
| 23 | copy mpsclo.h release\include | ||
| 24 | copy mpscmv.h release\include | ||
| 25 | copy mpscmvff.h release\include | ||
| 26 | copy mpscsnc.h release\include | ||
| 27 | copy mpsio.h release\include | ||
| 28 | copy mpslib.h release\include | ||
| 29 | copy mpstd.h release\include | ||
| 30 | copy mpsw3.h release\include | ||
| 31 | copy mpswin.h release\include | ||
| 32 | copy w3i3mv\we\mps_conf.lib release\lib\w3i3\release | ||
| 33 | copy w3i3mv\ce\mps_conf.lib release\lib\w3i3\debug | ||
| 34 | copy w3i3mv\we\mpsplan.lib release\lib\w3i3\release | ||
| 35 | copy w3i3mv\ce\mpsplan.lib release\lib\w3i3\debug | ||
| 36 | copy mpsliban.c release\src | ||
| 37 | copy 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 | |||
| 30 | SRCID(global, "$Id$"); | 30 | SRCID(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 | |||
| 604 | Res 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 @@ | |||
| 1 | MSVCNT 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 @@ | |||
| 1 | MSVCNT 5_0 | ||
| 2 | MSTOOLS Aug96US9 | ||
| 3 | MSMASM 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 | |||
| 14 | case $# in | ||
| 15 | 1) ;; | ||
| 16 | *) echo 1>&2 'Wrong number of arguments to hqbuild. | ||
| 17 | Exactly one argument expected'; exit 1;; | ||
| 18 | esac | ||
| 19 | |||
| 20 | gnumake -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 | ||
| 7 | IF NOT %MSMASM%X == X SET PATH=%MSMASM%\bin;%PATH% | ||
| 8 | SET PATH=%MSVCNT%\..\sharedide\bin\ide;%MSVCNT%\..\sharedide\bin;%MSVCNT%\bin;%PATH% | ||
| 9 | SET INCLUDE=%MSVCNT%\include;%MSVCNT%\mfc\include;%INCLUDE% | ||
| 10 | SET LIB=%MSVCNT%\lib;%MSVCNT%\mfc\lib;%LIB% | ||
| 11 | @REM First argument is expected to be platform code, rest we pass on | ||
| 12 | nmake /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 | |||
| 37 | typedef struct PoolStatStruct *PoolStat; | ||
| 38 | |||
| 39 | typedef 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 | |||
| 51 | static 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 | |||
| 60 | static 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 | |||
| 76 | static void recordFreedObjectStat(PoolStat stat) | ||
| 77 | { | ||
| 78 | stat->fCount++; | ||
| 79 | } | ||
| 80 | |||
| 81 | |||
| 82 | static 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 | |||
| 110 | static 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 | |||
| 132 | static 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 | |||
| 147 | static 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 | |||
| 192 | int 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 | |||
| 19 | SRCID(locus, "$Id$"); | 18 | SRCID(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 | ||
| 48 | Res SegPrefExpress(SegPref pref, SegPrefKind kind, void *p) | 47 | void 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 | ||
| 94 | static Bool GenDescCheck(GenDesc gen) | 89 | static Bool GenDescCheck(GenDesc gen) |
| @@ -473,9 +468,6 @@ void LocusFinish(Arena arena) | |||
| 473 | Bool LocusCheck(Arena arena) | 468 | Bool 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 | |||
| 38 | typedef struct PoolStatStruct *PoolStat; | ||
| 39 | |||
| 40 | typedef 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 | |||
| 52 | static 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 | |||
| 60 | static 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 | |||
| 76 | static void recordFreedObjectStat(PoolStat stat) | ||
| 77 | { | ||
| 78 | stat->fCount++; | ||
| 79 | } | ||
| 80 | |||
| 81 | |||
| 82 | static 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 | |||
| 110 | static 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 | |||
| 136 | static 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 | |||
| 150 | static 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 | |||
| 214 | static 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 | |||
| 233 | int 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 | |||
| 9 | RequiresVariant 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. | ||
| 16 | ImplementsVariant generic_MPS ; | ||
| 17 | |||
| 18 | |||
| 19 | # Determine which MPS platform code matches this target. | ||
| 20 | local MPSOS ; local MPSPF ; | ||
| 21 | switch $(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 | } | ||
| 39 | if ! $(MPSPF) { | ||
| 40 | Error Cannot determine MPS platform for target $(TargetOS)-$(TargetArch) ; | ||
| 41 | } | ||
| 42 | |||
| 43 | |||
| 44 | # Set MPS configuration | ||
| 45 | |||
| 46 | AddToVar Inherited Local : C-Defines : CONFIG_PF_$(MPSPF:U) ; | ||
| 47 | |||
| 48 | AddToVar Inherited Local : C-Defines : CONFIG_PROD_EPCORE | ||
| 49 | : Variant Non_generic_MPS ; | ||
| 50 | AddToVar Inherited Local : C-Defines : CONFIG_PROD_MPS | ||
| 51 | : Variant generic_MPS ; | ||
| 52 | AddToVar Inherited Local : Suffix : mps : Variant generic_MPS ; | ||
| 53 | |||
| 54 | AddToVar Inherited Local : C-Defines : CONFIG_ASSERT : Build ASSERT ; | ||
| 55 | AddToVar 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 | |||
| 67 | AddToVar Local : VariantMPSsources | ||
| 68 | : prmcan.c protsw.c ssan.c than.c | ||
| 69 | mpsioan.c poolepdl.c poolepvm.c | ||
| 70 | : Variant Non_generic_MPS ; | ||
| 71 | |||
| 72 | switch $(MPSPF) { | ||
| 73 | case 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 ; | ||
| 79 | case 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 ; | ||
| 85 | case 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 ; | ||
| 91 | case 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 ; | ||
| 96 | case 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 ; | ||
| 101 | case 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 ; | ||
| 108 | case 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 ; | ||
| 113 | case 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 ; | ||
| 118 | case * : | ||
| 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 | |||
| 196 | rule 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 | ||
| 19 | SRCID(message, "$Id$"); | 20 | SRCID(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 | |||
| 18 | SRCID(mpm, "$Id$"); | 18 | SRCID(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 | |||
| 29 | unsigned CheckLevel = CHECK_DEFAULT; | ||
| 30 | |||
| 31 | |||
| 21 | /* MPMCheck -- test MPM assumptions */ | 32 | /* MPMCheck -- test MPM assumptions */ |
| 22 | 33 | ||
| 23 | Bool MPMCheck(void) | 34 | Bool 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 | ||
| 117 | Bool (WordIsAligned)(Word word, Align align) | 131 | Bool (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); | |||
| 156 | extern char *MPSVersion(void); | 157 | extern 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 */ | ||
| 162 | extern 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 */ | ||
| 167 | extern 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 */ | ||
| 174 | extern 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 */ | ||
| 181 | extern 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 | |||
| 188 | extern Res BTCreate(BT *btReturn, Arena arena, Count length); | ||
| 189 | extern void BTDestroy(BT bt, Arena arena, Count length); | ||
| 190 | extern void BTSetRange(BT bt, Index base, Index limit); | ||
| 191 | extern Bool BTIsSetRange(BT bt, Index base, Index limit); | ||
| 192 | extern void BTResRange(BT bt, Index base, Index limit); | ||
| 193 | extern Bool BTIsResRange(BT bt, Index base, Index limit); | ||
| 194 | extern Bool BTFindShortResRange(Index *baseReturn, Index *limitReturn, | ||
| 195 | BT bt, Index searchBase, Index searchLimit, | ||
| 196 | unsigned long length); | ||
| 197 | extern Bool BTFindShortResRangeHigh(Index *baseReturn, Index *limitReturn, | ||
| 198 | BT bt, Index searchBase, Index searchLimit, | ||
| 199 | unsigned long length); | ||
| 200 | extern Bool BTFindLongResRange(Index *baseReturn, Index *limitReturn, | ||
| 201 | BT bt, Index searchBase, Index searchLimit, | ||
| 202 | unsigned long length); | ||
| 203 | extern Bool BTFindLongResRangeHigh(Index *baseReturn, Index *limitReturn, | ||
| 204 | BT bt, Index searchBase, Index searchLimit, | ||
| 205 | unsigned long length); | ||
| 206 | extern Bool BTRangesSame(BT BTx, BT BTy, Index base, Index limit); | ||
| 207 | extern void BTCopyInvertRange(BT fromBT, BT toBT, Index base, Index limit); | ||
| 208 | extern void BTCopyRange(BT fromBT, BT toBT, Index base, Index limit); | ||
| 209 | extern 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 | ||
| 216 | extern Res PoolInit(Pool pool, Arena arena, PoolClass class, ...); | 162 | extern Res PoolInit(Pool pool, Arena arena, PoolClass class, ...); |
| @@ -253,6 +199,7 @@ extern void PoolFixEmergency(Pool pool, ScanState ss, Seg seg, Addr *refIO); | |||
| 253 | extern void PoolReclaim(Pool pool, Trace trace, Seg seg); | 199 | extern void PoolReclaim(Pool pool, Trace trace, Seg seg); |
| 254 | extern void PoolWalk(Pool pool, Seg seg, FormattedObjectsStepMethod f, | 200 | extern void PoolWalk(Pool pool, Seg seg, FormattedObjectsStepMethod f, |
| 255 | void *v, unsigned long s); | 201 | void *v, unsigned long s); |
| 202 | extern void PoolFreeWalk(Pool pool, FreeBlockStepMethod f, void *p); | ||
| 256 | extern Res PoolTrivInit(Pool pool, va_list arg); | 203 | extern Res PoolTrivInit(Pool pool, va_list arg); |
| 257 | extern void PoolTrivFinish(Pool pool); | 204 | extern void PoolTrivFinish(Pool pool); |
| 258 | extern Res PoolNoAlloc(Addr *pReturn, Pool pool, Size size, | 205 | extern Res PoolNoAlloc(Addr *pReturn, Pool pool, Size size, |
| @@ -300,6 +247,7 @@ extern Res PoolTrivFramePop(Pool pool, Buffer buf, AllocFrame frame); | |||
| 300 | extern void PoolNoFramePopPending(Pool pool, Buffer buf, AllocFrame frame); | 247 | extern void PoolNoFramePopPending(Pool pool, Buffer buf, AllocFrame frame); |
| 301 | extern void PoolNoWalk(Pool pool, Seg seg, FormattedObjectsStepMethod step, | 248 | extern void PoolNoWalk(Pool pool, Seg seg, FormattedObjectsStepMethod step, |
| 302 | void *p, unsigned long s); | 249 | void *p, unsigned long s); |
| 250 | extern void PoolNoFreeWalk(Pool pool, FreeBlockStepMethod f, void *p); | ||
| 303 | extern PoolDebugMixin PoolNoDebugMixin(Pool pool); | 251 | extern PoolDebugMixin PoolNoDebugMixin(Pool pool); |
| 304 | extern BufferClass PoolNoBufferClass(void); | 252 | extern BufferClass PoolNoBufferClass(void); |
| 305 | 253 | ||
| @@ -584,6 +532,7 @@ extern Size ArenaAvail(Arena arena); | |||
| 584 | extern Res ArenaExtend(Arena, Addr base, Size size); | 532 | extern Res ArenaExtend(Arena, Addr base, Size size); |
| 585 | 533 | ||
| 586 | extern Res ArenaFinalize(Arena arena, Ref obj); | 534 | extern Res ArenaFinalize(Arena arena, Ref obj); |
| 535 | extern Res ArenaDefinalize(Arena arena, Ref obj); | ||
| 587 | 536 | ||
| 588 | extern Bool ArenaIsReservedAddr(Arena arena, Addr addr); | 537 | extern Bool ArenaIsReservedAddr(Arena arena, Addr addr); |
| 589 | 538 | ||
| @@ -611,7 +560,7 @@ extern Res ArenaNoExtend(Arena arena, Addr base, Size size); | |||
| 611 | 560 | ||
| 612 | extern Bool SegPrefCheck(SegPref pref); | 561 | extern Bool SegPrefCheck(SegPref pref); |
| 613 | extern SegPref SegPrefDefault(void); | 562 | extern SegPref SegPrefDefault(void); |
| 614 | extern Res SegPrefExpress(SegPref pref, SegPrefKind kind, void *p); | 563 | extern void SegPrefExpress(SegPref pref, SegPrefKind kind, void *p); |
| 615 | 564 | ||
| 616 | extern void LocusInit(Arena arena); | 565 | extern void LocusInit(Arena arena); |
| 617 | extern void LocusFinish(Arena arena); | 566 | extern 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 | ||
| 26 | static 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 | |
| 30 | static 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 | ||
| 91 | static size_t randomSize(int i) | 99 | static 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 | |||
| 111 | static 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 | |||
| 101 | static size_t fixedSizeSize = 0; | 121 | static size_t fixedSizeSize = 0; |
| 102 | 122 | ||
| 103 | static size_t fixedSize(int i) | 123 | static size_t fixedSize(int i) |
| @@ -107,23 +127,35 @@ static size_t fixedSize(int i) | |||
| 107 | } | 127 | } |
| 108 | 128 | ||
| 109 | 129 | ||
| 110 | static mps_pool_debug_option_s debugOptions = { (void *)"postpost", 8 }; | 130 | /* testInArena -- test all the pool classes in the given arena */ |
| 131 | |||
| 132 | static mps_pool_debug_option_s bothOptions = | ||
| 133 | { (void *)"postpost", 8, (void *)"DEAD", 4 }; | ||
| 134 | |||
| 135 | static mps_pool_debug_option_s fenceOptions = | ||
| 136 | { (void *)"\0XXX ''\"\"'' XXX\0", 16, NULL, 0 }; | ||
| 111 | 137 | ||
| 112 | static int testInArena(mps_arena_t arena) | 138 | static 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 */ |
| 140 | typedef void (*FormattedObjectsStepMethod)(Addr, Format, Pool, | 141 | typedef 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 */ | ||
| 145 | typedef 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); |
| 213 | typedef void (*PoolWalkMethod)(Pool pool, Seg seg, | 218 | typedef void (*PoolWalkMethod)(Pool pool, Seg seg, |
| 214 | FormattedObjectsStepMethod f, | 219 | FormattedObjectsStepMethod f, |
| 215 | void *p, unsigned long s); | 220 | void *v, unsigned long s); |
| 221 | typedef void (*PoolFreeWalkMethod)(Pool pool, FreeBlockStepMethod f, void *p); | ||
| 216 | typedef BufferClass (*PoolBufferClassMethod)(void); | 222 | typedef BufferClass (*PoolBufferClassMethod)(void); |
| 217 | typedef Res (*PoolDescribeMethod)(Pool pool, mps_lib_FILE *stream); | 223 | typedef Res (*PoolDescribeMethod)(Pool pool, mps_lib_FILE *stream); |
| 218 | typedef PoolDebugMixin (*PoolDebugMixinMethod)(Pool pool); | 224 | typedef 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 */ |
| 296 | enum { | 302 | enum { |
| 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 | ||
| 42 | typedef MPS_T_WORD mps_word_t; /* machine word (target dep.) */ | 42 | typedef unsigned long mps_word_t; /* pointer-sized word */ |
| 43 | typedef int mps_bool_t; /* boolean (int) */ | 43 | typedef int mps_bool_t; /* boolean (int) */ |
| 44 | typedef int mps_res_t; /* result code (int) */ | 44 | typedef int mps_res_t; /* result code (int) */ |
| 45 | typedef unsigned mps_shift_t; /* shift amount (unsigned int) */ | 45 | typedef 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. */ |
| 136 | typedef struct mps_sac_classes_s { | 136 | typedef 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 | ||
| 215 | typedef 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 | |||
| 227 | typedef void (*mps_assert_t)(const char *, const char *, const char *, | ||
| 228 | unsigned); | ||
| 229 | |||
| 230 | extern mps_assert_t mps_assert_install(mps_assert_t); | ||
| 231 | extern mps_assert_t mps_assert_default(void); | ||
| 232 | |||
| 233 | |||
| 234 | /* arenas */ | 236 | /* arenas */ |
| 235 | 237 | ||
| 236 | extern void mps_arena_clamp(mps_arena_t); | 238 | extern 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 *); |
| 279 | extern mps_res_t mps_fmt_create_auto_header(mps_fmt_t *, mps_arena_t, | 281 | extern 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 *); |
| 283 | extern mps_res_t mps_fmt_create_fixed(mps_fmt_t *, mps_arena_t, | ||
| 284 | mps_fmt_fixed_s *); | ||
| 281 | extern void mps_fmt_destroy(mps_fmt_t); | 285 | extern 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 | ||
| 483 | typedef void *(*mps_tramp_t)(void *, size_t); | 487 | typedef void *(*mps_tramp_t)(void *, size_t); |
| 484 | |||
| 485 | extern void (mps_tramp)(void **, mps_tramp_t, void *, size_t); | 488 | extern 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 | |||
| 500 | extern mps_res_t mps_thread_reg(mps_thr_t *, mps_arena_t); | 490 | extern mps_res_t mps_thread_reg(mps_thr_t *, mps_arena_t); |
| 501 | extern void mps_thread_dereg(mps_thr_t); | 491 | extern 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 | ||
| 544 | extern mps_res_t mps_finalize(mps_arena_t, mps_addr_t *); | 534 | extern mps_res_t mps_finalize(mps_arena_t, mps_addr_t *); |
| 545 | extern void mps_definalize(mps_arena_t, mps_addr_t *); | 535 | extern 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 | ||
| 579 | typedef struct mps_pool_debug_option_s { | 569 | typedef 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 | ||
| 584 | extern void mps_pool_check_fenceposts(mps_pool_t); | 576 | extern void mps_pool_check_fenceposts(mps_pool_t); |
| 577 | extern 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 | ||
| 12 | extern mps_class_t mps_class_ams(void); | 13 | extern mps_class_t mps_class_ams(void); |
| 14 | extern 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 | ||
| 189 | mps_assert_t mps_assert_install(mps_assert_t handler) | ||
| 190 | { | ||
| 191 | AVER(handler != NULL); | ||
| 192 | return AssertInstall(handler); | ||
| 193 | } | ||
| 194 | |||
| 195 | mps_assert_t mps_assert_default(void) | ||
| 196 | { | ||
| 197 | return AssertDefault(); | ||
| 198 | } | ||
| 199 | |||
| 200 | |||
| 201 | mps_res_t mps_arena_extend(mps_arena_t mps_arena, | 190 | mps_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 | ||
| 447 | mps_bool_t mps_arena_has_addr(mps_arena_t mps_arena, mps_addr_t p) | 437 | mps_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 | |||
| 562 | mps_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 | ||
| 572 | void mps_fmt_destroy(mps_fmt_t mps_fmt) | 597 | void 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 | ||
| 1467 | mps_res_t mps_finalize(mps_arena_t mps_arena, mps_addr_t *refref) | 1492 | mps_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 | ||
| 1482 | void mps_definalize(mps_arena_t arena, mps_addr_t *refref) | 1507 | |
| 1508 | /* mps_definalize -- deregister for finalization */ | ||
| 1509 | |||
| 1510 | mps_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 = ▮ | 425 | void *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(®_root, arena, | 434 | die(mps_root_create_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 | ||
| 15 | SRCID(mpsint, "$Id$"); | 15 | SRCID(mpsiw3, "$Id$"); |
| 16 | 16 | ||
| 17 | /* This is defined in protnt.c */ | 17 | |
| 18 | /* This is defined in protw3.c */ | ||
| 18 | extern LONG ProtSEHfilter(LPEXCEPTION_POINTERS info); | 19 | extern LONG ProtSEHfilter(LPEXCEPTION_POINTERS info); |
| 19 | 20 | ||
| 20 | LONG mps_SEH_filter(LPEXCEPTION_POINTERS info, | 21 | LONG 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); | |||
| 29 | extern int mps_lib_fputc(int, mps_lib_FILE *); | 29 | extern int mps_lib_fputc(int, mps_lib_FILE *); |
| 30 | extern int mps_lib_fputs(const char *, mps_lib_FILE *); | 30 | extern int mps_lib_fputs(const char *, mps_lib_FILE *); |
| 31 | 31 | ||
| 32 | 32 | extern void mps_lib_assert_fail(const char *); | |
| 33 | extern void mps_lib_abort(void); | ||
| 34 | |||
| 35 | 33 | ||
| 36 | extern void *(mps_lib_memset)(void *, int, size_t); | 34 | extern void *(mps_lib_memset)(void *, int, size_t); |
| 37 | extern void *(mps_lib_memcpy)(void *, const void *, size_t); | 35 | extern 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 | ||
| 81 | void mps_lib_abort(void) | 82 | void 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 | ||
| 17 | extern LONG mps_SEH_filter(LPEXCEPTION_POINTERS, void **, size_t *); | 17 | extern LONG mps_SEH_filter(LPEXCEPTION_POINTERS, void **, size_t *); |
| 18 | extern void mps_SEH_handler(void *, size_t); | 18 | extern 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 | ||
| 457 | void PoolWalk(Pool pool, Seg seg, FormattedObjectsStepMethod f, | 464 | void 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 | |||
| 481 | void 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 | ||
| 471 | Res PoolDescribe(Pool pool, mps_lib_FILE *stream) | 493 | Res 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 | ||
| 625 | void 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 | |||
| 623 | BufferClass PoolNoBufferClass(void) | 637 | BufferClass 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 | ||
| 13 | SRCID(poolamc, "$Id$"); | 15 | SRCID(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 | ||
| 1732 | adjustColour: | ||
| 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 | |||
| 32 | typedef struct AMSDebugStruct { | ||
| 33 | AMSStruct amsStruct; /* AMS structure */ | ||
| 34 | PoolDebugMixinStruct debug; /* debug mixin */ | ||
| 35 | } AMSDebugStruct; | ||
| 36 | |||
| 37 | typedef 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 | ||
| 30 | Bool AMSSegCheck(AMSSeg amsseg) | 47 | Bool 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 | |||
| 83 | void 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 | |||
| 114 | static void amsFreeBlockCheckStep(Addr base, Addr limit, Pool pool, void *p) | ||
| 115 | { | ||
| 116 | UNUSED(p); | ||
| 117 | DebugPoolFreeCheck(pool, base, limit); | ||
| 118 | } | ||
| 119 | |||
| 120 | void 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 | ||
| 58 | static Res amsCreateTables(BT *allocReturn, | 143 | static 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 | ||
| 97 | static void amsDestroyTables(BT allocTable, | 186 | static 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 | ||
| 302 | failSuper: | 393 | failSuper: |
| 303 | amsDestroyTables(allocTable, nongreyTable, nonwhiteTable, | 394 | amsDestroyTables(ams, allocTable, nongreyTable, nonwhiteTable, |
| 304 | arena, allGrains); | 395 | arena, allGrains); |
| 305 | failCreateTables: | 396 | failCreateTables: |
| 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 | ||
| 405 | failSuper: | 496 | failSuper: |
| 406 | amsDestroyTables(allocTableHi, nongreyTableHi, nonwhiteTableHi, | 497 | amsDestroyTables(ams, allocTableHi, nongreyTableHi, nonwhiteTableHi, |
| 407 | arena, hiGrains); | 498 | arena, hiGrains); |
| 408 | failCreateTablesHi: | 499 | failCreateTablesHi: |
| 409 | amsDestroyTables(allocTableLo, nongreyTableLo, nonwhiteTableLo, | 500 | amsDestroyTables(ams, allocTableLo, nongreyTableLo, nonwhiteTableLo, |
| 410 | arena, loGrains); | 501 | arena, loGrains); |
| 411 | failCreateTablesLo: | 502 | failCreateTablesLo: |
| 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 | ||
| 637 | static 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 | ||
| 665 | Res AMSInitInternal(AMS ams, Format format, Chain chain) | 759 | Res 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 | */ |
| 731 | static Bool amsSegAlloc(Index *baseReturn, Index *limitReturn, | 825 | static 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 | */ |
| 782 | Res AMSBufferFill(Addr *baseReturn, Addr *limitReturn, | 879 | static 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 | ||
| 836 | found: | 936 | found: |
| 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 | */ |
| 854 | void AMSBufferEmpty(Pool pool, Buffer buffer, Addr init, Addr limit) | 954 | static 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 | */ |
| 914 | static void amsRangeCondemn(Seg seg, Index base, Index limit) | 1019 | static 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 | ||
| 940 | Res AMSWhiten(Pool pool, Trace trace, Seg seg) | 1034 | static 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. */ | ||
| 1110 | typedef 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 | |
| 999 | static Res AMSIterate(Seg seg, AMSObjectFunction f, void *closure) | 1127 | static 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 | ||
| 1062 | struct amsScanClosureStruct { | 1209 | struct 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 | ||
| 1204 | Res AMSFix(Pool pool, ScanState ss, Seg seg, Ref *refIO) | 1358 | static 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 | */ |
| 1297 | void AMSBlacken(Pool pool, TraceSet traceSet, Seg seg) | 1455 | static 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 | ||
| 1321 | void AMSReclaim(Pool pool, Trace trace, Seg seg) | 1479 | static 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 | |||
| 1548 | static 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 | |||
| 1636 | static 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 | |||
| 1650 | DEFINE_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 | ||
| 1456 | Bool AMSCheck(AMS ams) | 1662 | Bool 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 | |||
| 1478 | mps_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); | |||
| 32 | typedef Res (*AMSSegSizePolicyFunction)(Size *sizeReturn, | 35 | typedef 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. */ | ||
| 37 | typedef 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 | |||
| 47 | typedef Res (*AMSIterateFunction)(Seg seg, AMSObjectFunction f, void *closure); | ||
| 48 | 38 | ||
| 49 | 39 | ||
| 50 | typedef struct AMSStruct { | 40 | typedef 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 | ||
| 175 | extern Res AMSInitInternal(AMS ams, Format format, Chain chain); | 168 | extern Res AMSInitInternal(AMS ams, Format format, Chain chain, |
| 169 | Bool shareAllocTable); | ||
| 176 | extern void AMSFinish(Pool pool); | 170 | extern void AMSFinish(Pool pool); |
| 177 | extern Bool AMSCheck(AMS ams); | 171 | extern Bool AMSCheck(AMS ams); |
| 178 | 172 | ||
| 179 | extern Res AMSBufferInit(Pool pool, Buffer buffer, va_list args); | ||
| 180 | extern Res AMSBufferFill(Addr *baseReturn, Addr *limitReturn, | ||
| 181 | Pool pool, Buffer buffer, Size size, | ||
| 182 | Bool withReservoirPermit); | ||
| 183 | extern void AMSBufferEmpty(Pool pool, Buffer buffer, | ||
| 184 | Addr init, Addr limit); | ||
| 185 | |||
| 186 | extern Res AMSWhiten(Pool pool, Trace trace, Seg seg); | ||
| 187 | extern Res AMSScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg); | 173 | extern Res AMSScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg); |
| 188 | extern Res AMSFix(Pool pool, ScanState ss, Seg seg, Ref *refIO); | ||
| 189 | extern void AMSBlacken(Pool pool, TraceSet traceSet, Seg seg); | ||
| 190 | extern void AMSReclaim(Pool pool, Trace trace, Seg seg); | ||
| 191 | 174 | ||
| 192 | #define AMSChain(ams) ((ams)->chain) | 175 | #define AMSChain(ams) ((ams)->chain) |
| 193 | 176 | ||
| 177 | extern void AMSSegFreeWalk(AMSSeg amsseg, FreeBlockStepMethod f, void *p); | ||
| 178 | |||
| 179 | extern void AMSSegFreeCheck(AMSSeg amsseg); | ||
| 180 | |||
| 194 | 181 | ||
| 195 | typedef SegClass AMSSegClass; | 182 | typedef SegClass AMSSegClass; |
| 196 | typedef SegClassStruct AMSSegClassStruct; | 183 | typedef SegClassStruct AMSSegClassStruct; |
| @@ -202,6 +189,7 @@ typedef PoolClass AMSPoolClass; | |||
| 202 | typedef PoolClassStruct AMSPoolClassStruct; | 189 | typedef PoolClassStruct AMSPoolClassStruct; |
| 203 | 190 | ||
| 204 | extern AMSPoolClass AMSPoolClassGet(void); | 191 | extern AMSPoolClass AMSPoolClassGet(void); |
| 192 | extern 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 | |||
| 12 | SRCID(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 | |||
| 17 | mps_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 | |||
| 25 | mps_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 | |||
| 47 | SRCID(poolawl, "$Id$"); | 46 | SRCID(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 */ |
| 38 | enum { | 41 | enum { |
| 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 | ||
| 48 | typedef struct LinkStruct *Link; | 50 | typedef struct LinkStruct *Link; |
| 49 | typedef struct LinkStruct { | 51 | typedef 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 | |||
| 329 | static RefPart MRGRefPartOfLink(Link link, Arena arena) | 333 | static 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 | ||
| 355 | static Link MRGLinkOfRefPart(RefPart refPart, Arena arena) | 362 | static 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 | ||
| 400 | static void MRGMessageDelete(Message message) | 408 | static 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 | ||
| 552 | static void MRGFinalize(Arena arena, MRGLinkSeg linkseg, Index index) | 551 | static 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 | |||
| 689 | Res MRGRegister(Pool pool, Ref ref) | 690 | Res 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 | ||
| 736 | static void MRGFree(Pool pool, Addr old, Size size) | 736 | Res 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 | ||
| 14 | typedef struct MRGStruct *MRG; | 14 | typedef struct MRGStruct *MRG; |
| 15 | 15 | ||
| 16 | extern PoolClass PoolClassMRG(void); | 16 | extern PoolClass PoolClassMRG(void); |
| 17 | extern Res MRGRegister(Pool, Ref); | 17 | extern Res MRGRegister(Pool, Ref); |
| 18 | extern 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 | |||
| 43 | Pool (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 { | |||
| 57 | typedef MVDebugStruct *MVDebug; | 51 | typedef 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 | ||
| 50 | extern Bool MVCheck(MV mv); | 51 | extern Bool MVCheck(MV mv); |
| 51 | 52 | ||
| 52 | #define MVPool(mv) (&(mv)->poolStruct) | 53 | #define MV2Pool(mv) (&(mv)->poolStruct) |
| 53 | extern 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 { | |||
| 71 | typedef MVFFDebugStruct *MVFFDebug; | 72 | typedef 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 | |||
| 480 | failInit: | ||
| 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) | |||
| 640 | static Bool MVFFCheck(MVFF mvff) | 649 | static 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 | ||
| 41 | int main(void) | 41 | int 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 | |||
| 25 | SRCID(poolsnc, "$Id$"); | 24 | SRCID(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 | ||
| 3 | rem $Id$ | ||
| 4 | rem Copyright (c) 2001 Ravenbrook Limited. | ||
| 5 | nmake /f w3i3mv.nmk VARIETY=ci mmdw.lib mpsplan.lib | ||
| 6 | nmake /f w3i3mv.nmk VARIETY=hi mmdw.lib mpsplan.lib | ||
| 7 | nmake /f w3i3mv.nmk VARIETY=he mmdw.lib mpsplan.lib | ||
| 8 | nmake /f w3i3mv.nmk VARIETY=wi mmdw.lib mpsplan.lib | ||
| 9 | rmdir /Q/S dylan | ||
| 10 | mkdir dylan | ||
| 11 | mkdir dylan\mps | ||
| 12 | mkdir dylan\mps\include | ||
| 13 | mkdir dylan\mps\lib | ||
| 14 | mkdir dylan\mps\lib\w3i3 | ||
| 15 | mkdir dylan\mps\lib\w3i3\ci | ||
| 16 | mkdir dylan\mps\lib\w3i3\hi | ||
| 17 | mkdir dylan\mps\lib\w3i3\he | ||
| 18 | mkdir dylan\mps\lib\w3i3\wi | ||
| 19 | mkdir dylan\mps\src | ||
| 20 | copy mps.h dylan\mps\include | ||
| 21 | copy mpsavm.h dylan\mps\include | ||
| 22 | copy mpscamc.h dylan\mps\include | ||
| 23 | copy mpscawl.h dylan\mps\include | ||
| 24 | copy mpsclo.h dylan\mps\include | ||
| 25 | copy mpscsnc.h dylan\mps\include | ||
| 26 | copy mpscmv.h dylan\mps\include | ||
| 27 | copy mpsio.h dylan\mps\include | ||
| 28 | copy mpslib.h dylan\mps\include | ||
| 29 | copy mpstd.h dylan\mps\include | ||
| 30 | copy mpsw3.h dylan\mps\include | ||
| 31 | copy mpswin.h dylan\mps\include | ||
| 32 | copy w3i3mv\ci\mmdw.lib dylan\mps\lib\w3i3\ci | ||
| 33 | copy w3i3mv\hi\mmdw.lib dylan\mps\lib\w3i3\hi | ||
| 34 | copy w3i3mv\he\mmdw.lib dylan\mps\lib\w3i3\he | ||
| 35 | copy w3i3mv\wi\mmdw.lib dylan\mps\lib\w3i3\wi | ||
| 36 | copy w3i3mv\ci\mpsplan.lib dylan\mps\lib\w3i3\ci | ||
| 37 | copy w3i3mv\hi\mpsplan.lib dylan\mps\lib\w3i3\hi | ||
| 38 | copy w3i3mv\he\mpsplan.lib dylan\mps\lib\w3i3\he | ||
| 39 | copy w3i3mv\wi\mpsplan.lib dylan\mps\lib\w3i3\wi | ||
| 40 | copy mpsliban.c dylan\mps\src | ||
| 41 | copy 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 | |||
| 14 | SRCID(protocol, "$Id$"); | 13 | SRCID(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) | |||
| 372 | Size ReservoirAvailable(Reservoir reservoir) | 372 | Size 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 | |||
| 20 | SRCID(ring, "$Id$"); | 19 | SRCID(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 | |||
| 40 | static mps_res_t make(mps_addr_t *p, mps_sac_t sac, size_t size) | 42 | static 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 | ||
| 49 | static 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 | |||
| 53 | static 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 | |||
| 132 | static size_t randomSize8(int i) | 138 | static 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 | ||
| 143 | static mps_pool_debug_option_s debugOptions = { (void *)"postpost", 8 }; | 149 | /* testInArena -- test all the pool classes in the given arena */ |
| 150 | |||
| 151 | static mps_pool_debug_option_s debugOptions = | ||
| 152 | { (void *)"postpost", 8, NULL, 0 }; | ||
| 144 | 153 | ||
| 145 | static mps_sac_classes_s classes[4] = { {8, 1, 1}, {16, 1, 2}, {136, 9, 5}, | 154 | static 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}, | |||
| 148 | static int testInArena(mps_arena_t arena) | 157 | static 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 | |||
| 720 | static mps_pool_t pool; | 725 | static mps_pool_t pool; |
| 721 | static mps_ap_t ap; | 726 | static mps_ap_t ap; |
| 722 | static mps_addr_t exactRoots[exactRootsCOUNT]; | 727 | static mps_addr_t exactRoots[exactRootsCOUNT]; |
| @@ -724,6 +729,8 @@ static mps_addr_t ambigRoots[ambigRootsCOUNT]; | |||
| 724 | static size_t totalSize = 0; | 729 | static size_t totalSize = 0; |
| 725 | 730 | ||
| 726 | 731 | ||
| 732 | /* make -- object allocation and init */ | ||
| 733 | |||
| 727 | static mps_addr_t make(void) | 734 | static 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 | |||
| 747 | static void *test(void *arg, size_t s) | 756 | static 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 | |||
| 27 | end | ||
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 | |||
| 17 | void 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 | |||
| 21 | SRCID(splay, "$Id$"); | 20 | SRCID(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 | |||
| 36 | Bool SplayTreeCheck(SplayTree tree) | 39 | Bool 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 | |||
| 45 | Bool SplayNodeCheck(SplayNode node) | 49 | Bool 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 | |||
| 67 | void SplayNodeInit(SplayNode node) | 72 | void 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 | |||
| 78 | void SplayNodeFinish(SplayNode node) | 84 | void 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 | |||
| 87 | void SplayTreeFinish(SplayTree tree) | 94 | void 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 | |||
| 94 | static void SplayNodeUpdate(SplayTree tree, SplayNode node) | 102 | static 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 | ||
| 443 | terminalZig: | 456 | terminalZig: |
| 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 | |||
| 566 | Res SplayTreeSearch(SplayNode *nodeReturn, SplayTree tree, void *key) { | 578 | Res 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 | |||
| 792 | typedef struct { | 800 | typedef 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 | ||
| 35 | SRCID(sslii3, "$Id$"); | 35 | SRCID(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 | |||
| 37 | SRCID(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 | |||
| 44 | Res 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 | |||
| 8 | PFM = sus8lc | ||
| 9 | |||
| 10 | MPMPF = mpsliban.c mpsioan.c lockan.c than.c vmsu.c \ | ||
| 11 | protsu.c prmcan.c span.c | ||
| 12 | MPMS = sssus8.s | ||
| 13 | |||
| 14 | include 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 | |||
| 17 | SRCID(teletest, "$Id$"); | 16 | SRCID(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 |
| 15 | struct itimerspec; /* stop complaints from time.h */ | 17 | struct 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 | ||
| 28 | unsigned long rnd(void) | 29 | unsigned 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 | |||
| 49 | mps_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 | ||
| 42 | void randomize(int argc, char **argv) | 63 | void 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); | |||
| 140 | extern unsigned long rnd(void); | 144 | extern 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 | |||
| 152 | extern 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 | ||
| 16 | SRCID(tract, "$Id$"); | 17 | SRCID(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 | |||
| 21 | SRCID(version, "$Id$"); | 19 | SRCID(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 | ||
| 40 | char MPSCopyrightNotice[] = | 38 | char 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 @@ | |||
| 56 | SRCID(vmso, "$Id$"); | 58 | SRCID(vmso, "$Id$"); |
| 57 | 59 | ||
| 58 | 60 | ||
| 59 | /* Fix up unprototyped system calls. */ | ||
| 60 | |||
| 61 | extern int close(int fd); | ||
| 62 | extern 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 | |||
| 81 | Align VMAlign(VM vm) | 79 | Align 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 | |||
| 88 | Bool VMCheck(VM vm) | 88 | Bool 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 | |||
| 105 | Res VMCreate(VM *vmReturn, Size size) | 107 | Res 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 | ||
| 177 | failReserve: | 179 | failReserve: |
| 178 | (void)munmap((caddr_t)vm, (size_t)SizeAlignUp(sizeof(VMStruct), align)); | 180 | (void)munmap((void *)vm, (size_t)SizeAlignUp(sizeof(VMStruct), align)); |
| 179 | failVMMap: | 181 | failVMMap: |
| 180 | (void)close(none_fd); /* see .close.fail */ | 182 | (void)close(none_fd); /* see .close.fail */ |
| 181 | failNoneOpen: | 183 | failNoneOpen: |
| @@ -184,6 +186,8 @@ failNoneOpen: | |||
| 184 | } | 186 | } |
| 185 | 187 | ||
| 186 | 188 | ||
| 189 | /* VMDestroy -- destroy the VM structure */ | ||
| 190 | |||
| 187 | void VMDestroy(VM vm) | 191 | void 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 | |||
| 216 | Addr VMBase(VM vm) | 222 | Addr 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 | |||
| 222 | Addr VMLimit(VM vm) | 231 | Addr 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 | |||
| 229 | Size VMReserved(VM vm) | 240 | Size 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 | |||
| 235 | Size VMMapped(VM vm) | 249 | Size 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 | |||
| 242 | Res VMMap(VM vm, Addr base, Addr limit) | 258 | Res 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 | |||
| 278 | void VMUnmap(VM vm, Addr base, Addr limit) | 296 | void 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 | ||
| 11 | PFMDEFS = /DWIN32 /D_WINDOWS /I$(RAINBOWPATH) | 11 | PFMDEFS = /DWIN32 /D_WINDOWS /I$(RAINBOWPATH) |
| 12 | 12 | ||
| 13 | MPM = <assert> <ring> <mpm> <bt> <protocol> <boot> \ | 13 | MPM = <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> |
| 24 | SW = <assert> <ring> <mpm> <bt> <protocol> \ | 24 | SW = <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> |
| 33 | PLINTH = <mpsliban> <mpsioan> | 33 | PLINTH = <mpsliban> <mpsioan> |
| 34 | AMC = <poolamc> | 34 | AMC = <poolamc> |
| 35 | AMS = <poolams> | 35 | AMS = <poolams> <poolamsi> |
| 36 | AWL = <poolawl> | 36 | AWL = <poolawl> |
| 37 | LO = <poollo> | 37 | LO = <poollo> |
| 38 | DW = <fmtdy> <fmtno> | 38 | DW = <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 | ||
| 11 | PFMDEFS = /DWIN32 /D_WINDOWS /I$(RAINBOWPATH) | 11 | PFMDEFS = /DWIN32 /D_WINDOWS /I$(RAINBOWPATH) |
| 12 | 12 | ||
| 13 | MPM = <assert> <ring> <mpm> <bt> <protocol> <boot> \ | 13 | MPM = <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> |
| 21 | SW = <assert> <ring> <mpm> <bt> <protocol> <boot> \ | 21 | SW = <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> |
| 30 | CONFIGURA = <assert> <ring> <mpm> <bt> <protocol> <boot> \ | 30 | CONFIGURA = <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> |
| 38 | PLINTH = <mpsliban> <mpsioan> | 38 | PLINTH = <mpsliban> <mpsioan> |
| 39 | AMC = <poolamc> | 39 | AMC = <poolamc> |
| 40 | AMS = <poolams> | 40 | AMS = <poolams> <poolamsi> |
| 41 | AWL = <poolawl> | 41 | AWL = <poolawl> |
| 42 | LO = <poollo> | 42 | LO = <poollo> |
| 43 | SNC = <poolsnc> | 43 | SNC = <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 | ||
| 11 | PFMDEFS = /DWIN32 /D_WINDOWS /I$(RAINBOWPATH) | 11 | PFMDEFS = /DWIN32 /D_WINDOWS /I$(RAINBOWPATH) |
| 12 | 12 | ||
| 13 | MPM = <assert> <ring> <mpm> <bt> <protocol> <boot> \ | 13 | MPM = <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> |
| 21 | SW = <assert> <ring> <mpm> <bt> <protocol> <boot> \ | 21 | SW = <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> |
| 30 | PLINTH = <mpsliban> <mpsioan> | 30 | PLINTH = <mpsliban> <mpsioan> |
| 31 | AMC = <poolamc> | 31 | AMC = <poolamc> |
| 32 | AMS = <poolams> | 32 | AMS = <poolams> <poolamsi> |
| 33 | AWL = <poolawl> | 33 | AWL = <poolawl> |
| 34 | LO = <poollo> | 34 | LO = <poollo> |
| 35 | DW = <fmtdy> <fmtno> | 35 | DW = <fmtdy> <fmtno> |