aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorNick Barnes2002-05-14 13:06:13 +0100
committerNick Barnes2002-05-14 13:06:13 +0100
commit833f5bf257e3acff6162176efc70f25ef005b037 (patch)
treee41f7ed1e545bf2d69dd28431c149b424ea252f5 /mps/code
parentc5e9dc4c8402721d8ed29a368ea7604136c00341 (diff)
downloademacs-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.c5
-rw-r--r--mps/code/amcsshe.c97
-rw-r--r--mps/code/amsss.c1
-rw-r--r--mps/code/amssshe.c26
-rw-r--r--mps/code/awluthe.c1
-rw-r--r--mps/code/comm.gmk20
-rw-r--r--mps/code/finalcv.c1
-rw-r--r--mps/code/fmtdy.c113
-rw-r--r--mps/code/fmtdy.h17
-rw-r--r--mps/code/fmtdytst.c13
-rw-r--r--mps/code/fmtdytst.h21
-rw-r--r--mps/code/fmthe.c749
-rw-r--r--mps/code/fmthe.h20
-rw-r--r--mps/code/fmtno.c143
-rw-r--r--mps/code/fmtno.h24
-rw-r--r--mps/code/mpsicv.c3
-rw-r--r--mps/code/segsmss.c5
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)
50static void report(mps_arena_t arena) 51static 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];
44static mps_addr_t ambigRoots[ambigRootsCOUNT]; 45static mps_addr_t ambigRoots[ambigRootsCOUNT];
45static mps_addr_t bogusRoots[bogusRootsCOUNT]; 46static mps_addr_t bogusRoots[bogusRootsCOUNT];
46 47
47
48
49static mps_word_t *ww = NULL;
50static mps_word_t *tvw;
51
52
53static 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
64static 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
123static 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
141static mps_addr_t make(void) 48static 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;
45static mps_addr_t make(void) 44static 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
191POOLN = pooln.c 191POOLN = pooln.c
192MVFF = poolmvff.c 192MVFF = poolmvff.c
193TESTLIB = testlib.c 193TESTLIB = testlib.c
194FMTDY = fmtdy.c 194FMTDY = fmtdy.c fmtno.c
195FMTDYTST = fmtdy.c fmtdytst.c 195FMTDYTST = fmtdy.c fmtno.c fmtdytst.c
196FMTHETST = fmthe.c fmtdy.c fmtno.c fmtdytst.c
196FMTPS = fmtpstst.c 197FMTPS = fmtpstst.c
197PLINTH = mpsliban.c mpsioan.c 198PLINTH = mpsliban.c mpsioan.c
198EVENTPROC = eventcnv.c eventpro.c table.c 199EVENTPROC = eventcnv.c eventpro.c table.c
@@ -262,7 +263,7 @@ TESTLIBDEP = $(TESTLIB:%.c=$(PFM)/$(VARIETY)/%.d)
262FMTDYOBJ = $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.o) 263FMTDYOBJ = $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.o)
263FMTDYDEP = $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.d) 264FMTDYDEP = $(FMTDY:%.c=$(PFM)/$(VARIETY)/%.d)
264FMTDYTSTOBJ = $(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.o) 265FMTDYTSTOBJ = $(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.o)
265FMTDYTSTDEP = $(FMTDYTST:%.c=$(PFM)/$(VARIETY)/%.d) 266FMTHETSTOBJ = $(FMTHETST:%.c=$(PFM)/$(VARIETY)/%.o)
266FMTPSOBJ = $(FMTPS:%.c=$(PFM)/$(VARIETY)/%.o) 267FMTPSOBJ = $(FMTPS:%.c=$(PFM)/$(VARIETY)/%.o)
267FMTPSDEP = $(FMTPS:%.c=$(PFM)/$(VARIETY)/%.d) 268FMTPSDEP = $(FMTPS:%.c=$(PFM)/$(VARIETY)/%.d)
268PLINTHOBJ = $(PLINTH:%.c=$(PFM)/$(VARIETY)/%.o) 269PLINTHOBJ = $(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
280all: mpmss sacss amcss amcsshe amsss segsmss awlut awluthe \ 281all: 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
292testrun: mpmss apss sacss amcss amcsshe amsss segsmss awlut awluthe \ 293testrun: 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
307mpmss sacss amcss amcssth amcsshe amsss segsmss awlut awlutth \ 308mpmss 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
108int dylan_wrapper_check(mps_word_t *w) 107int 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
371static mps_res_t dylan_scan1(mps_ss_t mps_ss, mps_addr_t *object_io) 370extern 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
547static mps_res_t dylan_scan1_weak(mps_ss_t mps_ss, mps_addr_t *object_io) 546extern 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
695static void dylan_no_copy(mps_addr_t old, mps_addr_t new)
696{
697 unused(old); unused(new);
698 notreached();
699}
700
701static mps_addr_t dylan_isfwd(mps_addr_t object) 694static 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
713static mps_addr_t dylan_no_isfwd(mps_addr_t object)
714{
715 unused(object);
716 notreached();
717 return 0;
718}
719
720static void dylan_fwd(mps_addr_t old, mps_addr_t new) 706static 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
738static void dylan_no_fwd(mps_addr_t old, mps_addr_t new)
739{
740 unused(old); unused(new);
741 notreached();
742}
743
744void dylan_pad(mps_addr_t addr, size_t size) 724void 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
757static 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
763static struct mps_fmt_A_s dylan_fmt_A_s = 740static 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
774static struct mps_fmt_A_s dylan_fmt_A_weak_s = 751static 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
785mps_fmt_A_s *dylan_fmt_A(void) 765mps_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
790mps_fmt_A_s *dylan_fmt_A_weak(void) 770mps_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
796static struct mps_fmt_B_s dylan_fmt_B_s = 778mps_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
785static 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
808static struct mps_fmt_B_s dylan_fmt_B_weak_s = 796static 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
820mps_fmt_B_s *dylan_fmt_B(void) 808/* Functions returning the weak format structures */
809
810mps_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
825mps_fmt_B_s *dylan_fmt_B_weak(void) 816mps_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
835mps_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
840mps_res_t dylan_fmt_weak(mps_fmt_t *mps_fmt_o, mps_arena_t arena) 825mps_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
846mps_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. */
14extern mps_res_t dylan_scan1(mps_ss_t, mps_addr_t *);
15extern mps_res_t dylan_scan1_weak(mps_ss_t, mps_addr_t *);
16
12/* Format */ 17/* Format */
13extern mps_fmt_A_s *dylan_fmt_A(void); 18extern mps_fmt_A_s *dylan_fmt_A(void);
14extern mps_fmt_A_s *dylan_fmt_A_weak(void); 19extern mps_fmt_A_s *dylan_fmt_A_weak(void);
@@ -17,15 +22,13 @@ extern mps_fmt_B_s *dylan_fmt_B_weak(void);
17extern mps_res_t dylan_fmt(mps_fmt_t *, mps_arena_t); 22extern mps_res_t dylan_fmt(mps_fmt_t *, mps_arena_t);
18extern mps_res_t dylan_fmt_weak(mps_fmt_t *, mps_arena_t); 23extern mps_res_t dylan_fmt_weak(mps_fmt_t *, mps_arena_t);
19 24
25/* The null format */
26extern mps_fmt_A_s *no_fmt_A(void);
27extern mps_fmt_B_s *no_fmt_B(void);
28extern mps_res_t no_fmt(mps_fmt_t *, mps_arena_t);
29
20extern mps_addr_t dylan_weak_dependent(mps_addr_t); 30extern mps_addr_t dylan_weak_dependent(mps_addr_t);
21 31
22/* Used only for debugging / testing */
23extern mps_res_t dylan_init(mps_addr_t addr, size_t size,
24 mps_addr_t *refs, size_t nr_refs);
25extern void dylan_write(mps_addr_t addr,
26 mps_addr_t *refs, size_t nr_refs);
27extern mps_addr_t dylan_read(mps_addr_t addr);
28extern mps_bool_t dylan_check(mps_addr_t addr);
29extern void dylan_pad(mps_addr_t addr, size_t size); 32extern void dylan_pad(mps_addr_t addr, size_t size);
30extern int dylan_wrapper_check(mps_word_t *w); 33extern 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
144mps_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
12extern mps_res_t dylan_init(mps_addr_t addr, size_t size,
13 mps_addr_t *refs, size_t nr_refs);
14extern void dylan_write(mps_addr_t addr,
15 mps_addr_t *refs, size_t nr_refs);
16extern mps_addr_t dylan_read(mps_addr_t addr);
17extern mps_bool_t dylan_check(mps_addr_t addr);
18extern void dylan_pad(mps_addr_t addr, size_t size);
19extern 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
76static unsigned long dylan_vff_counts[4*8];
77static unsigned long dylan_fl_counts[FMTDY_FL_LIMIT];
78static unsigned long dylan_fl_oversize_count;
79static unsigned long dylan_fw_counts[2];
80#else
81#define FMTDY_COUNT(x)
82#endif /* FMTDY_COUNTING */
83
84
85static 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
196static 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
222extern 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
253static mps_res_t
254dylan_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
299static 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
37static mps_fmt_A_s *dylan_format;
342 38
343#define NONWORD_LENGTH(_vt, _es) \ 39static 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
349static 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
509static 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
526static mps_res_t dylan_scan1_weak(mps_ss_t mps_ss, mps_addr_t *object_io) 68static 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
602static 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
617static mps_addr_t dylan_skip(mps_addr_t object) 98static 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
687static mps_addr_t dylan_isfwd(mps_addr_t object) 123static 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
705static 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
724static void dylan_pad(mps_addr_t addr, size_t fullSize) 135static 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
730static mps_addr_t dylan_no_isfwd(mps_addr_t object)
731{
732 unused(object);
733 notreached();
734 return 0;
735}
736
737static void dylan_no_fwd(mps_addr_t old, mps_addr_t new)
738{
739 unused(old); unused(new);
740 notreached();
741}
742
743static 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
751static struct mps_fmt_auto_header_s HeaderFormat = 143static 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 =
765static struct mps_fmt_auto_header_s HeaderWeakFormat = 157static 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
779mps_res_t EnsureHeaderFormat(mps_fmt_t *mps_fmt_o, mps_arena_t arena) 171mps_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
787mps_res_t EnsureHeaderWeakFormat(mps_fmt_t *mps_fmt_o, mps_arena_t arena) 181mps_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
795mps_res_t HeaderFormatCheck(mps_addr_t addr) 190mps_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
806mps_res_t HeaderWeakFormatCheck(mps_addr_t addr) 201mps_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 */
14extern mps_res_t EnsureHeaderFormat(mps_fmt_t *, mps_arena_t); 13extern mps_res_t EnsureHeaderFormat(mps_fmt_t *, mps_arena_t);
15extern mps_res_t EnsureHeaderWeakFormat(mps_fmt_t *, mps_arena_t); 14extern mps_res_t EnsureHeaderWeakFormat(mps_fmt_t *, mps_arena_t);
16extern mps_res_t HeaderFormatCheck(mps_addr_t addr); 15extern mps_res_t HeaderFormatCheck(mps_addr_t addr);
17extern mps_res_t HeaderWeakFormatCheck(mps_addr_t addr); 16extern mps_res_t HeaderWeakFormatCheck(mps_addr_t addr);
18 17
19/* dependent object function for weak pool */
20extern 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
49mps_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
58mps_addr_t no_skip(mps_addr_t object)
59{
60 unused(object);
61 notreached();
62 return 0;
63}
64
65void no_copy(mps_addr_t old,
66 mps_addr_t new)
67{
68 unused(old); unused(new);
69 notreached();
70}
71
72void no_fwd(mps_addr_t old,
73 mps_addr_t new)
74{
75 unused(old); unused(new);
76 notreached();
77}
78
79mps_addr_t no_isfwd(mps_addr_t object)
80{
81 unused(object);
82 notreached();
83 return 0;
84}
85
86void no_pad(mps_addr_t addr,
87 size_t size)
88{
89 unused(addr); unused(size);
90 notreached();
91}
92
93mps_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
102static 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
113static 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
127mps_fmt_A_s *no_fmt_A(void)
128{
129 return &no_fmt_A_s;
130}
131
132mps_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
140mps_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
12extern mps_res_t no_scan(mps_ss_t, mps_addr_t, mps_addr_t);
13extern mps_addr_t no_skip(mps_addr_t);
14extern void no_copy(mps_addr_t, mps_addr_t);
15extern void no_fwd(mps_addr_t, mps_addr_t);
16extern mps_addr_t no_isfwd(mps_addr_t);
17extern void no_pad(mps_addr_t, size_t);
18extern mps_addr_t no_class(mps_addr_t);
19
20extern mps_fmt_A_s *no_fmt_A(void);
21extern mps_fmt_B_s *no_fmt_B(void);
22extern 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 */