diff options
| author | Nick Barnes | 2002-05-14 13:06:13 +0100 |
|---|---|---|
| committer | Nick Barnes | 2002-05-14 13:06:13 +0100 |
| commit | 833f5bf257e3acff6162176efc70f25ef005b037 (patch) | |
| tree | e41f7ed1e545bf2d69dd28431c149b424ea252f5 /mps/code | |
| parent | c5e9dc4c8402721d8ed29a368ea7604136c00341 (diff) | |
| download | emacs-833f5bf257e3acff6162176efc70f25ef005b037.tar.gz emacs-833f5bf257e3acff6162176efc70f25ef005b037.zip | |
Improve treatment of dylan formats: keep common code in fmtdy.c, header-specific code in fmthe.c, the null format in fmtno.[ch], and split out the prototypes for the test functions into fmtdytst.h.
Copied from Perforce
Change: 29145
ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
| -rw-r--r-- | mps/code/amcss.c | 5 | ||||
| -rw-r--r-- | mps/code/amcsshe.c | 97 | ||||
| -rw-r--r-- | mps/code/amsss.c | 1 | ||||
| -rw-r--r-- | mps/code/amssshe.c | 26 | ||||
| -rw-r--r-- | mps/code/awluthe.c | 1 | ||||
| -rw-r--r-- | mps/code/comm.gmk | 20 | ||||
| -rw-r--r-- | mps/code/finalcv.c | 1 | ||||
| -rw-r--r-- | mps/code/fmtdy.c | 113 | ||||
| -rw-r--r-- | mps/code/fmtdy.h | 17 | ||||
| -rw-r--r-- | mps/code/fmtdytst.c | 13 | ||||
| -rw-r--r-- | mps/code/fmtdytst.h | 21 | ||||
| -rw-r--r-- | mps/code/fmthe.c | 749 | ||||
| -rw-r--r-- | mps/code/fmthe.h | 20 | ||||
| -rw-r--r-- | mps/code/fmtno.c | 143 | ||||
| -rw-r--r-- | mps/code/fmtno.h | 24 | ||||
| -rw-r--r-- | mps/code/mpsicv.c | 3 | ||||
| -rw-r--r-- | mps/code/segsmss.c | 5 |
17 files changed, 367 insertions, 892 deletions
diff --git a/mps/code/amcss.c b/mps/code/amcss.c index 34983f61783..7b1308edb5f 100644 --- a/mps/code/amcss.c +++ b/mps/code/amcss.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include "fmtdy.h" | 7 | #include "fmtdy.h" |
| 8 | #include "fmtdytst.h" | ||
| 8 | #include "testlib.h" | 9 | #include "testlib.h" |
| 9 | #include "mpscamc.h" | 10 | #include "mpscamc.h" |
| 10 | #include "mpsavm.h" | 11 | #include "mpsavm.h" |
| @@ -50,7 +51,7 @@ static void enable(mps_arena_t arena) | |||
| 50 | static void report(mps_arena_t arena) | 51 | static void report(mps_arena_t arena) |
| 51 | { | 52 | { |
| 52 | mps_message_t message; | 53 | mps_message_t message; |
| 53 | 54 | ||
| 54 | while (mps_message_get(&message, arena, mps_message_type_gc())) { | 55 | while (mps_message_get(&message, arena, mps_message_type_gc())) { |
| 55 | size_t live, condemned, not_condemned; | 56 | size_t live, condemned, not_condemned; |
| 56 | 57 | ||
| @@ -163,7 +164,7 @@ static void *test(void *arg, size_t s) | |||
| 163 | break; | 164 | break; |
| 164 | } | 165 | } |
| 165 | } while(1); | 166 | } while(1); |
| 166 | 167 | ||
| 167 | report(arena); | 168 | report(arena); |
| 168 | for(r = 0; r < exactRootsCOUNT; ++r) | 169 | for(r = 0; r < exactRootsCOUNT; ++r) |
| 169 | cdie(exactRoots[r] == objNULL || | 170 | cdie(exactRoots[r] == objNULL || |
diff --git a/mps/code/amcsshe.c b/mps/code/amcsshe.c index 2be9e32be89..bc5de2f184c 100644 --- a/mps/code/amcsshe.c +++ b/mps/code/amcsshe.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include "fmthe.h" | 7 | #include "fmthe.h" |
| 8 | #include "fmtdytst.h" | ||
| 8 | #include "testlib.h" | 9 | #include "testlib.h" |
| 9 | #include "mpscamc.h" | 10 | #include "mpscamc.h" |
| 10 | #include "mpsavm.h" | 11 | #include "mpsavm.h" |
| @@ -44,100 +45,6 @@ static mps_addr_t exactRoots[exactRootsCOUNT]; | |||
| 44 | static mps_addr_t ambigRoots[ambigRootsCOUNT]; | 45 | static mps_addr_t ambigRoots[ambigRootsCOUNT]; |
| 45 | static mps_addr_t bogusRoots[bogusRootsCOUNT]; | 46 | static mps_addr_t bogusRoots[bogusRootsCOUNT]; |
| 46 | 47 | ||
| 47 | |||
| 48 | |||
| 49 | static mps_word_t *ww = NULL; | ||
| 50 | static mps_word_t *tvw; | ||
| 51 | |||
| 52 | |||
| 53 | static mps_word_t dylan_make_WV(mps_word_t version, mps_word_t vb, | ||
| 54 | mps_word_t es, mps_word_t vf) | ||
| 55 | { | ||
| 56 | /* VERSION- ... VB------ reserved ES---VF- */ | ||
| 57 | return((version << (MPS_WORD_WIDTH - 8)) | | ||
| 58 | (vb << 16) | | ||
| 59 | (es << 3) | | ||
| 60 | vf); | ||
| 61 | } | ||
| 62 | |||
| 63 | |||
| 64 | static mps_res_t init(mps_addr_t addr, size_t size, | ||
| 65 | mps_addr_t *refs, size_t nr_refs) | ||
| 66 | { | ||
| 67 | |||
| 68 | /* Make sure the size is aligned. */ | ||
| 69 | if ((size & (ALIGN-1)) != 0) return MPS_RES_PARAM; | ||
| 70 | |||
| 71 | if (ww == NULL) { | ||
| 72 | ww = malloc(sizeof(mps_word_t) * (BASIC_WRAPPER_SIZE + 1)); | ||
| 73 | if (ww == NULL) return MPS_RES_MEMORY; | ||
| 74 | tvw = malloc(sizeof(mps_word_t) * BASIC_WRAPPER_SIZE); | ||
| 75 | if (tvw == NULL) { | ||
| 76 | free(ww); | ||
| 77 | return MPS_RES_MEMORY; | ||
| 78 | } | ||
| 79 | |||
| 80 | /* Build a wrapper wrapper. */ | ||
| 81 | ww[WW] = (mps_word_t)ww; | ||
| 82 | ww[WC] = (mps_word_t)ww; /* dummy class */ | ||
| 83 | ww[WM] = (1 << 2) | 1; /* dummy subtype_mask */ | ||
| 84 | ww[WF] = ((WS - 1) << 2) | 2; | ||
| 85 | ww[WV] = dylan_make_WV(2, 0, 0, 0); | ||
| 86 | ww[WS] = (1 << 2) | 1; | ||
| 87 | ww[WP] = 1; | ||
| 88 | |||
| 89 | /* Build a wrapper for traceable vectors. */ | ||
| 90 | tvw[WW] = (mps_word_t)ww; | ||
| 91 | tvw[WC] = (mps_word_t)ww; /* dummy class */ | ||
| 92 | tvw[WM] = (1 << 2) | 1; /* dummy subtype_mask */ | ||
| 93 | tvw[WF] = 0; /* no fixed part */ | ||
| 94 | tvw[WV] = dylan_make_WV(2, 0, 0, 2); /* traceable variable part */ | ||
| 95 | tvw[WS] = 1; /* no patterns */ | ||
| 96 | } | ||
| 97 | |||
| 98 | /* If there is enough room, make a vector, otherwise just */ | ||
| 99 | /* make a padding object. */ | ||
| 100 | |||
| 101 | if (size >= sizeof(mps_word_t) * 2) { | ||
| 102 | mps_word_t *p = (mps_word_t *)addr; | ||
| 103 | mps_word_t i, t = (size / sizeof(mps_word_t)) - 2; | ||
| 104 | |||
| 105 | p[0] = (mps_word_t)tvw; /* install vector wrapper */ | ||
| 106 | p[1] = (t << 2) | 1; /* tag the vector length */ | ||
| 107 | for(i = 0; i < t; ++i) { | ||
| 108 | mps_word_t r = rnd(); | ||
| 109 | |||
| 110 | if (r & 1) | ||
| 111 | p[2+i] = ((r & ~(mps_word_t)3) | 1); /* random int */ | ||
| 112 | else | ||
| 113 | p[2+i] = (mps_word_t)refs[(r >> 1) % nr_refs]; /* random ptr */ | ||
| 114 | } | ||
| 115 | } else { | ||
| 116 | die(MPS_RES_FAIL, "small object"); | ||
| 117 | } | ||
| 118 | |||
| 119 | return MPS_RES_OK; | ||
| 120 | } | ||
| 121 | |||
| 122 | |||
| 123 | static void dylan_write(mps_addr_t addr, mps_addr_t *refs, size_t nr_refs) | ||
| 124 | { | ||
| 125 | mps_word_t *p = (mps_word_t *)addr; | ||
| 126 | mps_word_t t = p[1] >> 2; | ||
| 127 | |||
| 128 | /* If the object is a vector, update a random entry. */ | ||
| 129 | if (p[0] == (mps_word_t)tvw && t > 0) { | ||
| 130 | mps_word_t r = rnd(); | ||
| 131 | size_t i = 2 + (rnd() % t); | ||
| 132 | |||
| 133 | if (r & 1) | ||
| 134 | p[i] = ((r & ~(mps_word_t)3) | 1); /* random int */ | ||
| 135 | else | ||
| 136 | p[i] = (mps_word_t)refs[(r >> 1) % nr_refs]; /* random ptr */ | ||
| 137 | } | ||
| 138 | } | ||
| 139 | |||
| 140 | |||
| 141 | static mps_addr_t make(void) | 48 | static mps_addr_t make(void) |
| 142 | { | 49 | { |
| 143 | size_t length = rnd() % (2*avLEN); | 50 | size_t length = rnd() % (2*avLEN); |
| @@ -150,7 +57,7 @@ static mps_addr_t make(void) | |||
| 150 | if (res) | 57 | if (res) |
| 151 | die(res, "MPS_RESERVE_BLOCK"); | 58 | die(res, "MPS_RESERVE_BLOCK"); |
| 152 | userP = (mps_addr_t)((char*)p + headerSIZE); | 59 | userP = (mps_addr_t)((char*)p + headerSIZE); |
| 153 | res = init(userP, size, exactRoots, exactRootsCOUNT); | 60 | res = dylan_init(userP, size, exactRoots, exactRootsCOUNT); |
| 154 | if (res) | 61 | if (res) |
| 155 | die(res, "dylan_init"); | 62 | die(res, "dylan_init"); |
| 156 | ((int*)p)[0] = realHeader; | 63 | ((int*)p)[0] = realHeader; |
diff --git a/mps/code/amsss.c b/mps/code/amsss.c index 6cc24aba44b..2008334248e 100644 --- a/mps/code/amsss.c +++ b/mps/code/amsss.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | */ | 9 | */ |
| 10 | 10 | ||
| 11 | #include "fmtdy.h" | 11 | #include "fmtdy.h" |
| 12 | #include "fmtdytst.h" | ||
| 12 | #include "testlib.h" | 13 | #include "testlib.h" |
| 13 | #include "mpscams.h" | 14 | #include "mpscams.h" |
| 14 | #include "mpsavm.h" | 15 | #include "mpsavm.h" |
diff --git a/mps/code/amssshe.c b/mps/code/amssshe.c index 6cc24aba44b..b1e0a0435e8 100644 --- a/mps/code/amssshe.c +++ b/mps/code/amssshe.c | |||
| @@ -1,14 +1,13 @@ | |||
| 1 | /* impl.c.amsss: POOL CLASS AMS STRESS TEST | 1 | /* impl.c.amssshe: POOL CLASS AMS STRESS TEST WITH HEADERS |
| 2 | * | 2 | * |
| 3 | * $Id$ | 3 | * $Id$ |
| 4 | * Copyright (c) 2001 Ravenbrook Limited. | 4 | * Copyright (c) 2001 Ravenbrook Limited. |
| 5 | * | 5 | * |
| 6 | * .design: Adapted from amcss.c, but not counting collections, just | 6 | * .design: Adapted from amsss.c. |
| 7 | * total size of objects allocated (because epoch doesn't increment | ||
| 8 | * when AMS is collected). | ||
| 9 | */ | 7 | */ |
| 10 | 8 | ||
| 11 | #include "fmtdy.h" | 9 | #include "fmthe.h" |
| 10 | #include "fmtdytst.h" | ||
| 12 | #include "testlib.h" | 11 | #include "testlib.h" |
| 13 | #include "mpscams.h" | 12 | #include "mpscams.h" |
| 14 | #include "mpsavm.h" | 13 | #include "mpsavm.h" |
| @@ -25,7 +24,7 @@ | |||
| 25 | 24 | ||
| 26 | #define exactRootsCOUNT 50 | 25 | #define exactRootsCOUNT 50 |
| 27 | #define ambigRootsCOUNT 100 | 26 | #define ambigRootsCOUNT 100 |
| 28 | /* This is enough for three GCs. */ | 27 | /* This is enough for five GCs. */ |
| 29 | #define totalSizeMAX 800 * (size_t)1024 | 28 | #define totalSizeMAX 800 * (size_t)1024 |
| 30 | #define totalSizeSTEP 200 * (size_t)1024 | 29 | #define totalSizeSTEP 200 * (size_t)1024 |
| 31 | /* objNULL needs to be odd so that it's ignored in exactRoots. */ | 30 | /* objNULL needs to be odd so that it's ignored in exactRoots. */ |
| @@ -45,20 +44,23 @@ static size_t totalSize = 0; | |||
| 45 | static mps_addr_t make(void) | 44 | static mps_addr_t make(void) |
| 46 | { | 45 | { |
| 47 | size_t length = rnd() % 20, size = (length+2) * sizeof(mps_word_t); | 46 | size_t length = rnd() % 20, size = (length+2) * sizeof(mps_word_t); |
| 48 | mps_addr_t p; | 47 | mps_addr_t p, userP; |
| 49 | mps_res_t res; | 48 | mps_res_t res; |
| 50 | 49 | ||
| 51 | do { | 50 | do { |
| 52 | MPS_RESERVE_BLOCK(res, p, ap, size); | 51 | MPS_RESERVE_BLOCK(res, p, ap, size + headerSIZE); |
| 53 | if(res) | 52 | if(res) |
| 54 | die(res, "MPS_RESERVE_BLOCK"); | 53 | die(res, "MPS_RESERVE_BLOCK"); |
| 55 | res = dylan_init(p, size, exactRoots, exactRootsCOUNT); | 54 | userP = (mps_addr_t)((char*)p + headerSIZE); |
| 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 | } while(!mps_commit(ap, p, size)); | 58 | ((int*)p)[0] = realTYPE; |
| 59 | ((int*)p)[1] = 0xED0ED; | ||
| 60 | } while(!mps_commit(ap, p, size + headerSIZE)); | ||
| 59 | 61 | ||
| 60 | totalSize += size; | 62 | totalSize += size; |
| 61 | return p; | 63 | return userP; |
| 62 | } | 64 | } |
| 63 | 65 | ||
| 64 | 66 | ||
| @@ -76,7 +78,7 @@ static void *test(void *arg, size_t s) | |||
| 76 | arena = (mps_arena_t)arg; | 78 | arena = (mps_arena_t)arg; |
| 77 | (void)s; /* unused */ | 79 | (void)s; /* unused */ |
| 78 | 80 | ||
| 79 | die(mps_fmt_create_A(&format, arena, dylan_fmt_A()), "fmt_create"); | 81 | die(EnsureHeaderFormat(&format, arena), "make header format"); |
| 80 | die(mps_chain_create(&chain, arena, 1, testChain), "chain_create"); | 82 | die(mps_chain_create(&chain, arena, 1, testChain), "chain_create"); |
| 81 | die(mps_pool_create(&pool, arena, mps_class_ams(), format, chain), | 83 | die(mps_pool_create(&pool, arena, mps_class_ams(), format, chain), |
| 82 | "pool_create(ams)"); | 84 | "pool_create(ams)"); |
diff --git a/mps/code/awluthe.c b/mps/code/awluthe.c index cb3fe99f343..b5d0ddc52eb 100644 --- a/mps/code/awluthe.c +++ b/mps/code/awluthe.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include "mpsclo.h" | 12 | #include "mpsclo.h" |
| 13 | #include "mpsavm.h" | 13 | #include "mpsavm.h" |
| 14 | #include "fmthe.h" | 14 | #include "fmthe.h" |
| 15 | #include "fmtdy.h" | ||
| 15 | #include "testlib.h" | 16 | #include "testlib.h" |
| 16 | #include "mps.h" | 17 | #include "mps.h" |
| 17 | #include "mpstd.h" | 18 | #include "mpstd.h" |
diff --git a/mps/code/comm.gmk b/mps/code/comm.gmk index 8e3172f7c77..bc561b09d6a 100644 --- a/mps/code/comm.gmk +++ b/mps/code/comm.gmk | |||
| @@ -191,8 +191,9 @@ SNC = poolsnc.c | |||
| 191 | POOLN = pooln.c | 191 | POOLN = pooln.c |
| 192 | MVFF = poolmvff.c | 192 | MVFF = poolmvff.c |
| 193 | TESTLIB = testlib.c | 193 | TESTLIB = testlib.c |
| 194 | FMTDY = fmtdy.c | 194 | FMTDY = fmtdy.c fmtno.c |
| 195 | FMTDYTST = fmtdy.c fmtdytst.c | 195 | FMTDYTST = fmtdy.c fmtno.c fmtdytst.c |
| 196 | FMTHETST = fmthe.c fmtdy.c fmtno.c fmtdytst.c | ||
| 196 | FMTPS = fmtpstst.c | 197 | FMTPS = fmtpstst.c |
| 197 | PLINTH = mpsliban.c mpsioan.c | 198 | PLINTH = mpsliban.c mpsioan.c |
| 198 | EVENTPROC = eventcnv.c eventpro.c table.c | 199 | EVENTPROC = eventcnv.c eventpro.c table.c |
| @@ -262,7 +263,7 @@ TESTLIBDEP = $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.d) | |||
| 262 | FMTDYOBJ = $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.o) | 263 | FMTDYOBJ = $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.o) |
| 263 | FMTDYDEP = $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.d) | 264 | FMTDYDEP = $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.d) |
| 264 | FMTDYTSTOBJ = $(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.o) | 265 | FMTDYTSTOBJ = $(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.o) |
| 265 | FMTDYTSTDEP = $(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.d) | 266 | FMTHETSTOBJ = $(FMTHETST:%.c=$(PFM)/$(VARIETY)/%.o) |
| 266 | FMTPSOBJ = $(FMTPS:%.c=$(PFM)/$(VARIETY)/%.o) | 267 | FMTPSOBJ = $(FMTPS:%.c=$(PFM)/$(VARIETY)/%.o) |
| 267 | FMTPSDEP = $(FMTPS:%.c=$(PFM)/$(VARIETY)/%.d) | 268 | FMTPSDEP = $(FMTPS:%.c=$(PFM)/$(VARIETY)/%.d) |
| 268 | PLINTHOBJ = $(PLINTH:%.c=$(PFM)/$(VARIETY)/%.o) | 269 | PLINTHOBJ = $(PLINTH:%.c=$(PFM)/$(VARIETY)/%.o) |
| @@ -277,7 +278,7 @@ endif | |||
| 277 | # %%TARGET: Add the target to the all dependencies, if it uses the | 278 | # %%TARGET: Add the target to the all dependencies, if it uses the |
| 278 | # CONFIG_PROD_MPS configuration, to swall if CONFIG_PROD_EPCORE | 279 | # CONFIG_PROD_MPS configuration, to swall if CONFIG_PROD_EPCORE |
| 279 | 280 | ||
| 280 | all: mpmss sacss amcss amcsshe amsss segsmss awlut awluthe \ | 281 | all: mpmss sacss amcss amcsshe amsss amssshe segsmss awlut awluthe \ |
| 281 | mpsicv lockcov poolncv locv qs apss \ | 282 | mpsicv lockcov poolncv locv qs apss \ |
| 282 | finalcv arenacv bttest teletest \ | 283 | finalcv arenacv bttest teletest \ |
| 283 | abqtest cbstest btcv mv2test messtest \ | 284 | abqtest cbstest btcv mv2test messtest \ |
| @@ -289,7 +290,7 @@ swall: mmsw.a epvmss replaysw epdss | |||
| 289 | # These tests are run overnight (see design.buildsys.overnight). | 290 | # These tests are run overnight (see design.buildsys.overnight). |
| 290 | # bttest & teletest cannot be run unattended | 291 | # bttest & teletest cannot be run unattended |
| 291 | # mv2test cannot be run because MV2 is broken | 292 | # mv2test cannot be run because MV2 is broken |
| 292 | testrun: mpmss apss sacss amcss amcsshe amsss segsmss awlut awluthe \ | 293 | testrun: mpmss apss sacss amcss amcsshe amsss amssshe segsmss awlut awluthe \ |
| 293 | mpsicv lockcov poolncv locv qs finalcv arenacv \ | 294 | mpsicv lockcov poolncv locv qs finalcv arenacv \ |
| 294 | abqtest cbstest btcv messtest | 295 | abqtest cbstest btcv messtest |
| 295 | $(^:%=date && $(PFM)/$(VARIETY)/% &&) true | 296 | $(^:%=date && $(PFM)/$(VARIETY)/% &&) true |
| @@ -304,7 +305,7 @@ testrunep: epvmss epdss | |||
| 304 | # | 305 | # |
| 305 | # %%TARGET: Add a pseudo-target for the new target here. | 306 | # %%TARGET: Add a pseudo-target for the new target here. |
| 306 | 307 | ||
| 307 | mpmss sacss amcss amcssth amcsshe amsss segsmss awlut awlutth \ | 308 | mpmss sacss amcss amcssth amcsshe amsss amssshe segsmss awlut awlutth \ |
| 308 | awluthe mpsicv lockcov poolncv locv qs apss \ | 309 | awluthe mpsicv lockcov poolncv locv qs apss \ |
| 309 | finalcv arenacv bttest teletest epvmss epdss \ | 310 | finalcv arenacv bttest teletest epvmss epdss \ |
| 310 | abqtest cbstest btcv mv2test \ | 311 | abqtest cbstest btcv mv2test \ |
| @@ -393,11 +394,14 @@ $(PFM)/$(VARIETY)/amcssth: $(PFM)/$(VARIETY)/amcssth.o \ | |||
| 393 | $(FMTDYTSTOBJ) $(MPMOBJ) $(AMCOBJ) $(TESTLIBOBJ) | 394 | $(FMTDYTSTOBJ) $(MPMOBJ) $(AMCOBJ) $(TESTLIBOBJ) |
| 394 | 395 | ||
| 395 | $(PFM)/$(VARIETY)/amcsshe: $(PFM)/$(VARIETY)/amcsshe.o \ | 396 | $(PFM)/$(VARIETY)/amcsshe: $(PFM)/$(VARIETY)/amcsshe.o \ |
| 396 | $(PFM)/$(VARIETY)/fmthe.o $(MPMOBJ) $(AMCOBJ) $(TESTLIBOBJ) | 397 | $(FMTHETSTOBJ) $(MPMOBJ) $(AMCOBJ) $(TESTLIBOBJ) |
| 397 | 398 | ||
| 398 | $(PFM)/$(VARIETY)/amsss: $(PFM)/$(VARIETY)/amsss.o \ | 399 | $(PFM)/$(VARIETY)/amsss: $(PFM)/$(VARIETY)/amsss.o \ |
| 399 | $(FMTDYTSTOBJ) $(MPMOBJ) $(AMSOBJ) $(TESTLIBOBJ) | 400 | $(FMTDYTSTOBJ) $(MPMOBJ) $(AMSOBJ) $(TESTLIBOBJ) |
| 400 | 401 | ||
| 402 | $(PFM)/$(VARIETY)/amssshe: $(PFM)/$(VARIETY)/amssshe.o \ | ||
| 403 | $(FMTHETSTOBJ) $(MPMOBJ) $(AMSOBJ) $(TESTLIBOBJ) | ||
| 404 | |||
| 401 | $(PFM)/$(VARIETY)/segsmss: $(PFM)/$(VARIETY)/segsmss.o \ | 405 | $(PFM)/$(VARIETY)/segsmss: $(PFM)/$(VARIETY)/segsmss.o \ |
| 402 | $(FMTDYTSTOBJ) $(MPMOBJ) $(AMSOBJ) $(TESTLIBOBJ) | 406 | $(FMTDYTSTOBJ) $(MPMOBJ) $(AMSOBJ) $(TESTLIBOBJ) |
| 403 | 407 | ||
| @@ -411,7 +415,7 @@ $(PFM)/$(VARIETY)/awlut: $(PFM)/$(VARIETY)/awlut.o \ | |||
| 411 | $(FMTDYTSTOBJ) $(MPMOBJ) $(LOOBJ) $(AWLOBJ) $(TESTLIBOBJ) | 415 | $(FMTDYTSTOBJ) $(MPMOBJ) $(LOOBJ) $(AWLOBJ) $(TESTLIBOBJ) |
| 412 | 416 | ||
| 413 | $(PFM)/$(VARIETY)/awluthe: $(PFM)/$(VARIETY)/awluthe.o \ | 417 | $(PFM)/$(VARIETY)/awluthe: $(PFM)/$(VARIETY)/awluthe.o \ |
| 414 | $(PFM)/$(VARIETY)/fmthe.o $(MPMOBJ) $(LOOBJ) $(AWLOBJ) $(TESTLIBOBJ) | 418 | $(FMTHETSTOBJ) $(MPMOBJ) $(LOOBJ) $(AWLOBJ) $(TESTLIBOBJ) |
| 415 | 419 | ||
| 416 | $(PFM)/$(VARIETY)/awlutth: $(PFM)/$(VARIETY)/awlutth.o \ | 420 | $(PFM)/$(VARIETY)/awlutth: $(PFM)/$(VARIETY)/awlutth.o \ |
| 417 | $(FMTDYTSTOBJ) $(MPMOBJ) $(LOOBJ) $(AWLOBJ) $(TESTLIBOBJ) | 421 | $(FMTDYTSTOBJ) $(MPMOBJ) $(LOOBJ) $(AWLOBJ) $(TESTLIBOBJ) |
diff --git a/mps/code/finalcv.c b/mps/code/finalcv.c index 459dd394174..1fa1a5cfd94 100644 --- a/mps/code/finalcv.c +++ b/mps/code/finalcv.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include "mpscamc.h" | 22 | #include "mpscamc.h" |
| 23 | #include "mpsavm.h" | 23 | #include "mpsavm.h" |
| 24 | #include "fmtdy.h" | 24 | #include "fmtdy.h" |
| 25 | #include "fmtdytst.h" | ||
| 25 | #include "mpstd.h" | 26 | #include "mpstd.h" |
| 26 | #ifdef MPS_OS_W3 | 27 | #ifdef MPS_OS_W3 |
| 27 | #include "mpsw3.h" | 28 | #include "mpsw3.h" |
diff --git a/mps/code/fmtdy.c b/mps/code/fmtdy.c index 84db8101257..52d9d871f98 100644 --- a/mps/code/fmtdy.c +++ b/mps/code/fmtdy.c | |||
| @@ -51,6 +51,7 @@ | |||
| 51 | 51 | ||
| 52 | 52 | ||
| 53 | #include "fmtdy.h" | 53 | #include "fmtdy.h" |
| 54 | #include "fmtno.h" | ||
| 54 | #include "mps.h" | 55 | #include "mps.h" |
| 55 | #include <assert.h> | 56 | #include <assert.h> |
| 56 | #include <string.h> | 57 | #include <string.h> |
| @@ -103,8 +104,6 @@ static unsigned long dylan_fw_counts[2]; | |||
| 103 | #endif /* FMTDY_COUNTING */ | 104 | #endif /* FMTDY_COUNTING */ |
| 104 | 105 | ||
| 105 | 106 | ||
| 106 | #ifndef NDEBUG | ||
| 107 | |||
| 108 | int dylan_wrapper_check(mps_word_t *w) | 107 | int dylan_wrapper_check(mps_word_t *w) |
| 109 | { | 108 | { |
| 110 | mps_word_t *ww; | 109 | mps_word_t *ww; |
| @@ -209,8 +208,6 @@ int dylan_wrapper_check(mps_word_t *w) | |||
| 209 | return 1; | 208 | return 1; |
| 210 | } | 209 | } |
| 211 | 210 | ||
| 212 | #endif /* NDEBUG */ | ||
| 213 | |||
| 214 | 211 | ||
| 215 | /* Scan a contiguous array of references in [base, limit). */ | 212 | /* Scan a contiguous array of references in [base, limit). */ |
| 216 | /* This code has been hand-optimised and examined using Metrowerks */ | 213 | /* This code has been hand-optimised and examined using Metrowerks */ |
| @@ -315,6 +312,8 @@ dylan_scan_contig_weak(mps_ss_t mps_ss, | |||
| 315 | } | 312 | } |
| 316 | 313 | ||
| 317 | 314 | ||
| 315 | /* dylan_scan_pat -- scan according to pattern */ | ||
| 316 | |||
| 318 | /* Scan an array of words in [base, limit) using the patterns at pats */ | 317 | /* Scan an array of words in [base, limit) using the patterns at pats */ |
| 319 | /* to determine which words can be fixed. */ | 318 | /* to determine which words can be fixed. */ |
| 320 | /* This code has been hand-optimised and examined using Metrowerks */ | 319 | /* This code has been hand-optimised and examined using Metrowerks */ |
| @@ -368,7 +367,7 @@ static mps_res_t dylan_scan_pat(mps_ss_t mps_ss, | |||
| 368 | (MPS_WORD_SHIFT - (_es)) : \ | 367 | (MPS_WORD_SHIFT - (_es)) : \ |
| 369 | (_vt) << ((_es) - MPS_WORD_SHIFT)) | 368 | (_vt) << ((_es) - MPS_WORD_SHIFT)) |
| 370 | 369 | ||
| 371 | static mps_res_t dylan_scan1(mps_ss_t mps_ss, mps_addr_t *object_io) | 370 | extern mps_res_t dylan_scan1(mps_ss_t mps_ss, mps_addr_t *object_io) |
| 372 | { | 371 | { |
| 373 | mps_addr_t *p; /* cursor in object */ | 372 | mps_addr_t *p; /* cursor in object */ |
| 374 | mps_addr_t *q; /* cursor limit for loops */ | 373 | mps_addr_t *q; /* cursor limit for loops */ |
| @@ -544,7 +543,7 @@ static mps_addr_t dylan_class(mps_addr_t obj) | |||
| 544 | return (mps_addr_t)first_word; | 543 | return (mps_addr_t)first_word; |
| 545 | } | 544 | } |
| 546 | 545 | ||
| 547 | static mps_res_t dylan_scan1_weak(mps_ss_t mps_ss, mps_addr_t *object_io) | 546 | extern mps_res_t dylan_scan1_weak(mps_ss_t mps_ss, mps_addr_t *object_io) |
| 548 | { | 547 | { |
| 549 | mps_addr_t *assoc; | 548 | mps_addr_t *assoc; |
| 550 | mps_addr_t *base; | 549 | mps_addr_t *base; |
| @@ -692,12 +691,6 @@ static void dylan_copy(mps_addr_t old, mps_addr_t new) | |||
| 692 | memcpy(new, old, length); | 691 | memcpy(new, old, length); |
| 693 | } | 692 | } |
| 694 | 693 | ||
| 695 | static void dylan_no_copy(mps_addr_t old, mps_addr_t new) | ||
| 696 | { | ||
| 697 | unused(old); unused(new); | ||
| 698 | notreached(); | ||
| 699 | } | ||
| 700 | |||
| 701 | static mps_addr_t dylan_isfwd(mps_addr_t object) | 694 | static mps_addr_t dylan_isfwd(mps_addr_t object) |
| 702 | { | 695 | { |
| 703 | mps_word_t h, tag; | 696 | mps_word_t h, tag; |
| @@ -710,13 +703,6 @@ static mps_addr_t dylan_isfwd(mps_addr_t object) | |||
| 710 | return NULL; | 703 | return NULL; |
| 711 | } | 704 | } |
| 712 | 705 | ||
| 713 | static mps_addr_t dylan_no_isfwd(mps_addr_t object) | ||
| 714 | { | ||
| 715 | unused(object); | ||
| 716 | notreached(); | ||
| 717 | return 0; | ||
| 718 | } | ||
| 719 | |||
| 720 | static void dylan_fwd(mps_addr_t old, mps_addr_t new) | 706 | static void dylan_fwd(mps_addr_t old, mps_addr_t new) |
| 721 | { | 707 | { |
| 722 | mps_word_t *p; | 708 | mps_word_t *p; |
| @@ -735,12 +721,6 @@ static void dylan_fwd(mps_addr_t old, mps_addr_t new) | |||
| 735 | } | 721 | } |
| 736 | } | 722 | } |
| 737 | 723 | ||
| 738 | static void dylan_no_fwd(mps_addr_t old, mps_addr_t new) | ||
| 739 | { | ||
| 740 | unused(old); unused(new); | ||
| 741 | notreached(); | ||
| 742 | } | ||
| 743 | |||
| 744 | void dylan_pad(mps_addr_t addr, size_t size) | 724 | void dylan_pad(mps_addr_t addr, size_t size) |
| 745 | { | 725 | { |
| 746 | mps_word_t *p; | 726 | mps_word_t *p; |
| @@ -754,11 +734,8 @@ void dylan_pad(mps_addr_t addr, size_t size) | |||
| 754 | } | 734 | } |
| 755 | } | 735 | } |
| 756 | 736 | ||
| 757 | static void dylan_no_pad(mps_addr_t addr, size_t size) | 737 | |
| 758 | { | 738 | /* The dylan format structures */ |
| 759 | unused(addr); unused(size); | ||
| 760 | notreached(); | ||
| 761 | } | ||
| 762 | 739 | ||
| 763 | static struct mps_fmt_A_s dylan_fmt_A_s = | 740 | static struct mps_fmt_A_s dylan_fmt_A_s = |
| 764 | { | 741 | { |
| @@ -771,38 +748,49 @@ static struct mps_fmt_A_s dylan_fmt_A_s = | |||
| 771 | dylan_pad | 748 | dylan_pad |
| 772 | }; | 749 | }; |
| 773 | 750 | ||
| 774 | static struct mps_fmt_A_s dylan_fmt_A_weak_s = | 751 | static struct mps_fmt_B_s dylan_fmt_B_s = |
| 775 | { | 752 | { |
| 776 | ALIGN, | 753 | ALIGN, |
| 777 | dylan_scan_weak, | 754 | dylan_scan, |
| 778 | dylan_skip, | 755 | dylan_skip, |
| 779 | dylan_no_copy, | 756 | dylan_copy, |
| 780 | dylan_no_fwd, | 757 | dylan_fwd, |
| 781 | dylan_no_isfwd, | 758 | dylan_isfwd, |
| 782 | dylan_no_pad | 759 | dylan_pad, |
| 760 | dylan_class | ||
| 783 | }; | 761 | }; |
| 784 | 762 | ||
| 763 | /* Functions returning the dylan format structures */ | ||
| 764 | |||
| 785 | mps_fmt_A_s *dylan_fmt_A(void) | 765 | mps_fmt_A_s *dylan_fmt_A(void) |
| 786 | { | 766 | { |
| 787 | return &dylan_fmt_A_s; | 767 | return &dylan_fmt_A_s; |
| 788 | } | 768 | } |
| 789 | 769 | ||
| 790 | mps_fmt_A_s *dylan_fmt_A_weak(void) | 770 | mps_fmt_B_s *dylan_fmt_B(void) |
| 791 | { | 771 | { |
| 792 | return &dylan_fmt_A_weak_s; | 772 | return &dylan_fmt_B_s; |
| 793 | } | 773 | } |
| 794 | 774 | ||
| 775 | /* Format variety-independent version that picks the right format | ||
| 776 | * variety and creates it. */ | ||
| 795 | 777 | ||
| 796 | static struct mps_fmt_B_s dylan_fmt_B_s = | 778 | mps_res_t dylan_fmt(mps_fmt_t *mps_fmt_o, mps_arena_t arena) |
| 779 | { | ||
| 780 | return mps_fmt_create_B(mps_fmt_o, arena, dylan_fmt_B()); | ||
| 781 | } | ||
| 782 | |||
| 783 | /* The weak format structures */ | ||
| 784 | |||
| 785 | static struct mps_fmt_A_s dylan_fmt_A_weak_s = | ||
| 797 | { | 786 | { |
| 798 | ALIGN, | 787 | ALIGN, |
| 799 | dylan_scan, | 788 | dylan_scan_weak, |
| 800 | dylan_skip, | 789 | dylan_skip, |
| 801 | dylan_copy, | 790 | no_copy, |
| 802 | dylan_fwd, | 791 | no_fwd, |
| 803 | dylan_isfwd, | 792 | no_isfwd, |
| 804 | dylan_pad, | 793 | no_pad |
| 805 | dylan_class | ||
| 806 | }; | 794 | }; |
| 807 | 795 | ||
| 808 | static struct mps_fmt_B_s dylan_fmt_B_weak_s = | 796 | static struct mps_fmt_B_s dylan_fmt_B_weak_s = |
| @@ -810,32 +798,29 @@ static struct mps_fmt_B_s dylan_fmt_B_weak_s = | |||
| 810 | ALIGN, | 798 | ALIGN, |
| 811 | dylan_scan_weak, | 799 | dylan_scan_weak, |
| 812 | dylan_skip, | 800 | dylan_skip, |
| 813 | dylan_no_copy, | 801 | no_copy, |
| 814 | dylan_no_fwd, | 802 | no_fwd, |
| 815 | dylan_no_isfwd, | 803 | no_isfwd, |
| 816 | dylan_no_pad, | 804 | no_pad, |
| 817 | dylan_class | 805 | dylan_class |
| 818 | }; | 806 | }; |
| 819 | 807 | ||
| 820 | mps_fmt_B_s *dylan_fmt_B(void) | 808 | /* Functions returning the weak format structures */ |
| 809 | |||
| 810 | mps_fmt_A_s *dylan_fmt_A_weak(void) | ||
| 821 | { | 811 | { |
| 822 | return &dylan_fmt_B_s; | 812 | return &dylan_fmt_A_weak_s; |
| 823 | } | 813 | } |
| 824 | 814 | ||
| 815 | |||
| 825 | mps_fmt_B_s *dylan_fmt_B_weak(void) | 816 | mps_fmt_B_s *dylan_fmt_B_weak(void) |
| 826 | { | 817 | { |
| 827 | return &dylan_fmt_B_weak_s; | 818 | return &dylan_fmt_B_weak_s; |
| 828 | } | 819 | } |
| 829 | 820 | ||
| 830 | 821 | ||
| 831 | /* Now we have format variety-independent version that pick the right | 822 | /* Format variety-independent version that picks the right format |
| 832 | * format variety and create it. | 823 | * variety and creates it. */ |
| 833 | */ | ||
| 834 | |||
| 835 | mps_res_t dylan_fmt(mps_fmt_t *mps_fmt_o, mps_arena_t arena) | ||
| 836 | { | ||
| 837 | return mps_fmt_create_B(mps_fmt_o, arena, dylan_fmt_B()); | ||
| 838 | } | ||
| 839 | 824 | ||
| 840 | mps_res_t dylan_fmt_weak(mps_fmt_t *mps_fmt_o, mps_arena_t arena) | 825 | mps_res_t dylan_fmt_weak(mps_fmt_t *mps_fmt_o, mps_arena_t arena) |
| 841 | { | 826 | { |
| @@ -843,13 +828,3 @@ mps_res_t dylan_fmt_weak(mps_fmt_t *mps_fmt_o, mps_arena_t arena) | |||
| 843 | } | 828 | } |
| 844 | 829 | ||
| 845 | 830 | ||
| 846 | mps_bool_t dylan_check(mps_addr_t addr) | ||
| 847 | { | ||
| 848 | assert(addr != 0); | ||
| 849 | assert(((mps_word_t)addr & (ALIGN-1)) == 0); | ||
| 850 | assert(dylan_wrapper_check((mps_word_t *)((mps_word_t *)addr)[0])); | ||
| 851 | /* .assert.unused: Asserts throw away their conditions */ | ||
| 852 | /* in hot varieties, so UNUSED is needed. */ | ||
| 853 | unused(addr); | ||
| 854 | return 1; | ||
| 855 | } | ||
diff --git a/mps/code/fmtdy.h b/mps/code/fmtdy.h index e174121c06f..795544d8e74 100644 --- a/mps/code/fmtdy.h +++ b/mps/code/fmtdy.h | |||
| @@ -9,6 +9,11 @@ | |||
| 9 | 9 | ||
| 10 | #include "mps.h" | 10 | #include "mps.h" |
| 11 | 11 | ||
| 12 | /* Low-level routines, exposed here so that the with-header format | ||
| 13 | * can use common code. */ | ||
| 14 | extern mps_res_t dylan_scan1(mps_ss_t, mps_addr_t *); | ||
| 15 | extern mps_res_t dylan_scan1_weak(mps_ss_t, mps_addr_t *); | ||
| 16 | |||
| 12 | /* Format */ | 17 | /* Format */ |
| 13 | extern mps_fmt_A_s *dylan_fmt_A(void); | 18 | extern mps_fmt_A_s *dylan_fmt_A(void); |
| 14 | extern mps_fmt_A_s *dylan_fmt_A_weak(void); | 19 | extern mps_fmt_A_s *dylan_fmt_A_weak(void); |
| @@ -17,15 +22,13 @@ extern mps_fmt_B_s *dylan_fmt_B_weak(void); | |||
| 17 | extern mps_res_t dylan_fmt(mps_fmt_t *, mps_arena_t); | 22 | extern mps_res_t dylan_fmt(mps_fmt_t *, mps_arena_t); |
| 18 | extern mps_res_t dylan_fmt_weak(mps_fmt_t *, mps_arena_t); | 23 | extern mps_res_t dylan_fmt_weak(mps_fmt_t *, mps_arena_t); |
| 19 | 24 | ||
| 25 | /* The null format */ | ||
| 26 | extern mps_fmt_A_s *no_fmt_A(void); | ||
| 27 | extern mps_fmt_B_s *no_fmt_B(void); | ||
| 28 | extern mps_res_t no_fmt(mps_fmt_t *, mps_arena_t); | ||
| 29 | |||
| 20 | extern mps_addr_t dylan_weak_dependent(mps_addr_t); | 30 | extern mps_addr_t dylan_weak_dependent(mps_addr_t); |
| 21 | 31 | ||
| 22 | /* Used only for debugging / testing */ | ||
| 23 | extern mps_res_t dylan_init(mps_addr_t addr, size_t size, | ||
| 24 | mps_addr_t *refs, size_t nr_refs); | ||
| 25 | extern void dylan_write(mps_addr_t addr, | ||
| 26 | mps_addr_t *refs, size_t nr_refs); | ||
| 27 | extern mps_addr_t dylan_read(mps_addr_t addr); | ||
| 28 | extern mps_bool_t dylan_check(mps_addr_t addr); | ||
| 29 | extern void dylan_pad(mps_addr_t addr, size_t size); | 32 | extern void dylan_pad(mps_addr_t addr, size_t size); |
| 30 | extern int dylan_wrapper_check(mps_word_t *w); | 33 | extern int dylan_wrapper_check(mps_word_t *w); |
| 31 | 34 | ||
diff --git a/mps/code/fmtdytst.c b/mps/code/fmtdytst.c index cffd3d1c8bd..71fdc8ae69b 100644 --- a/mps/code/fmtdytst.c +++ b/mps/code/fmtdytst.c | |||
| @@ -7,12 +7,14 @@ | |||
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #include "fmtdy.h" | 9 | #include "fmtdy.h" |
| 10 | #include "fmtdytst.h" | ||
| 10 | #include "mps.h" | 11 | #include "mps.h" |
| 11 | #include "testlib.h" | 12 | #include "testlib.h" |
| 12 | #include <assert.h> | 13 | #include <assert.h> |
| 13 | #include <string.h> | 14 | #include <string.h> |
| 14 | #include <stdlib.h> | 15 | #include <stdlib.h> |
| 15 | 16 | ||
| 17 | #define unused(param) ((void)param) | ||
| 16 | 18 | ||
| 17 | #ifdef MPS_BUILD_MV | 19 | #ifdef MPS_BUILD_MV |
| 18 | /* windows.h causes warnings about "unreferenced inline function */ | 20 | /* windows.h causes warnings about "unreferenced inline function */ |
| @@ -138,3 +140,14 @@ mps_addr_t dylan_read(mps_addr_t addr) | |||
| 138 | 140 | ||
| 139 | return addr; | 141 | return addr; |
| 140 | } | 142 | } |
| 143 | |||
| 144 | mps_bool_t dylan_check(mps_addr_t addr) | ||
| 145 | { | ||
| 146 | assert(addr != 0); | ||
| 147 | assert(((mps_word_t)addr & (ALIGN-1)) == 0); | ||
| 148 | assert(dylan_wrapper_check((mps_word_t *)((mps_word_t *)addr)[0])); | ||
| 149 | /* .assert.unused: Asserts throw away their conditions */ | ||
| 150 | /* in hot varieties, so UNUSED is needed. */ | ||
| 151 | unused(addr); | ||
| 152 | return 1; | ||
| 153 | } | ||
diff --git a/mps/code/fmtdytst.h b/mps/code/fmtdytst.h new file mode 100644 index 00000000000..cdd8508ecf7 --- /dev/null +++ b/mps/code/fmtdytst.h | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | /* impl.h.fmtdytst: DYLAN OBJECT FORMAT TESTING | ||
| 2 | * | ||
| 3 | * $Id: //info.ravenbrook.com/project/mps/master/code/fmtdy.h#7 $ | ||
| 4 | * Copyright (c) 2001 Ravenbrook Limited. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef fmtdytst_h | ||
| 8 | #define fmtdytst_h | ||
| 9 | |||
| 10 | #include "mps.h" | ||
| 11 | |||
| 12 | extern mps_res_t dylan_init(mps_addr_t addr, size_t size, | ||
| 13 | mps_addr_t *refs, size_t nr_refs); | ||
| 14 | extern void dylan_write(mps_addr_t addr, | ||
| 15 | mps_addr_t *refs, size_t nr_refs); | ||
| 16 | extern mps_addr_t dylan_read(mps_addr_t addr); | ||
| 17 | extern mps_bool_t dylan_check(mps_addr_t addr); | ||
| 18 | extern void dylan_pad(mps_addr_t addr, size_t size); | ||
| 19 | extern int dylan_wrapper_check(mps_word_t *w); | ||
| 20 | |||
| 21 | #endif /* fmtdy_h */ | ||
diff --git a/mps/code/fmthe.c b/mps/code/fmthe.c index ffd9a29a4c7..69a1220dbab 100644 --- a/mps/code/fmthe.c +++ b/mps/code/fmthe.c | |||
| @@ -3,48 +3,12 @@ | |||
| 3 | * $Id$ | 3 | * $Id$ |
| 4 | * Copyright (c) 2001 Ravenbrook Limited. | 4 | * Copyright (c) 2001 Ravenbrook Limited. |
| 5 | * | 5 | * |
| 6 | * .source: This was derived from impl.c.fmtdy -- it's probably a good idea to | 6 | * Uses impl.c.fmtdy for the actual Dylan format, and just adds |
| 7 | * keep them in sync and share improvements. | 7 | * a thin layer to handle the object headers themselves. |
| 8 | * | ||
| 9 | * .layouts: | ||
| 10 | * | ||
| 11 | * All objects, B: | ||
| 12 | * | ||
| 13 | * B W pointer to wrapper | ||
| 14 | * B+1 object body | ||
| 15 | * | ||
| 16 | * Forwarded (or padding) one-word objects, B: | ||
| 17 | * | ||
| 18 | * B N | 0b01 new address | 1 | ||
| 19 | * | ||
| 20 | * Forwarded (or padding) multi-word objects, B: | ||
| 21 | * | ||
| 22 | * B N | 0b10 new address | 2 | ||
| 23 | * B+1 L limit of object (addr of end + 1) | ||
| 24 | * | ||
| 25 | * Wrappers, W: | ||
| 26 | * | ||
| 27 | * W WW pointer to wrapper wrapper | ||
| 28 | * W+1 class DylanWorks class pointer (traceable) | ||
| 29 | * W+2 subtype_mask DylanWorks subtype_mask (untraceable) | ||
| 30 | * W+3 (FL << 2) | FF fixed part length and format | ||
| 31 | * W+4 (VS << 3) | VF variable part format and element size | ||
| 32 | * W+5 (WT << 2) | 1 tagged pattern vector length | ||
| 33 | * W+6 pattern 0 patterns for fixed part fields | ||
| 34 | * W+6+WT-1 pattern WT-1 | ||
| 35 | * | ||
| 36 | * The wrapper wrapper, WW: | ||
| 37 | * | ||
| 38 | * WW WW WW is it's own wrapper | ||
| 39 | * WW+1 class DylanWorks class of wrappers | ||
| 40 | * WW+2 subtype_mask DylanWorks subtype_mask for WW | ||
| 41 | * WW+3 (4 << 2) | 2 wrappers have four patterned fields | ||
| 42 | * WW+4 (0 << 3) | 0 wrappers have a non-traceable vector | ||
| 43 | * WW+5 (1 << 2) | 1 one pattern word follows | ||
| 44 | * WW+6 0b001 only field 0 is traceable | ||
| 45 | */ | 8 | */ |
| 46 | 9 | ||
| 47 | 10 | #include "fmtdy.h" | |
| 11 | #include "fmtno.h" | ||
| 48 | #include "fmthe.h" | 12 | #include "fmthe.h" |
| 49 | #include "mps.h" | 13 | #include "mps.h" |
| 50 | 14 | ||
| @@ -67,454 +31,32 @@ | |||
| 67 | 31 | ||
| 68 | #define assert(cond) Insist(cond) | 32 | #define assert(cond) Insist(cond) |
| 69 | #define notreached() assert(0) | 33 | #define notreached() assert(0) |
| 70 | #define unused(param) ((void)(param)) | ||
| 71 | |||
| 72 | |||
| 73 | #ifdef FMTDY_COUNTING | ||
| 74 | #define FMTDY_COUNT(x) x | ||
| 75 | #define FMTDY_FL_LIMIT 16 | ||
| 76 | static unsigned long dylan_vff_counts[4*8]; | ||
| 77 | static unsigned long dylan_fl_counts[FMTDY_FL_LIMIT]; | ||
| 78 | static unsigned long dylan_fl_oversize_count; | ||
| 79 | static unsigned long dylan_fw_counts[2]; | ||
| 80 | #else | ||
| 81 | #define FMTDY_COUNT(x) | ||
| 82 | #endif /* FMTDY_COUNTING */ | ||
| 83 | |||
| 84 | |||
| 85 | static int dylan_wrapper_check(mps_word_t *w) | ||
| 86 | { | ||
| 87 | mps_word_t *ww; | ||
| 88 | mps_word_t vh; | ||
| 89 | mps_word_t version; | ||
| 90 | mps_word_t reserved; | ||
| 91 | mps_word_t class; | ||
| 92 | mps_word_t fh, fl, ff; | ||
| 93 | mps_word_t vb, es, vf; | ||
| 94 | mps_word_t vt, t; | ||
| 95 | |||
| 96 | assert(w != NULL); | ||
| 97 | assert(((mps_word_t)w & 3) == 0); | ||
| 98 | |||
| 99 | /* The first word of the wrapper is a pointer to a wrapper wrapper, */ | ||
| 100 | /* which always has the same contents. Check it. */ | ||
| 101 | |||
| 102 | /* .improve.unique.wrapper: When this becomes part of the Dylan | ||
| 103 | * run-time, it would be possible to know the address of a unique | ||
| 104 | * wrapper wrapper and check that instead. */ | ||
| 105 | |||
| 106 | assert(w[WW] != 0); | ||
| 107 | assert((w[WW] & 3) == 0); /* wrapper wrapper is aligned */ | ||
| 108 | ww = (mps_word_t *)w[WW]; | ||
| 109 | assert(ww[WW] == w[WW]); /* wrapper wrapper is own wrapper */ | ||
| 110 | assert(ww[WC] != 0); /* wrapper class exists */ | ||
| 111 | assert((ww[WC] & 3) == 0); /* wrapper class is aligned */ | ||
| 112 | assert(ww[WF] == (((WS - 1) << 2) | 2)); /* fields with patterns */ | ||
| 113 | assert((ww[WV] & 0x00ffffff) == 0);/* non-traceable vector */ | ||
| 114 | /* Code in this file only works for version 2 */ | ||
| 115 | assert(((ww[WV] >> (MPS_WORD_WIDTH - 8)) & 0xff) == 2); | ||
| 116 | assert(ww[WS] == ((1 << 2) | 1)); /* one pattern word in wrapper wrapper */ | ||
| 117 | /* The first field is traceable, the second field can be traced, */ | ||
| 118 | /* but doesn't need to be. */ | ||
| 119 | assert((ww[WP] == 1) || (ww[WP] == 3)); | ||
| 120 | |||
| 121 | /* Unpack the wrapper. */ | ||
| 122 | |||
| 123 | class = w[WC]; /* class */ | ||
| 124 | fh = w[WF]; /* fixed part header word */ | ||
| 125 | fl = fh >> 2; /* fixed part length */ | ||
| 126 | ff = fh & 3; /* fixed part format code */ | ||
| 127 | vh = w[WV]; /* variable part header */ | ||
| 128 | version = (vh >> (MPS_WORD_WIDTH - 8)) & 0xff; | ||
| 129 | assert(version == 2); /* Code in this file only works for version 2 */ | ||
| 130 | reserved = (vh >> 8) & 0xff; | ||
| 131 | assert(reserved == 0); | ||
| 132 | vb = (vh >> 16) & 0xff; | ||
| 133 | es = (vh & 0xff) >> 3;/* element size */ | ||
| 134 | vf = vh & 7; /* variable part format code */ | ||
| 135 | vt = w[WS]; /* vector total word (Dylan-tagged) */ | ||
| 136 | t = vt >> 2; /* vector total length */ | ||
| 137 | |||
| 138 | /* The second word is the class of the wrapped object. */ | ||
| 139 | /* It would be good to check which pool this is in. */ | ||
| 140 | |||
| 141 | assert(class != 0); /* class exists */ | ||
| 142 | assert((class & 3) == 0); /* class is aligned */ | ||
| 143 | |||
| 144 | /* The third word contains the fixed part format and length. */ | ||
| 145 | /* The only illegal format is 3. Anything else is possible, although */ | ||
| 146 | /* we could do some bound checking on the length if we knew more about */ | ||
| 147 | /* the surroundings of the object. */ | ||
| 148 | |||
| 149 | /* Fixed part format 3 is reserved. */ | ||
| 150 | assert(ff != 3); | ||
| 151 | |||
| 152 | /* Zero length fixed part is only legal in format 0. */ | ||
| 153 | /* Current Dylan run-time does not honour this so I remove it for now */ | ||
| 154 | /* We probably want this check as then we can scan without having to */ | ||
| 155 | /* check for 0 fixed length fields as a special case */ | ||
| 156 | /* assert(ff == 0 || fl != 0); */ | ||
| 157 | |||
| 158 | /* The fourth word contains the variable part format and element */ | ||
| 159 | /* size. This assumes that DylanWorks is only going to use byte */ | ||
| 160 | /* vectors in the non-word case. */ | ||
| 161 | |||
| 162 | /* Variable part format 6 is reserved. */ | ||
| 163 | assert(vf != 6); | ||
| 164 | |||
| 165 | /* There should be no shift in word vector formats. */ | ||
| 166 | assert((vf & 6) == 4 || es == 0); | ||
| 167 | |||
| 168 | /* The fifth word is the number of patterns in the pattern */ | ||
| 169 | /* vector. This can be calculated from the fixed part length. */ | ||
| 170 | /* The word is also tagged like a DylanWorks integer. */ | ||
| 171 | |||
| 172 | assert((vt & 3) == 1); | ||
| 173 | |||
| 174 | /* The pattern vector in the wrapper should be of non-zero length */ | ||
| 175 | /* only if there is a patterned fixed part. */ | ||
| 176 | assert(ff == 2 || t == 0); | ||
| 177 | |||
| 178 | /* The number of patterns is (fixed fields+31)/32. */ | ||
| 179 | assert(ff != 2 || t == ((fl + MPS_WORD_WIDTH - 1) >> MPS_WORD_SHIFT)); | ||
| 180 | |||
| 181 | /* The patterns are random bits, so we can't check them. However, */ | ||
| 182 | /* the left-over bits in the last pattern should be zero. */ | ||
| 183 | |||
| 184 | assert(ff != 2 || (w[WS+t] >> ((fh>>2) & (MPS_WORD_WIDTH-1))) == 0); | ||
| 185 | |||
| 186 | return 1; | ||
| 187 | } | ||
| 188 | |||
| 189 | |||
| 190 | /* Scan a contiguous array of references in [base, limit). */ | ||
| 191 | /* This code has been hand-optimised and examined using Metrowerks */ | ||
| 192 | /* Codewarrior on a 68K and also Microsoft Visual C on a 486. The */ | ||
| 193 | /* variables in the loop allocate nicely into registers. Alter with */ | ||
| 194 | /* care. */ | ||
| 195 | |||
| 196 | static mps_res_t dylan_scan_contig(mps_ss_t mps_ss, | ||
| 197 | mps_addr_t *base, mps_addr_t *limit) | ||
| 198 | { | ||
| 199 | mps_res_t res; | ||
| 200 | mps_addr_t *p; /* reference cursor */ | ||
| 201 | mps_addr_t r; /* reference to be fixed */ | ||
| 202 | |||
| 203 | MPS_SCAN_BEGIN(mps_ss) { | ||
| 204 | p = base; | ||
| 205 | loop: if(p >= limit) goto out; | ||
| 206 | r = *p++; | ||
| 207 | if(((mps_word_t)r&3) != 0) /* pointers tagged with 0 */ | ||
| 208 | goto loop; /* not a pointer */ | ||
| 209 | if(!MPS_FIX1(mps_ss, r)) goto loop; | ||
| 210 | res = MPS_FIX2(mps_ss, p-1); | ||
| 211 | if(res == MPS_RES_OK) goto loop; | ||
| 212 | return res; | ||
| 213 | out: assert(p == limit); | ||
| 214 | } MPS_SCAN_END(mps_ss); | ||
| 215 | |||
| 216 | return MPS_RES_OK; | ||
| 217 | } | ||
| 218 | |||
| 219 | /* dylan_weak_dependent -- returns the linked object, if any. | ||
| 220 | */ | ||
| 221 | |||
| 222 | extern mps_addr_t dylan_weak_dependent(mps_addr_t parent) | ||
| 223 | { | ||
| 224 | mps_word_t *object; | ||
| 225 | mps_word_t *wrapper; | ||
| 226 | mps_word_t fword; | ||
| 227 | mps_word_t fl; | ||
| 228 | mps_word_t ff; | ||
| 229 | |||
| 230 | assert(parent != NULL); | ||
| 231 | object = (mps_word_t *)parent; | ||
| 232 | wrapper = (mps_word_t *)object[0]; | ||
| 233 | assert(dylan_wrapper_check(wrapper)); | ||
| 234 | fword = wrapper[3]; | ||
| 235 | ff = fword & 3; | ||
| 236 | /* traceable fixed part */ | ||
| 237 | assert(ff == 1); | ||
| 238 | fl = fword & ~3uL; | ||
| 239 | /* at least one fixed field */ | ||
| 240 | assert(fl >= 1); | ||
| 241 | return (mps_addr_t) object[1]; | ||
| 242 | } | ||
| 243 | |||
| 244 | |||
| 245 | /* Scan weakly a contiguous array of references in [base, limit). */ | ||
| 246 | /* Only required to scan vectors for Dylan Weak Tables. */ | ||
| 247 | /* Depends on the vector length field being scannable (ie a tagged */ | ||
| 248 | /* integer). */ | ||
| 249 | /* When a reference that has been fixed to NULL is detected the */ | ||
| 250 | /* corresponding reference in the associated table (pointed to be the */ | ||
| 251 | /* assoc variable) will be deleted. */ | ||
| 252 | |||
| 253 | static mps_res_t | ||
| 254 | dylan_scan_contig_weak(mps_ss_t mps_ss, | ||
| 255 | mps_addr_t *base, mps_addr_t *limit, | ||
| 256 | mps_addr_t *objectBase, mps_addr_t *assoc) | ||
| 257 | { | ||
| 258 | mps_addr_t *p; | ||
| 259 | mps_res_t res; | ||
| 260 | mps_addr_t r; | ||
| 261 | |||
| 262 | MPS_SCAN_BEGIN(mps_ss) { | ||
| 263 | p = base; | ||
| 264 | goto skip_inc; | ||
| 265 | loop: | ||
| 266 | ++p; | ||
| 267 | skip_inc: | ||
| 268 | if(p >= limit) | ||
| 269 | goto out; | ||
| 270 | r = *p; | ||
| 271 | if(((mps_word_t)r & 3) != 0) /* non-pointer */ | ||
| 272 | goto loop; | ||
| 273 | if(!MPS_FIX1(mps_ss, r)) | ||
| 274 | goto loop; | ||
| 275 | res = MPS_FIX2(mps_ss, p); | ||
| 276 | if(res == MPS_RES_OK) { | ||
| 277 | if(*p == 0 && r != 0) { | ||
| 278 | if(assoc != NULL) { | ||
| 279 | assoc[p-objectBase] = 0; /* delete corresponding entry */ | ||
| 280 | } | ||
| 281 | } | ||
| 282 | goto loop; | ||
| 283 | } | ||
| 284 | return res; | ||
| 285 | out: | ||
| 286 | assert(p == limit); | ||
| 287 | } MPS_SCAN_END(mps_ss); | ||
| 288 | |||
| 289 | return MPS_RES_OK; | ||
| 290 | } | ||
| 291 | |||
| 292 | |||
| 293 | /* dylan_scan_pat -- scan according to pattern | ||
| 294 | * | ||
| 295 | * Scan an array of words in [base, limit) using the patterns at pats | ||
| 296 | * to determine which words can be fixed. | ||
| 297 | */ | ||
| 298 | |||
| 299 | static mps_res_t dylan_scan_pat(mps_ss_t mps_ss, | ||
| 300 | mps_addr_t *base, mps_addr_t *limit, | ||
| 301 | mps_word_t *pats, mps_word_t nr_pats) | ||
| 302 | { | ||
| 303 | mps_res_t res; | ||
| 304 | mps_word_t *pc = pats;/* pattern cursor */ | ||
| 305 | mps_word_t pat; /* pattern register */ | ||
| 306 | mps_addr_t *p; /* reference cursor */ | ||
| 307 | mps_addr_t *pp; /* inner loop cursor */ | ||
| 308 | int b; /* bit */ | ||
| 309 | mps_addr_t r; /* reference to be fixed */ | ||
| 310 | |||
| 311 | unused(nr_pats); | ||
| 312 | |||
| 313 | MPS_SCAN_BEGIN(mps_ss) { | ||
| 314 | p = base; | ||
| 315 | goto in; | ||
| 316 | pat: p += MPS_WORD_WIDTH; | ||
| 317 | if(p >= limit) goto out; | ||
| 318 | in: pp = p; | ||
| 319 | pat = *pc++; | ||
| 320 | loop: if(pat == 0) goto pat; | ||
| 321 | ++pp; | ||
| 322 | b = (int)(pat & 1); | ||
| 323 | pat >>= 1; | ||
| 324 | if(b == 0) goto loop; | ||
| 325 | r = *(pp-1); | ||
| 326 | if(((mps_word_t)r&3) != 0) /* pointers tagged with 0 */ | ||
| 327 | goto loop; /* not a pointer */ | ||
| 328 | if(!MPS_FIX1(mps_ss, r)) goto loop; | ||
| 329 | res = MPS_FIX2(mps_ss, pp-1); | ||
| 330 | if(res == MPS_RES_OK) goto loop; | ||
| 331 | return res; | ||
| 332 | out: assert(p < limit + MPS_WORD_WIDTH); | ||
| 333 | assert(pc == pats + nr_pats); | ||
| 334 | } MPS_SCAN_END(mps_ss); | ||
| 335 | |||
| 336 | return MPS_RES_OK; | ||
| 337 | } | ||
| 338 | |||
| 339 | 34 | ||
| 340 | #define AddHeader(p) ((mps_addr_t)((char*)(p) + headerSIZE)) | 35 | #define AddHeader(p) ((mps_addr_t)((char*)(p) + headerSIZE)) |
| 341 | 36 | ||
| 37 | static mps_fmt_A_s *dylan_format; | ||
| 342 | 38 | ||
| 343 | #define NONWORD_LENGTH(_vt, _es) \ | 39 | static mps_res_t dylan_header_scan(mps_ss_t mps_ss, |
| 344 | ((_es) < MPS_WORD_SHIFT ? \ | 40 | mps_addr_t base, mps_addr_t limit) |
| 345 | ((_vt) + (1 << (MPS_WORD_SHIFT - (_es))) - 1) >> \ | ||
| 346 | (MPS_WORD_SHIFT - (_es)) : \ | ||
| 347 | (_vt) << ((_es) - MPS_WORD_SHIFT)) | ||
| 348 | |||
| 349 | static mps_res_t dylan_scan1(mps_ss_t mps_ss, mps_addr_t *object_io) | ||
| 350 | { | ||
| 351 | mps_addr_t *p; /* cursor in object */ | ||
| 352 | mps_addr_t *q; /* cursor limit for loops */ | ||
| 353 | mps_word_t h; /* header word */ | ||
| 354 | mps_word_t *w; /* pointer to wrapper */ | ||
| 355 | mps_word_t fh; /* fixed part header word */ | ||
| 356 | mps_word_t fl; /* fixed part length, in words */ | ||
| 357 | mps_word_t vh; /* variable part header */ | ||
| 358 | mps_word_t vf; /* variable part format */ | ||
| 359 | mps_word_t vl; /* variable part actual length */ | ||
| 360 | unsigned vb; /* vector bias */ | ||
| 361 | unsigned es; /* variable part element size (log2 of bits) */ | ||
| 362 | mps_word_t vt; /* total vector length */ | ||
| 363 | mps_res_t res; | ||
| 364 | int header; | ||
| 365 | |||
| 366 | assert(object_io != NULL); | ||
| 367 | |||
| 368 | p = (mps_addr_t *)*object_io; | ||
| 369 | assert(p != NULL); | ||
| 370 | |||
| 371 | header = *(int*)((char*)p - headerSIZE); | ||
| 372 | switch(headerType(header)) { | ||
| 373 | case realTYPE: | ||
| 374 | break; | ||
| 375 | case padTYPE: | ||
| 376 | *object_io = (mps_addr_t)((char*)p + headerPadSize(header)); | ||
| 377 | return MPS_RES_OK; | ||
| 378 | default: | ||
| 379 | notreached(); | ||
| 380 | break; | ||
| 381 | } | ||
| 382 | |||
| 383 | h = (mps_word_t)p[0]; /* load the header word */ | ||
| 384 | |||
| 385 | /* If the object is forwarded, simply skip it. */ | ||
| 386 | if(h & 3) { | ||
| 387 | mps_addr_t l; | ||
| 388 | |||
| 389 | if((h & 3) == 1) { | ||
| 390 | /* single-word */ | ||
| 391 | l = AddHeader(p + 1); | ||
| 392 | FMTDY_COUNT(++dylan_fw_counts[0]); | ||
| 393 | } else { /* multi-word */ | ||
| 394 | assert((h & 3) == 2); | ||
| 395 | l = (mps_addr_t)p[1]; | ||
| 396 | FMTDY_COUNT(++dylan_fw_counts[1]); | ||
| 397 | } | ||
| 398 | |||
| 399 | *object_io = l; | ||
| 400 | return MPS_RES_OK; | ||
| 401 | } | ||
| 402 | |||
| 403 | mps_fix(mps_ss, p); /* fix the wrapper */ | ||
| 404 | w = (mps_word_t *)p[0]; /* wrapper is header word */ | ||
| 405 | assert(dylan_wrapper_check(w)); | ||
| 406 | |||
| 407 | ++p; /* skip header */ | ||
| 408 | |||
| 409 | /* Fixed Part */ | ||
| 410 | |||
| 411 | fh = w[WF]; | ||
| 412 | fl = fh >> 2; /* get the fixed part length */ | ||
| 413 | |||
| 414 | /* It might be worth inlining common cases here, for example, */ | ||
| 415 | /* pairs. This can be done by examining fh as a whole. */ | ||
| 416 | |||
| 417 | FMTDY_COUNT(fl < FMTDY_FL_LIMIT ? ++dylan_fl_counts[fl] : | ||
| 418 | ++dylan_fl_oversize_count); | ||
| 419 | if(fl > 0) { | ||
| 420 | q = p + fl; /* set q to end of fixed part */ | ||
| 421 | switch(fh & 3) { /* switch on the fixed format */ | ||
| 422 | case 0: /* all non-traceable fields */ | ||
| 423 | p = q; | ||
| 424 | break; | ||
| 425 | |||
| 426 | case 1: /* all traceable fields */ | ||
| 427 | res = dylan_scan_contig(mps_ss, p, q); | ||
| 428 | if(res) return res; | ||
| 429 | break; | ||
| 430 | |||
| 431 | case 2: /* patterns */ | ||
| 432 | res = dylan_scan_pat(mps_ss, p, q, &w[WP], w[WS]>>2); | ||
| 433 | if(res) return res; | ||
| 434 | break; | ||
| 435 | |||
| 436 | default: | ||
| 437 | notreached(); | ||
| 438 | break; | ||
| 439 | } | ||
| 440 | p = q; | ||
| 441 | } | ||
| 442 | |||
| 443 | /* Variable Part */ | ||
| 444 | vh = w[WV]; | ||
| 445 | vf = vh & 7; /* get variable part format */ | ||
| 446 | FMTDY_COUNT(++dylan_vff_counts[(vf << 2)|(fh&3)]); | ||
| 447 | if(vf != 7) | ||
| 448 | { | ||
| 449 | vt = *(mps_word_t *)p; /* total vector length */ | ||
| 450 | assert((vt & 3) == 1); /* check Dylan integer tag */ | ||
| 451 | vt >>= 2; /* untag it */ | ||
| 452 | ++p; | ||
| 453 | |||
| 454 | switch(vf) | ||
| 455 | { | ||
| 456 | case 0: /* non-stretchy non-traceable */ | ||
| 457 | p += vt; | ||
| 458 | break; | ||
| 459 | |||
| 460 | case 1: /* stretchy non-traceable */ | ||
| 461 | notreached(); /* Not used by DylanWorks yet */ | ||
| 462 | p += vt + 1; | ||
| 463 | break; | ||
| 464 | |||
| 465 | case 2: /* non-stretchy traceable */ | ||
| 466 | q = p + vt; | ||
| 467 | res = dylan_scan_contig(mps_ss, p, q); | ||
| 468 | if(res) return res; | ||
| 469 | p = q; | ||
| 470 | break; | ||
| 471 | |||
| 472 | case 3: /* stretchy traceable */ | ||
| 473 | notreached(); /* DW doesn't create them yet */ | ||
| 474 | vl = *(mps_word_t *)p; /* vector length */ | ||
| 475 | assert((vl & 3) == 1); /* check Dylan integer tag */ | ||
| 476 | vl >>= 2; /* untag it */ | ||
| 477 | ++p; | ||
| 478 | res = dylan_scan_contig(mps_ss, p, p + vl); | ||
| 479 | if(res) return res; | ||
| 480 | p += vt; /* skip to end of whole vector */ | ||
| 481 | break; | ||
| 482 | |||
| 483 | case 4: /* non-word */ | ||
| 484 | es = (vh & 0xff) >> 3; | ||
| 485 | vb = (vh >> 16) & 0xff; | ||
| 486 | vt += vb; | ||
| 487 | p += NONWORD_LENGTH(vt, es); | ||
| 488 | break; | ||
| 489 | |||
| 490 | case 5: /* stretchy non-word */ | ||
| 491 | notreached(); /* DW doesn't create them yet */ | ||
| 492 | es = (vh & 0xff) >> 3; | ||
| 493 | vb = (vh >> 16) & 0xff; | ||
| 494 | vt += vb; | ||
| 495 | p += NONWORD_LENGTH(vt, es) + 1; | ||
| 496 | break; | ||
| 497 | |||
| 498 | default: | ||
| 499 | notreached(); | ||
| 500 | break; | ||
| 501 | } | ||
| 502 | } | ||
| 503 | |||
| 504 | *object_io = AddHeader(p); | ||
| 505 | return MPS_RES_OK; | ||
| 506 | } | ||
| 507 | |||
| 508 | |||
| 509 | static mps_res_t dylan_scan(mps_ss_t mps_ss, | ||
| 510 | mps_addr_t base, mps_addr_t limit) | ||
| 511 | { | 41 | { |
| 512 | mps_res_t res; | 42 | mps_res_t res; |
| 513 | mps_addr_t p = base; | 43 | mps_addr_t p = base; |
| 514 | 44 | ||
| 515 | while(p < limit) { | 45 | while(p < limit) { |
| 516 | res = dylan_scan1(mps_ss, &p); | 46 | int header = *(int*)((char*)p - headerSIZE); |
| 517 | if(res) return res; | 47 | switch(headerType(header)) { |
| 48 | case realTYPE: | ||
| 49 | break; | ||
| 50 | case padTYPE: | ||
| 51 | p = (mps_addr_t)((char*)p + headerPadSize(header)); | ||
| 52 | continue; | ||
| 53 | default: | ||
| 54 | notreached(); | ||
| 55 | break; | ||
| 56 | } | ||
| 57 | res = dylan_scan1(mps_ss, &p); | ||
| 58 | if(res) return res; | ||
| 59 | p = AddHeader(p); | ||
| 518 | } | 60 | } |
| 519 | 61 | ||
| 520 | assert(p <= AddHeader(limit)); | 62 | assert(p <= AddHeader(limit)); |
| @@ -523,90 +65,29 @@ static mps_res_t dylan_scan(mps_ss_t mps_ss, | |||
| 523 | } | 65 | } |
| 524 | 66 | ||
| 525 | 67 | ||
| 526 | static mps_res_t dylan_scan1_weak(mps_ss_t mps_ss, mps_addr_t *object_io) | 68 | static mps_res_t dylan_header_scan_weak(mps_ss_t mps_ss, |
| 527 | { | 69 | mps_addr_t base, |
| 528 | mps_addr_t *assoc; | 70 | mps_addr_t limit) |
| 529 | mps_addr_t *base; | ||
| 530 | mps_addr_t *p, q; | ||
| 531 | mps_res_t res; | ||
| 532 | mps_word_t *w; | ||
| 533 | mps_word_t fword, ff, fl; | ||
| 534 | mps_word_t h; | ||
| 535 | mps_word_t vword, vf, vl; | ||
| 536 | int header; | ||
| 537 | |||
| 538 | assert(object_io != NULL); | ||
| 539 | base = (mps_addr_t *)*object_io; | ||
| 540 | assert(base != NULL); | ||
| 541 | p = base; | ||
| 542 | |||
| 543 | header = *(int*)((char*)p - headerSIZE); | ||
| 544 | switch(headerType(header)) { | ||
| 545 | case realTYPE: | ||
| 546 | break; | ||
| 547 | case padTYPE: | ||
| 548 | *object_io = (mps_addr_t)((char*)p + headerPadSize(header)); | ||
| 549 | return MPS_RES_OK; | ||
| 550 | default: | ||
| 551 | notreached(); | ||
| 552 | break; | ||
| 553 | } | ||
| 554 | |||
| 555 | h = (mps_word_t)p[0]; | ||
| 556 | /* object should not be forwarded (as there is no forwarding method) */ | ||
| 557 | assert((h & 3) == 0); | ||
| 558 | |||
| 559 | mps_fix(mps_ss, p); | ||
| 560 | |||
| 561 | /* w points to wrapper */ | ||
| 562 | w = (mps_word_t *)p[0]; | ||
| 563 | |||
| 564 | assert(dylan_wrapper_check(w)); | ||
| 565 | |||
| 566 | ++p; /* skip header */ | ||
| 567 | |||
| 568 | fword = w[WF]; | ||
| 569 | fl = fword >> 2; | ||
| 570 | /* weak vectors should have at least one fixed field */ | ||
| 571 | /* (for assoc field) */ | ||
| 572 | assert(fl >= 1); | ||
| 573 | |||
| 574 | ff = fword & 3; | ||
| 575 | |||
| 576 | /* weak vectors should have traceable fixed format */ | ||
| 577 | assert(ff == 1); | ||
| 578 | |||
| 579 | assoc = (mps_addr_t *)p[0]; | ||
| 580 | |||
| 581 | vword = w[WV]; | ||
| 582 | vf = vword & 7; | ||
| 583 | vl = (mps_word_t)p[fl] >> 2; | ||
| 584 | |||
| 585 | /* weak vectors should be non-stretchy traceable */ | ||
| 586 | assert(vf == 2); | ||
| 587 | |||
| 588 | /* q is end of the object. There are fl fixed fields, vl variable */ | ||
| 589 | /* fields and another slot that contains the vector length */ | ||
| 590 | q = p + fl + vl + 1; | ||
| 591 | |||
| 592 | res = dylan_scan_contig_weak(mps_ss, p, q, base, assoc); | ||
| 593 | if(res != MPS_RES_OK) { | ||
| 594 | return res; | ||
| 595 | } | ||
| 596 | |||
| 597 | *object_io = AddHeader(q); | ||
| 598 | return MPS_RES_OK; | ||
| 599 | } | ||
| 600 | |||
| 601 | |||
| 602 | static mps_res_t dylan_scan_weak(mps_ss_t mps_ss, | ||
| 603 | mps_addr_t base, mps_addr_t limit) | ||
| 604 | { | 71 | { |
| 605 | mps_res_t res; | 72 | mps_res_t res; |
| 606 | 73 | ||
| 607 | while(base < limit) { | 74 | while(base < limit) { |
| 608 | res = dylan_scan1_weak(mps_ss, &base); | 75 | int header; |
| 609 | if(res) return res; | 76 | header = *(int*)((char*)base - headerSIZE); |
| 77 | switch(headerType(header)) { | ||
| 78 | case realTYPE: | ||
| 79 | break; | ||
| 80 | case padTYPE: | ||
| 81 | base = (mps_addr_t)((char*)base + headerPadSize(header)); | ||
| 82 | continue; | ||
| 83 | default: | ||
| 84 | notreached(); | ||
| 85 | break; | ||
| 86 | } | ||
| 87 | |||
| 88 | res = dylan_scan1_weak(mps_ss, &base); | ||
| 89 | if(res) return res; | ||
| 90 | base = AddHeader(base); | ||
| 610 | } | 91 | } |
| 611 | 92 | ||
| 612 | assert(base <= AddHeader(limit)); | 93 | assert(base <= AddHeader(limit)); |
| @@ -614,16 +95,9 @@ static mps_res_t dylan_scan_weak(mps_ss_t mps_ss, | |||
| 614 | return MPS_RES_OK; | 95 | return MPS_RES_OK; |
| 615 | } | 96 | } |
| 616 | 97 | ||
| 617 | static mps_addr_t dylan_skip(mps_addr_t object) | 98 | static mps_addr_t dylan_header_skip(mps_addr_t object) |
| 618 | { | 99 | { |
| 619 | mps_addr_t *p; /* cursor in object */ | 100 | mps_addr_t *p; /* cursor in object */ |
| 620 | mps_word_t *w; /* wrapper cursor */ | ||
| 621 | mps_word_t h; /* header word */ | ||
| 622 | mps_word_t vh; /* variable part header */ | ||
| 623 | mps_word_t vf; /* variable part format */ | ||
| 624 | mps_word_t vt; /* total vector length */ | ||
| 625 | unsigned vb; /* vector bias */ | ||
| 626 | unsigned es; /* variable part element size (log2 of bits) */ | ||
| 627 | int header; | 101 | int header; |
| 628 | 102 | ||
| 629 | p = (mps_addr_t *)object; | 103 | p = (mps_addr_t *)object; |
| @@ -640,122 +114,40 @@ static mps_addr_t dylan_skip(mps_addr_t object) | |||
| 640 | break; | 114 | break; |
| 641 | } | 115 | } |
| 642 | 116 | ||
| 643 | h = (mps_word_t)p[0]; /* load the header word */ | 117 | p = dylan_format->skip(object); |
| 644 | 118 | p = AddHeader(p); | |
| 645 | /* If the object is forwarded, simply skip it. */ | 119 | return p; |
| 646 | if(h & 3) { | ||
| 647 | if((h & 3) == 1) /* single-word */ | ||
| 648 | return AddHeader(p + 1); | ||
| 649 | else { /* multi-word */ | ||
| 650 | assert((h & 3) == 2); | ||
| 651 | return (mps_addr_t)p[1]; | ||
| 652 | } | ||
| 653 | } | ||
| 654 | |||
| 655 | w = (mps_word_t *)h; /* load the fixed wrapper */ | ||
| 656 | assert(dylan_wrapper_check(w)); | ||
| 657 | ++p; | ||
| 658 | |||
| 659 | p += w[WF] >> 2; /* skip fixed part fields */ | ||
| 660 | |||
| 661 | vh = w[WV]; | ||
| 662 | vf = vh & 7; /* get variable part format */ | ||
| 663 | if(vf != 7) | ||
| 664 | { | ||
| 665 | vt = *(mps_word_t *)p; | ||
| 666 | assert((vt & 3) == 1); /* check Dylan integer tag */ | ||
| 667 | vt = vt >> 2; /* total length */ | ||
| 668 | ++p; | ||
| 669 | |||
| 670 | p += vf & 1; /* stretchy vectors have an extra word */ | ||
| 671 | |||
| 672 | if((vf & 6) == 4) /* non-word */ | ||
| 673 | { | ||
| 674 | es = (vh & 0xff) >> 3; | ||
| 675 | vb = (vh >> 16) & 0xff; | ||
| 676 | vt += vb; | ||
| 677 | p += NONWORD_LENGTH(vt, es); | ||
| 678 | } | ||
| 679 | else | ||
| 680 | p += vt; | ||
| 681 | } | ||
| 682 | |||
| 683 | return AddHeader(p); | ||
| 684 | } | 120 | } |
| 685 | 121 | ||
| 686 | 122 | ||
| 687 | static mps_addr_t dylan_isfwd(mps_addr_t object) | 123 | static mps_addr_t dylan_header_isfwd(mps_addr_t object) |
| 688 | { | 124 | { |
| 689 | mps_word_t h, tag; | ||
| 690 | int header; | 125 | int header; |
| 691 | 126 | ||
| 692 | header = *(int*)((char*)object - headerSIZE); | 127 | header = *(int*)((char*)object - headerSIZE); |
| 693 | if (headerType(header) != realTYPE) | 128 | if (headerType(header) != realTYPE) |
| 694 | return NULL; | 129 | return NULL; |
| 695 | 130 | ||
| 696 | h = *(mps_word_t *)object; | 131 | return dylan_format->isfwd(object); |
| 697 | tag = h & 3; | ||
| 698 | if(tag != 0) | ||
| 699 | return (mps_addr_t)(h - tag); | ||
| 700 | else | ||
| 701 | return NULL; | ||
| 702 | } | ||
| 703 | |||
| 704 | |||
| 705 | static void dylan_fwd(mps_addr_t old, mps_addr_t new) | ||
| 706 | { | ||
| 707 | mps_word_t *p; | ||
| 708 | mps_addr_t limit; | ||
| 709 | |||
| 710 | assert(dylan_isfwd(old) == NULL); | ||
| 711 | assert(((mps_word_t)new & 3) == 0); | ||
| 712 | |||
| 713 | p = (mps_word_t *)old; | ||
| 714 | limit = dylan_skip(old); | ||
| 715 | if(limit == &p[1]) /* single-word object? */ | ||
| 716 | p[0] = (mps_word_t)new | 1; | ||
| 717 | else { | ||
| 718 | p[0] = (mps_word_t)new | 2; | ||
| 719 | p[1] = (mps_word_t)limit; | ||
| 720 | } | ||
| 721 | } | 132 | } |
| 722 | 133 | ||
| 723 | 134 | ||
| 724 | static void dylan_pad(mps_addr_t addr, size_t fullSize) | 135 | static void dylan_header_pad(mps_addr_t addr, size_t fullSize) |
| 725 | { | 136 | { |
| 726 | *(int*)addr = padHeader(fullSize); | 137 | *(int*)addr = padHeader(fullSize); |
| 727 | } | 138 | } |
| 728 | 139 | ||
| 729 | 140 | ||
| 730 | static mps_addr_t dylan_no_isfwd(mps_addr_t object) | ||
| 731 | { | ||
| 732 | unused(object); | ||
| 733 | notreached(); | ||
| 734 | return 0; | ||
| 735 | } | ||
| 736 | |||
| 737 | static void dylan_no_fwd(mps_addr_t old, mps_addr_t new) | ||
| 738 | { | ||
| 739 | unused(old); unused(new); | ||
| 740 | notreached(); | ||
| 741 | } | ||
| 742 | |||
| 743 | static void dylan_no_pad(mps_addr_t addr, size_t size) | ||
| 744 | { | ||
| 745 | unused(addr); unused(size); | ||
| 746 | notreached(); | ||
| 747 | } | ||
| 748 | |||
| 749 | /* HeaderFormat -- format descriptor for this format */ | 141 | /* HeaderFormat -- format descriptor for this format */ |
| 750 | 142 | ||
| 751 | static struct mps_fmt_auto_header_s HeaderFormat = | 143 | static struct mps_fmt_auto_header_s HeaderFormat = |
| 752 | { | 144 | { |
| 753 | ALIGN, | 145 | ALIGN, |
| 754 | dylan_scan, | 146 | dylan_header_scan, |
| 755 | dylan_skip, | 147 | dylan_header_skip, |
| 756 | dylan_fwd, | 148 | NULL, /* later overwritten by dylan format forward method */ |
| 757 | dylan_isfwd, | 149 | dylan_header_isfwd, |
| 758 | dylan_pad, | 150 | dylan_header_pad, |
| 759 | (size_t)headerSIZE | 151 | (size_t)headerSIZE |
| 760 | }; | 152 | }; |
| 761 | 153 | ||
| @@ -765,11 +157,11 @@ static struct mps_fmt_auto_header_s HeaderFormat = | |||
| 765 | static struct mps_fmt_auto_header_s HeaderWeakFormat = | 157 | static struct mps_fmt_auto_header_s HeaderWeakFormat = |
| 766 | { | 158 | { |
| 767 | ALIGN, | 159 | ALIGN, |
| 768 | dylan_scan_weak, | 160 | dylan_header_scan_weak, |
| 769 | dylan_skip, | 161 | dylan_header_skip, |
| 770 | dylan_no_fwd, | 162 | no_fwd, |
| 771 | dylan_no_isfwd, | 163 | no_isfwd, |
| 772 | dylan_no_pad, | 164 | no_pad, |
| 773 | (size_t)headerSIZE | 165 | (size_t)headerSIZE |
| 774 | }; | 166 | }; |
| 775 | 167 | ||
| @@ -778,7 +170,9 @@ static struct mps_fmt_auto_header_s HeaderWeakFormat = | |||
| 778 | 170 | ||
| 779 | mps_res_t EnsureHeaderFormat(mps_fmt_t *mps_fmt_o, mps_arena_t arena) | 171 | mps_res_t EnsureHeaderFormat(mps_fmt_t *mps_fmt_o, mps_arena_t arena) |
| 780 | { | 172 | { |
| 781 | return mps_fmt_create_auto_header(mps_fmt_o, arena, &HeaderFormat); | 173 | dylan_format = dylan_fmt_A(); |
| 174 | HeaderFormat.fwd = dylan_format->fwd; | ||
| 175 | return mps_fmt_create_auto_header(mps_fmt_o, arena, &HeaderFormat); | ||
| 782 | } | 176 | } |
| 783 | 177 | ||
| 784 | 178 | ||
| @@ -786,7 +180,8 @@ mps_res_t EnsureHeaderFormat(mps_fmt_t *mps_fmt_o, mps_arena_t arena) | |||
| 786 | 180 | ||
| 787 | mps_res_t EnsureHeaderWeakFormat(mps_fmt_t *mps_fmt_o, mps_arena_t arena) | 181 | mps_res_t EnsureHeaderWeakFormat(mps_fmt_t *mps_fmt_o, mps_arena_t arena) |
| 788 | { | 182 | { |
| 789 | return mps_fmt_create_auto_header(mps_fmt_o, arena, &HeaderWeakFormat); | 183 | dylan_format = dylan_fmt_A(); |
| 184 | return mps_fmt_create_auto_header(mps_fmt_o, arena, &HeaderWeakFormat); | ||
| 790 | } | 185 | } |
| 791 | 186 | ||
| 792 | 187 | ||
| @@ -794,20 +189,20 @@ mps_res_t EnsureHeaderWeakFormat(mps_fmt_t *mps_fmt_o, mps_arena_t arena) | |||
| 794 | 189 | ||
| 795 | mps_res_t HeaderFormatCheck(mps_addr_t addr) | 190 | mps_res_t HeaderFormatCheck(mps_addr_t addr) |
| 796 | { | 191 | { |
| 797 | if (addr != 0 && ((mps_word_t)addr & (ALIGN-1)) == 0 | 192 | if (addr != 0 && ((mps_word_t)addr & (ALIGN-1)) == 0 |
| 798 | && dylan_wrapper_check((mps_word_t *)((mps_word_t *)addr)[0])) | 193 | && dylan_wrapper_check((mps_word_t *)((mps_word_t *)addr)[0])) |
| 799 | return MPS_RES_OK; | 194 | return MPS_RES_OK; |
| 800 | else | 195 | else |
| 801 | return MPS_RES_FAIL; | 196 | return MPS_RES_FAIL; |
| 802 | } | 197 | } |
| 803 | 198 | ||
| 804 | /* HeaderWeakFormatCheck -- check an object in this format */ | 199 | /* HeaderWeakFormatCheck -- check an object in this format */ |
| 805 | 200 | ||
| 806 | mps_res_t HeaderWeakFormatCheck(mps_addr_t addr) | 201 | mps_res_t HeaderWeakFormatCheck(mps_addr_t addr) |
| 807 | { | 202 | { |
| 808 | if (addr != 0 && ((mps_word_t)addr & (ALIGN-1)) == 0 | 203 | if (addr != 0 && ((mps_word_t)addr & (ALIGN-1)) == 0 |
| 809 | && dylan_wrapper_check((mps_word_t *)((mps_word_t *)addr)[0])) | 204 | && dylan_wrapper_check((mps_word_t *)((mps_word_t *)addr)[0])) |
| 810 | return MPS_RES_OK; | 205 | return MPS_RES_OK; |
| 811 | else | 206 | else |
| 812 | return MPS_RES_FAIL; | 207 | return MPS_RES_FAIL; |
| 813 | } | 208 | } |
diff --git a/mps/code/fmthe.h b/mps/code/fmthe.h index 0445f34d098..f4b5121a17d 100644 --- a/mps/code/fmthe.h +++ b/mps/code/fmthe.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* impl.h.fmthe: DYLAN-LIKE OBJECT FORMAT WITH HEADERS | 1 | /* impl.h.fmthe: HEADERS FOR DYLAN-LIKE OBJECT FORMATS |
| 2 | * | 2 | * |
| 3 | * $Id$ | 3 | * $Id$ |
| 4 | * Copyright (c) 2001 Ravenbrook Limited. | 4 | * Copyright (c) 2001 Ravenbrook Limited. |
| @@ -9,30 +9,12 @@ | |||
| 9 | 9 | ||
| 10 | #include "mps.h" | 10 | #include "mps.h" |
| 11 | 11 | ||
| 12 | |||
| 13 | /* Formats */ | 12 | /* Formats */ |
| 14 | extern mps_res_t EnsureHeaderFormat(mps_fmt_t *, mps_arena_t); | 13 | extern mps_res_t EnsureHeaderFormat(mps_fmt_t *, mps_arena_t); |
| 15 | extern mps_res_t EnsureHeaderWeakFormat(mps_fmt_t *, mps_arena_t); | 14 | extern mps_res_t EnsureHeaderWeakFormat(mps_fmt_t *, mps_arena_t); |
| 16 | extern mps_res_t HeaderFormatCheck(mps_addr_t addr); | 15 | extern mps_res_t HeaderFormatCheck(mps_addr_t addr); |
| 17 | extern mps_res_t HeaderWeakFormatCheck(mps_addr_t addr); | 16 | extern mps_res_t HeaderWeakFormatCheck(mps_addr_t addr); |
| 18 | 17 | ||
| 19 | /* dependent object function for weak pool */ | ||
| 20 | extern mps_addr_t dylan_weak_dependent(mps_addr_t); | ||
| 21 | |||
| 22 | /* Constants describing wrappers. Used only for debugging / testing */ | ||
| 23 | #define WW 0 /* offset of Wrapper-Wrapper */ | ||
| 24 | #define WC 1 /* offset of Class pointer*/ | ||
| 25 | #define WM 2 /* offset of subtype Mask */ | ||
| 26 | #define WF 3 /* offset of Fixed part descriptor */ | ||
| 27 | #define WV 4 /* offset of Vector part descriptor */ | ||
| 28 | #define WS 5 /* offset of Size field for pattern vector */ | ||
| 29 | #define WP 6 /* offset of Pattern 0, if present */ | ||
| 30 | |||
| 31 | #define BASIC_WRAPPER_SIZE (WS + 1) /* size of wrapper with no patterns */ | ||
| 32 | |||
| 33 | #define ALIGN sizeof(mps_word_t) /* alignment for Dylan format */ | ||
| 34 | |||
| 35 | |||
| 36 | #define headerSIZE (32) | 18 | #define headerSIZE (32) |
| 37 | #define headerTypeBits 1 | 19 | #define headerTypeBits 1 |
| 38 | #define realTYPE 0 | 20 | #define realTYPE 0 |
diff --git a/mps/code/fmtno.c b/mps/code/fmtno.c new file mode 100644 index 00000000000..5fb59ac7ac6 --- /dev/null +++ b/mps/code/fmtno.c | |||
| @@ -0,0 +1,143 @@ | |||
| 1 | /* impl.c.fmtno: NULL OBJECT FORMAT IMPLEMENTATION | ||
| 2 | * | ||
| 3 | * $Id$ | ||
| 4 | * Copyright (c) 2001 Ravenbrook Limited. | ||
| 5 | * | ||
| 6 | * .readership: MPS developers | ||
| 7 | */ | ||
| 8 | |||
| 9 | |||
| 10 | #include "fmtno.h" | ||
| 11 | #include "mps.h" | ||
| 12 | #include <assert.h> | ||
| 13 | #include <string.h> | ||
| 14 | #include <stdlib.h> | ||
| 15 | |||
| 16 | #ifdef MPS_PF_SUS8LC | ||
| 17 | /* .hack.stderr: builder.lc (LCC) uses Sun's header files. Sun's | ||
| 18 | * assert.h is broken, as it assumes it can use stderr. We have to | ||
| 19 | * fix it by supplying stderr. | ||
| 20 | */ | ||
| 21 | #include <stdio.h> | ||
| 22 | #endif | ||
| 23 | |||
| 24 | |||
| 25 | #define notreached() assert(0) | ||
| 26 | #define unused(param) ((void)param) | ||
| 27 | |||
| 28 | #ifdef MPS_BUILD_MV | ||
| 29 | |||
| 30 | /* MSVC 2.0 generates a warning for unused(). */ | ||
| 31 | #ifdef _MSC_VER | ||
| 32 | #if _MSC_VER < 1000 | ||
| 33 | #pragma warning(disable: 4705) | ||
| 34 | #endif | ||
| 35 | #else /* _MSC_VER */ | ||
| 36 | #error "Expected _MSC_VER to be defined for builder.mv" | ||
| 37 | #endif /* _MSC_VER */ | ||
| 38 | |||
| 39 | /* windows.h causes warnings about "unreferenced inline function */ | ||
| 40 | /* has been removed". */ | ||
| 41 | #pragma warning(disable: 4514) | ||
| 42 | |||
| 43 | #endif /* MPS_BUILD_MV */ | ||
| 44 | |||
| 45 | #define ALIGN sizeof(mps_word_t) | ||
| 46 | |||
| 47 | /* Functions for the null format. */ | ||
| 48 | |||
| 49 | mps_res_t no_scan(mps_ss_t mps_ss, | ||
| 50 | mps_addr_t base, | ||
| 51 | mps_addr_t limit) | ||
| 52 | { | ||
| 53 | unused(mps_ss); unused(base); unused(limit); | ||
| 54 | notreached(); | ||
| 55 | return 0; | ||
| 56 | } | ||
| 57 | |||
| 58 | mps_addr_t no_skip(mps_addr_t object) | ||
| 59 | { | ||
| 60 | unused(object); | ||
| 61 | notreached(); | ||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | void no_copy(mps_addr_t old, | ||
| 66 | mps_addr_t new) | ||
| 67 | { | ||
| 68 | unused(old); unused(new); | ||
| 69 | notreached(); | ||
| 70 | } | ||
| 71 | |||
| 72 | void no_fwd(mps_addr_t old, | ||
| 73 | mps_addr_t new) | ||
| 74 | { | ||
| 75 | unused(old); unused(new); | ||
| 76 | notreached(); | ||
| 77 | } | ||
| 78 | |||
| 79 | mps_addr_t no_isfwd(mps_addr_t object) | ||
| 80 | { | ||
| 81 | unused(object); | ||
| 82 | notreached(); | ||
| 83 | return 0; | ||
| 84 | } | ||
| 85 | |||
| 86 | void no_pad(mps_addr_t addr, | ||
| 87 | size_t size) | ||
| 88 | { | ||
| 89 | unused(addr); unused(size); | ||
| 90 | notreached(); | ||
| 91 | } | ||
| 92 | |||
| 93 | mps_addr_t no_class(mps_addr_t obj) | ||
| 94 | { | ||
| 95 | unused(obj); | ||
| 96 | notreached(); | ||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | |||
| 100 | /* The null format structures */ | ||
| 101 | |||
| 102 | static struct mps_fmt_A_s no_fmt_A_s = | ||
| 103 | { | ||
| 104 | ALIGN, | ||
| 105 | no_scan, | ||
| 106 | no_skip, | ||
| 107 | no_copy, | ||
| 108 | no_fwd, | ||
| 109 | no_isfwd, | ||
| 110 | no_pad | ||
| 111 | }; | ||
| 112 | |||
| 113 | static struct mps_fmt_B_s no_fmt_B_s = | ||
| 114 | { | ||
| 115 | ALIGN, | ||
| 116 | no_scan, | ||
| 117 | no_skip, | ||
| 118 | no_copy, | ||
| 119 | no_fwd, | ||
| 120 | no_isfwd, | ||
| 121 | no_pad, | ||
| 122 | no_class | ||
| 123 | }; | ||
| 124 | |||
| 125 | /* Functions returning the null format structures. */ | ||
| 126 | |||
| 127 | mps_fmt_A_s *no_fmt_A(void) | ||
| 128 | { | ||
| 129 | return &no_fmt_A_s; | ||
| 130 | } | ||
| 131 | |||
| 132 | mps_fmt_B_s *no_fmt_B(void) | ||
| 133 | { | ||
| 134 | return &no_fmt_B_s; | ||
| 135 | } | ||
| 136 | |||
| 137 | /* Format variety-independent version that picks the right format | ||
| 138 | * variety and creates it. */ | ||
| 139 | |||
| 140 | mps_res_t no_fmt(mps_fmt_t *mps_fmt_o, mps_arena_t arena) | ||
| 141 | { | ||
| 142 | return mps_fmt_create_B(mps_fmt_o, arena, no_fmt_B()); | ||
| 143 | } | ||
diff --git a/mps/code/fmtno.h b/mps/code/fmtno.h new file mode 100644 index 00000000000..b98fa35f27c --- /dev/null +++ b/mps/code/fmtno.h | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | /* impl.h.fmtdy: NULL OBJECT FORMAT | ||
| 2 | * | ||
| 3 | * $Id$ | ||
| 4 | * Copyright (c) 2001 Ravenbrook Limited. | ||
| 5 | */ | ||
| 6 | |||
| 7 | #ifndef fmtno_h | ||
| 8 | #define fmtno_h | ||
| 9 | |||
| 10 | #include "mps.h" | ||
| 11 | |||
| 12 | extern mps_res_t no_scan(mps_ss_t, mps_addr_t, mps_addr_t); | ||
| 13 | extern mps_addr_t no_skip(mps_addr_t); | ||
| 14 | extern void no_copy(mps_addr_t, mps_addr_t); | ||
| 15 | extern void no_fwd(mps_addr_t, mps_addr_t); | ||
| 16 | extern mps_addr_t no_isfwd(mps_addr_t); | ||
| 17 | extern void no_pad(mps_addr_t, size_t); | ||
| 18 | extern mps_addr_t no_class(mps_addr_t); | ||
| 19 | |||
| 20 | extern mps_fmt_A_s *no_fmt_A(void); | ||
| 21 | extern mps_fmt_B_s *no_fmt_B(void); | ||
| 22 | extern mps_res_t no_fmt(mps_fmt_t *, mps_arena_t); | ||
| 23 | |||
| 24 | #endif /* fmtno_h */ | ||
diff --git a/mps/code/mpsicv.c b/mps/code/mpsicv.c index c581efdc188..b22f845bf92 100644 --- a/mps/code/mpsicv.c +++ b/mps/code/mpsicv.c | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "mpsavm.h" | 9 | #include "mpsavm.h" |
| 10 | #include "mpscmv.h" | 10 | #include "mpscmv.h" |
| 11 | #include "fmtdy.h" | 11 | #include "fmtdy.h" |
| 12 | #include "fmtdytst.h" | ||
| 12 | #include "mpstd.h" | 13 | #include "mpstd.h" |
| 13 | #ifdef MPS_OS_W3 | 14 | #ifdef MPS_OS_W3 |
| 14 | #include "mpsw3.h" | 15 | #include "mpsw3.h" |
| @@ -288,7 +289,7 @@ static void *test(void *arg, size_t s) | |||
| 288 | 289 | ||
| 289 | die(mps_pool_create(&mv, arena, mps_class_mv(), 0x10000, 32, 0x10000), | 290 | die(mps_pool_create(&mv, arena, mps_class_mv(), 0x10000, 32, 0x10000), |
| 290 | "pool_create(mv)"); | 291 | "pool_create(mv)"); |
| 291 | 292 | ||
| 292 | pool_create_v_test(arena, format, chain); /* creates amc pool */ | 293 | pool_create_v_test(arena, format, chain); /* creates amc pool */ |
| 293 | 294 | ||
| 294 | ap_create_v_test(amcpool); | 295 | ap_create_v_test(amcpool); |
diff --git a/mps/code/segsmss.c b/mps/code/segsmss.c index 3acd229a41c..590195a193c 100644 --- a/mps/code/segsmss.c +++ b/mps/code/segsmss.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "mpm.h" | 13 | #include "mpm.h" |
| 14 | #include "poolams.h" | 14 | #include "poolams.h" |
| 15 | #include "fmtdy.h" | 15 | #include "fmtdy.h" |
| 16 | #include "fmtdytst.h" | ||
| 16 | #include "testlib.h" | 17 | #include "testlib.h" |
| 17 | #include "chain.h" | 18 | #include "chain.h" |
| 18 | #include "mpscams.h" | 19 | #include "mpscams.h" |
| @@ -163,7 +164,7 @@ static void amstSegFinish(Seg seg) | |||
| 163 | /* finish the superclass fields last */ | 164 | /* finish the superclass fields last */ |
| 164 | super = SEG_SUPERCLASS(AMSTSegClass); | 165 | super = SEG_SUPERCLASS(AMSTSegClass); |
| 165 | super->finish(seg); | 166 | super->finish(seg); |
| 166 | } | 167 | } |
| 167 | 168 | ||
| 168 | 169 | ||
| 169 | 170 | ||
| @@ -581,7 +582,7 @@ static Res AMSTBufferFill(Addr *baseReturn, Addr *limitReturn, | |||
| 581 | Seg segLo, segHi; | 582 | Seg segLo, segHi; |
| 582 | Res sres; | 583 | Res sres; |
| 583 | AMSUnallocateRange(seg, mid, limit); | 584 | AMSUnallocateRange(seg, mid, limit); |
| 584 | sres = SegSplit(&segLo, &segHi, seg, mid, withReservoirPermit); | 585 | sres = SegSplit(&segLo, &segHi, seg, mid, withReservoirPermit); |
| 585 | if (ResOK == sres) { /* successful split */ | 586 | if (ResOK == sres) { /* successful split */ |
| 586 | limit = mid; /* range is lower segment */ | 587 | limit = mid; /* range is lower segment */ |
| 587 | } else { /* failed to split */ | 588 | } else { /* failed to split */ |