aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorRichard Brooksby2012-09-10 11:12:28 +0100
committerRichard Brooksby2012-09-10 11:12:28 +0100
commit1c9b8d7eb3455c6ebbf10e5a9b6e8f49dbb51d79 (patch)
treebd72728f108fb124c40efeea2af1b28c7f8efe71 /mps/code
parent75837d8376b7523c3a70fc0c213e9d816642ab89 (diff)
downloademacs-1c9b8d7eb3455c6ebbf10e5a9b6e8f49dbb51d79.tar.gz
emacs-1c9b8d7eb3455c6ebbf10e5a9b6e8f49dbb51d79.zip
Removing enternal/external type puns from segregated allocation caches.
Copied from Perforce Change: 179383 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/mps.h50
-rw-r--r--mps/code/mpsi.c43
-rw-r--r--mps/code/sac.c173
-rw-r--r--mps/code/sac.h36
4 files changed, 131 insertions, 171 deletions
diff --git a/mps/code/mps.h b/mps/code/mps.h
index c0d7a20286d..6e3a450a3ac 100644
--- a/mps/code/mps.h
+++ b/mps/code/mps.h
@@ -148,23 +148,23 @@ typedef struct mps_sac_s *mps_sac_t;
148#define MPS_SAC_CLASS_LIMIT ((size_t)8) 148#define MPS_SAC_CLASS_LIMIT ((size_t)8)
149 149
150typedef struct mps_sac_freelist_block_s { 150typedef struct mps_sac_freelist_block_s {
151 size_t mps_size; 151 size_t _size;
152 size_t mps_count; 152 size_t _count;
153 size_t mps_count_max; 153 size_t _count_max;
154 mps_addr_t mps_blocks; 154 mps_addr_t _blocks;
155} mps_sac_freelist_block_s; 155} mps_sac_freelist_block_s;
156 156
157typedef struct mps_sac_s { 157typedef struct mps_sac_s {
158 size_t mps_middle; 158 size_t _middle;
159 mps_bool_t mps_trapped; 159 mps_bool_t _trapped;
160 mps_sac_freelist_block_s mps_freelists[2 * MPS_SAC_CLASS_LIMIT]; 160 mps_sac_freelist_block_s _freelists[2 * MPS_SAC_CLASS_LIMIT];
161} mps_sac_s; 161} mps_sac_s;
162 162
163/* .sacc: Keep in sync with <code/sac.h>. */ 163/* .sacc: Keep in sync with <code/sac.h>. */
164typedef struct mps_sac_class_s { 164typedef struct mps_sac_class_s {
165 size_t mps_block_size; 165 size_t _block_size;
166 size_t mps_cached_count; 166 size_t _cached_count;
167 unsigned mps_frequency; 167 unsigned _frequency;
168} mps_sac_class_s; 168} mps_sac_class_s;
169 169
170#define mps_sac_classes_s mps_sac_class_s 170#define mps_sac_classes_s mps_sac_class_s
@@ -386,19 +386,19 @@ extern void mps_sac_empty(mps_sac_t, mps_addr_t, size_t);
386 size_t _mps_i, _mps_s; \ 386 size_t _mps_i, _mps_s; \
387 \ 387 \
388 _mps_s = (size); \ 388 _mps_s = (size); \
389 if (_mps_s > (sac)->mps_middle) { \ 389 if (_mps_s > (sac)->_middle) { \
390 _mps_i = 0; \ 390 _mps_i = 0; \
391 while (_mps_s > (sac)->mps_freelists[_mps_i].mps_size) \ 391 while (_mps_s > (sac)->_freelists[_mps_i]._size) \
392 _mps_i += 2; \ 392 _mps_i += 2; \
393 } else { \ 393 } else { \
394 _mps_i = 1; \ 394 _mps_i = 1; \
395 while (_mps_s <= (sac)->mps_freelists[_mps_i].mps_size) \ 395 while (_mps_s <= (sac)->_freelists[_mps_i]._size) \
396 _mps_i += 2; \ 396 _mps_i += 2; \
397 } \ 397 } \
398 if ((sac)->mps_freelists[_mps_i].mps_count != 0) { \ 398 if ((sac)->_freelists[_mps_i]._count != 0) { \
399 (p_o) = (sac)->mps_freelists[_mps_i].mps_blocks; \ 399 (p_o) = (sac)->_freelists[_mps_i]._blocks; \
400 (sac)->mps_freelists[_mps_i].mps_blocks = *(mps_addr_t *)(p_o); \ 400 (sac)->_freelists[_mps_i]._blocks = *(mps_addr_t *)(p_o); \
401 --(sac)->mps_freelists[_mps_i].mps_count; \ 401 --(sac)->_freelists[_mps_i]._count; \
402 (res_o) = MPS_RES_OK; \ 402 (res_o) = MPS_RES_OK; \
403 } else \ 403 } else \
404 (res_o) = mps_sac_fill(&(p_o), sac, _mps_s, \ 404 (res_o) = mps_sac_fill(&(p_o), sac, _mps_s, \
@@ -410,20 +410,20 @@ extern void mps_sac_empty(mps_sac_t, mps_addr_t, size_t);
410 size_t _mps_i, _mps_s; \ 410 size_t _mps_i, _mps_s; \
411 \ 411 \
412 _mps_s = (size); \ 412 _mps_s = (size); \
413 if (_mps_s > (sac)->mps_middle) { \ 413 if (_mps_s > (sac)->_middle) { \
414 _mps_i = 0; \ 414 _mps_i = 0; \
415 while (_mps_s > (sac)->mps_freelists[_mps_i].mps_size) \ 415 while (_mps_s > (sac)->_freelists[_mps_i]._size) \
416 _mps_i += 2; \ 416 _mps_i += 2; \
417 } else { \ 417 } else { \
418 _mps_i = 1; \ 418 _mps_i = 1; \
419 while (_mps_s <= (sac)->mps_freelists[_mps_i].mps_size) \ 419 while (_mps_s <= (sac)->_freelists[_mps_i]._size) \
420 _mps_i += 2; \ 420 _mps_i += 2; \
421 } \ 421 } \
422 if ((sac)->mps_freelists[_mps_i].mps_count \ 422 if ((sac)->_freelists[_mps_i]._count \
423 < (sac)->mps_freelists[_mps_i].mps_count_max) { \ 423 < (sac)->_freelists[_mps_i]._count_max) { \
424 *(mps_addr_t *)(p) = (sac)->mps_freelists[_mps_i].mps_blocks; \ 424 *(mps_addr_t *)(p) = (sac)->_freelists[_mps_i]._blocks; \
425 (sac)->mps_freelists[_mps_i].mps_blocks = (p); \ 425 (sac)->_freelists[_mps_i]._blocks = (p); \
426 ++(sac)->mps_freelists[_mps_i].mps_count; \ 426 ++(sac)->_freelists[_mps_i]._count; \
427 } else \ 427 } else \
428 mps_sac_empty(sac, p, _mps_s); \ 428 mps_sac_empty(sac, p, _mps_s); \
429 MPS_END 429 MPS_END
diff --git a/mps/code/mpsi.c b/mps/code/mpsi.c
index 9f29466a3a7..7e82291142a 100644
--- a/mps/code/mpsi.c
+++ b/mps/code/mpsi.c
@@ -113,35 +113,6 @@ static Bool mpsi_check(void)
113 /* out to external. */ 113 /* out to external. */
114 CHECKL(COMPATTYPE(mps_clock_t, Clock)); 114 CHECKL(COMPATTYPE(mps_clock_t, Clock));
115 115
116 /* Check sac_s/ExternalSACStruct compatibility by hand */
117 /* See <code/mps.h#sac> and <code/sac.h#sac>. */
118 CHECKL(sizeof(mps_sac_s) == sizeof(ExternalSACStruct));
119 CHECKL(COMPATFIELD(mps_sac_s, mps_middle, ExternalSACStruct, middle));
120 CHECKL(COMPATFIELD(mps_sac_s, mps_trapped,
121 ExternalSACStruct, trapped));
122 CHECKL(COMPATFIELDAPPROX(mps_sac_s, mps_freelists,
123 ExternalSACStruct, freelists));
124 CHECKL(sizeof(mps_sac_freelist_block_s)
125 == sizeof(SACFreeListBlockStruct));
126 CHECKL(COMPATFIELD(mps_sac_freelist_block_s, mps_size,
127 SACFreeListBlockStruct, size));
128 CHECKL(COMPATFIELD(mps_sac_freelist_block_s, mps_count,
129 SACFreeListBlockStruct, count));
130 CHECKL(COMPATFIELD(mps_sac_freelist_block_s, mps_count_max,
131 SACFreeListBlockStruct, countMax));
132 CHECKL(COMPATFIELD(mps_sac_freelist_block_s, mps_blocks,
133 SACFreeListBlockStruct, blocks));
134
135 /* Check sac_classes_s/SACClassesStruct compatibility by hand */
136 /* See <code/mps.h#sacc> and <code/sac.h#sacc>. */
137 CHECKL(sizeof(mps_sac_classes_s) == sizeof(SACClassesStruct));
138 CHECKL(COMPATFIELD(mps_sac_classes_s, mps_block_size,
139 SACClassesStruct, blockSize));
140 CHECKL(COMPATFIELD(mps_sac_classes_s, mps_cached_count,
141 SACClassesStruct, cachedCount));
142 CHECKL(COMPATFIELD(mps_sac_classes_s, mps_frequency,
143 SACClassesStruct, frequency));
144
145 return TRUE; 116 return TRUE;
146} 117}
147 118
@@ -1131,7 +1102,7 @@ mps_res_t mps_sac_create(mps_sac_t *mps_sac_o, mps_pool_t mps_pool,
1131 ArenaLeave(arena); 1102 ArenaLeave(arena);
1132 1103
1133 if (res != ResOK) return (mps_res_t)res; 1104 if (res != ResOK) return (mps_res_t)res;
1134 *mps_sac_o = (mps_sac_t)ExternalSACOfSAC(sac); 1105 *mps_sac_o = ExternalSACOfSAC(sac);
1135 return (mps_res_t)res; 1106 return (mps_res_t)res;
1136} 1107}
1137 1108
@@ -1140,7 +1111,7 @@ mps_res_t mps_sac_create(mps_sac_t *mps_sac_o, mps_pool_t mps_pool,
1140 1111
1141void mps_sac_destroy(mps_sac_t mps_sac) 1112void mps_sac_destroy(mps_sac_t mps_sac)
1142{ 1113{
1143 SAC sac = SACOfExternalSAC((ExternalSAC)mps_sac); 1114 SAC sac = SACOfExternalSAC(mps_sac);
1144 Arena arena; 1115 Arena arena;
1145 1116
1146 AVER(TESTT(SAC, sac)); 1117 AVER(TESTT(SAC, sac));
@@ -1158,7 +1129,7 @@ void mps_sac_destroy(mps_sac_t mps_sac)
1158 1129
1159void mps_sac_flush(mps_sac_t mps_sac) 1130void mps_sac_flush(mps_sac_t mps_sac)
1160{ 1131{
1161 SAC sac = SACOfExternalSAC((ExternalSAC)mps_sac); 1132 SAC sac = SACOfExternalSAC(mps_sac);
1162 Arena arena; 1133 Arena arena;
1163 1134
1164 AVER(TESTT(SAC, sac)); 1135 AVER(TESTT(SAC, sac));
@@ -1177,7 +1148,7 @@ void mps_sac_flush(mps_sac_t mps_sac)
1177mps_res_t mps_sac_fill(mps_addr_t *p_o, mps_sac_t mps_sac, size_t size, 1148mps_res_t mps_sac_fill(mps_addr_t *p_o, mps_sac_t mps_sac, size_t size,
1178 mps_bool_t has_reservoir_permit) 1149 mps_bool_t has_reservoir_permit)
1179{ 1150{
1180 SAC sac = SACOfExternalSAC((ExternalSAC)mps_sac); 1151 SAC sac = SACOfExternalSAC(mps_sac);
1181 Arena arena; 1152 Arena arena;
1182 Addr p = NULL; /* suppress "may be used uninitialized" */ 1153 Addr p = NULL; /* suppress "may be used uninitialized" */
1183 Res res; 1154 Res res;
@@ -1202,7 +1173,7 @@ mps_res_t mps_sac_fill(mps_addr_t *p_o, mps_sac_t mps_sac, size_t size,
1202 1173
1203void mps_sac_empty(mps_sac_t mps_sac, mps_addr_t p, size_t size) 1174void mps_sac_empty(mps_sac_t mps_sac, mps_addr_t p, size_t size)
1204{ 1175{
1205 SAC sac = SACOfExternalSAC((ExternalSAC)mps_sac); 1176 SAC sac = SACOfExternalSAC(mps_sac);
1206 Arena arena; 1177 Arena arena;
1207 1178
1208 AVER(TESTT(SAC, sac)); 1179 AVER(TESTT(SAC, sac));
@@ -1224,7 +1195,7 @@ mps_res_t mps_sac_alloc(mps_addr_t *p_o, mps_sac_t mps_sac, size_t size,
1224 Res res; 1195 Res res;
1225 1196
1226 AVER(p_o != NULL); 1197 AVER(p_o != NULL);
1227 AVER(TESTT(SAC, SACOfExternalSAC((ExternalSAC)mps_sac))); 1198 AVER(TESTT(SAC, SACOfExternalSAC(mps_sac)));
1228 AVER(size > 0); 1199 AVER(size > 0);
1229 1200
1230 MPS_SAC_ALLOC_FAST(res, *p_o, mps_sac, size, (has_reservoir_permit != 0)); 1201 MPS_SAC_ALLOC_FAST(res, *p_o, mps_sac, size, (has_reservoir_permit != 0));
@@ -1236,7 +1207,7 @@ mps_res_t mps_sac_alloc(mps_addr_t *p_o, mps_sac_t mps_sac, size_t size,
1236 1207
1237void mps_sac_free(mps_sac_t mps_sac, mps_addr_t p, size_t size) 1208void mps_sac_free(mps_sac_t mps_sac, mps_addr_t p, size_t size)
1238{ 1209{
1239 AVER(TESTT(SAC, SACOfExternalSAC((ExternalSAC)mps_sac))); 1210 AVER(TESTT(SAC, SACOfExternalSAC(mps_sac)));
1240 /* Can't check p outside arena lock */ 1211 /* Can't check p outside arena lock */
1241 AVER(size > 0); 1212 AVER(size > 0);
1242 1213
diff --git a/mps/code/sac.c b/mps/code/sac.c
index 93cec214934..3b82cd846d8 100644
--- a/mps/code/sac.c
+++ b/mps/code/sac.c
@@ -10,6 +10,9 @@
10SRCID(sac, "$Id$"); 10SRCID(sac, "$Id$");
11 11
12 12
13typedef mps_sac_freelist_block_s *SACFreeListBlock;
14
15
13/* SACCheck -- check function for SACs */ 16/* SACCheck -- check function for SACs */
14 17
15static Bool sacFreeListBlockCheck(SACFreeListBlock fb) 18static Bool sacFreeListBlockCheck(SACFreeListBlock fb)
@@ -18,9 +21,9 @@ static Bool sacFreeListBlockCheck(SACFreeListBlock fb)
18 Addr cb; 21 Addr cb;
19 22
20 /* nothing to check about size */ 23 /* nothing to check about size */
21 CHECKL(fb->count <= fb->countMax); 24 CHECKL(fb->_count <= fb->_count_max);
22 /* check the freelist has the right number of blocks */ 25 /* check the freelist has the right number of blocks */
23 for (j = 0, cb = fb->blocks; j < fb->count; ++j) { 26 for (j = 0, cb = fb->_blocks; j < fb->_count; ++j) {
24 CHECKL(cb != NULL); 27 CHECKL(cb != NULL);
25 /* @@@@ ignoring shields for now */ 28 /* @@@@ ignoring shields for now */
26 cb = *ADDR_PTR(Addr, cb); 29 cb = *ADDR_PTR(Addr, cb);
@@ -34,38 +37,40 @@ static Bool SACCheck(SAC sac)
34 Index i, j; 37 Index i, j;
35 Bool b; 38 Bool b;
36 Size prevSize; 39 Size prevSize;
40 mps_sac_t esac;
37 41
38 CHECKS(SAC, sac); 42 CHECKS(SAC, sac);
43 esac = ExternalSACOfSAC(sac);
39 CHECKU(Pool, sac->pool); 44 CHECKU(Pool, sac->pool);
40 CHECKL(sac->classesCount > 0); 45 CHECKL(sac->classesCount > 0);
41 CHECKL(sac->classesCount > sac->middleIndex); 46 CHECKL(sac->classesCount > sac->middleIndex);
42 CHECKL(BoolCheck(sac->esacStruct.trapped)); 47 CHECKL(BoolCheck(esac->_trapped));
43 CHECKL(sac->esacStruct.middle > 0); 48 CHECKL(esac->_middle > 0);
44 /* check classes above middle */ 49 /* check classes above middle */
45 prevSize = sac->esacStruct.middle; 50 prevSize = esac->_middle;
46 for (j = sac->middleIndex + 1, i = 0; 51 for (j = sac->middleIndex + 1, i = 0;
47 j <= sac->classesCount; ++j, i += 2) { 52 j <= sac->classesCount; ++j, i += 2) {
48 CHECKL(prevSize < sac->esacStruct.freelists[i].size); 53 CHECKL(prevSize < esac->_freelists[i]._size);
49 b = sacFreeListBlockCheck(&(sac->esacStruct.freelists[i])); 54 b = sacFreeListBlockCheck(&(esac->_freelists[i]));
50 if (!b) return b; 55 if (!b) return b;
51 prevSize = sac->esacStruct.freelists[i].size; 56 prevSize = esac->_freelists[i]._size;
52 } 57 }
53 /* check overlarge class */ 58 /* check overlarge class */
54 CHECKL(sac->esacStruct.freelists[i-2].size == SizeMAX); 59 CHECKL(esac->_freelists[i-2]._size == SizeMAX);
55 CHECKL(sac->esacStruct.freelists[i-2].count == 0); 60 CHECKL(esac->_freelists[i-2]._count == 0);
56 CHECKL(sac->esacStruct.freelists[i-2].countMax == 0); 61 CHECKL(esac->_freelists[i-2]._count_max == 0);
57 CHECKL(sac->esacStruct.freelists[i-2].blocks == NULL); 62 CHECKL(esac->_freelists[i-2]._blocks == NULL);
58 /* check classes below middle */ 63 /* check classes below middle */
59 prevSize = sac->esacStruct.middle; 64 prevSize = esac->_middle;
60 for (j = sac->middleIndex, i = 1; j > 0; --j, i += 2) { 65 for (j = sac->middleIndex, i = 1; j > 0; --j, i += 2) {
61 CHECKL(prevSize > sac->esacStruct.freelists[i].size); 66 CHECKL(prevSize > esac->_freelists[i]._size);
62 b = sacFreeListBlockCheck(&(sac->esacStruct.freelists[i])); 67 b = sacFreeListBlockCheck(&(esac->_freelists[i]));
63 if (!b) return b; 68 if (!b) return b;
64 prevSize = sac->esacStruct.freelists[i].size; 69 prevSize = esac->_freelists[i]._size;
65 } 70 }
66 /* check smallest class */ 71 /* check smallest class */
67 CHECKL(sac->esacStruct.freelists[i].size == 0); 72 CHECKL(esac->_freelists[i]._size == 0);
68 b = sacFreeListBlockCheck(&(sac->esacStruct.freelists[i])); 73 b = sacFreeListBlockCheck(&(esac->_freelists[i]));
69 return b; 74 return b;
70} 75}
71 76
@@ -81,7 +86,7 @@ static Size sacSize(Index middleIndex, Count classesCount)
81 indexMax = 2 * (classesCount - middleIndex - 1); 86 indexMax = 2 * (classesCount - middleIndex - 1);
82 else 87 else
83 indexMax = 1 + 2 * middleIndex; 88 indexMax = 1 + 2 * middleIndex;
84 return PointerOffset(&dummy, &dummy.esacStruct.freelists[indexMax+1]); 89 return PointerOffset(&dummy, &dummy.esac_s._freelists[indexMax+1]);
85} 90}
86 91
87 92
@@ -97,6 +102,7 @@ Res SACCreate(SAC *sacReturn, Pool pool, Count classesCount,
97 Index middleIndex; /* index of the size in the middle */ 102 Index middleIndex; /* index of the size in the middle */
98 Size prevSize; 103 Size prevSize;
99 unsigned totalFreq = 0; 104 unsigned totalFreq = 0;
105 mps_sac_t esac;
100 106
101 AVER(sacReturn != NULL); 107 AVER(sacReturn != NULL);
102 AVERT(Pool, pool); 108 AVERT(Pool, pool);
@@ -107,10 +113,10 @@ Res SACCreate(SAC *sacReturn, Pool pool, Count classesCount,
107 /* to be large enough, but that gets complicated, if you have to */ 113 /* to be large enough, but that gets complicated, if you have to */
108 /* merge classes because of the adjustment. */ 114 /* merge classes because of the adjustment. */
109 for (i = 0; i < classesCount; ++i) { 115 for (i = 0; i < classesCount; ++i) {
110 AVER(classes[i].blockSize > 0); 116 AVER(classes[i]._block_size > 0);
111 AVER(SizeIsAligned(classes[i].blockSize, PoolAlignment(pool))); 117 AVER(SizeIsAligned(classes[i]._block_size, PoolAlignment(pool)));
112 AVER(prevSize < classes[i].blockSize); 118 AVER(prevSize < classes[i]._block_size);
113 prevSize = classes[i].blockSize; 119 prevSize = classes[i]._block_size;
114 /* no restrictions on count */ 120 /* no restrictions on count */
115 /* no restrictions on frequency */ 121 /* no restrictions on frequency */
116 } 122 }
@@ -118,7 +124,7 @@ Res SACCreate(SAC *sacReturn, Pool pool, Count classesCount,
118 /* Calculate frequency scale */ 124 /* Calculate frequency scale */
119 for (i = 0; i < classesCount; ++i) { 125 for (i = 0; i < classesCount; ++i) {
120 unsigned oldFreq = totalFreq; 126 unsigned oldFreq = totalFreq;
121 totalFreq += classes[i].frequency; 127 totalFreq += classes[i]._frequency;
122 AVER(oldFreq <= totalFreq); /* check for overflow */ 128 AVER(oldFreq <= totalFreq); /* check for overflow */
123 UNUSED(oldFreq); /* <code/mpm.c#check.unused> */ 129 UNUSED(oldFreq); /* <code/mpm.c#check.unused> */
124 } 130 }
@@ -126,10 +132,10 @@ Res SACCreate(SAC *sacReturn, Pool pool, Count classesCount,
126 /* Find middle one */ 132 /* Find middle one */
127 totalFreq /= 2; 133 totalFreq /= 2;
128 for (i = 0; i < classesCount; ++i) { 134 for (i = 0; i < classesCount; ++i) {
129 if (totalFreq < classes[i].frequency) break; 135 if (totalFreq < classes[i]._frequency) break;
130 totalFreq -= classes[i].frequency; 136 totalFreq -= classes[i]._frequency;
131 } 137 }
132 if (totalFreq <= classes[i].frequency / 2) 138 if (totalFreq <= classes[i]._frequency / 2)
133 middleIndex = i; 139 middleIndex = i;
134 else 140 else
135 middleIndex = i + 1; /* there must exist another class at i+1 */ 141 middleIndex = i + 1; /* there must exist another class at i+1 */
@@ -143,30 +149,31 @@ Res SACCreate(SAC *sacReturn, Pool pool, Count classesCount,
143 149
144 /* Move classes in place */ 150 /* Move classes in place */
145 /* It's important this matches SACFind. */ 151 /* It's important this matches SACFind. */
152 esac = ExternalSACOfSAC(sac);
146 for (j = middleIndex + 1, i = 0; j < classesCount; ++j, i += 2) { 153 for (j = middleIndex + 1, i = 0; j < classesCount; ++j, i += 2) {
147 sac->esacStruct.freelists[i].size = classes[j].blockSize; 154 esac->_freelists[i]._size = classes[j]._block_size;
148 sac->esacStruct.freelists[i].count = 0; 155 esac->_freelists[i]._count = 0;
149 sac->esacStruct.freelists[i].countMax = classes[j].cachedCount; 156 esac->_freelists[i]._count_max = classes[j]._cached_count;
150 sac->esacStruct.freelists[i].blocks = NULL; 157 esac->_freelists[i]._blocks = NULL;
151 } 158 }
152 sac->esacStruct.freelists[i].size = SizeMAX; 159 esac->_freelists[i]._size = SizeMAX;
153 sac->esacStruct.freelists[i].count = 0; 160 esac->_freelists[i]._count = 0;
154 sac->esacStruct.freelists[i].countMax = 0; 161 esac->_freelists[i]._count_max = 0;
155 sac->esacStruct.freelists[i].blocks = NULL; 162 esac->_freelists[i]._blocks = NULL;
156 for (j = middleIndex, i = 1; j > 0; --j, i += 2) { 163 for (j = middleIndex, i = 1; j > 0; --j, i += 2) {
157 sac->esacStruct.freelists[i].size = classes[j-1].blockSize; 164 esac->_freelists[i]._size = classes[j-1]._block_size;
158 sac->esacStruct.freelists[i].count = 0; 165 esac->_freelists[i]._count = 0;
159 sac->esacStruct.freelists[i].countMax = classes[j].cachedCount; 166 esac->_freelists[i]._count_max = classes[j]._cached_count;
160 sac->esacStruct.freelists[i].blocks = NULL; 167 esac->_freelists[i]._blocks = NULL;
161 } 168 }
162 sac->esacStruct.freelists[i].size = 0; 169 esac->_freelists[i]._size = 0;
163 sac->esacStruct.freelists[i].count = 0; 170 esac->_freelists[i]._count = 0;
164 sac->esacStruct.freelists[i].countMax = classes[j].cachedCount; 171 esac->_freelists[i]._count_max = classes[j]._cached_count;
165 sac->esacStruct.freelists[i].blocks = NULL; 172 esac->_freelists[i]._blocks = NULL;
166 173
167 /* finish init */ 174 /* finish init */
168 sac->esacStruct.trapped = FALSE; 175 esac->_trapped = FALSE;
169 sac->esacStruct.middle = classes[middleIndex].blockSize; 176 esac->_middle = classes[middleIndex]._block_size;
170 sac->pool = pool; 177 sac->pool = pool;
171 sac->classesCount = classesCount; 178 sac->classesCount = classesCount;
172 sac->middleIndex = middleIndex; 179 sac->middleIndex = middleIndex;
@@ -202,22 +209,24 @@ static void sacFind(Index *iReturn, Size *blockSizeReturn,
202 SAC sac, Size size) 209 SAC sac, Size size)
203{ 210{
204 Index i, j; 211 Index i, j;
212 mps_sac_t esac;
205 213
206 if (size > sac->esacStruct.middle) { 214 esac = ExternalSACOfSAC(sac);
215 if (size > esac->_middle) {
207 i = 0; j = sac->middleIndex + 1; 216 i = 0; j = sac->middleIndex + 1;
208 AVER(j <= sac->classesCount); 217 AVER(j <= sac->classesCount);
209 while (size > sac->esacStruct.freelists[i].size) { 218 while (size > esac->_freelists[i]._size) {
210 AVER(j < sac->classesCount); 219 AVER(j < sac->classesCount);
211 i += 2; ++j; 220 i += 2; ++j;
212 } 221 }
213 *blockSizeReturn = sac->esacStruct.freelists[i].size; 222 *blockSizeReturn = esac->_freelists[i]._size;
214 } else { 223 } else {
215 Size prevSize = sac->esacStruct.middle; 224 Size prevSize = esac->_middle;
216 225
217 i = 1; j = sac->middleIndex; 226 i = 1; j = sac->middleIndex;
218 while (size <= sac->esacStruct.freelists[i].size) { 227 while (size <= esac->_freelists[i]._size) {
219 AVER(j > 0); 228 AVER(j > 0);
220 prevSize = sac->esacStruct.freelists[i].size; 229 prevSize = esac->_freelists[i]._size;
221 i += 2; --j; 230 i += 2; --j;
222 } 231 }
223 *blockSizeReturn = prevSize; 232 *blockSizeReturn = prevSize;
@@ -235,23 +244,25 @@ Res SACFill(Addr *p_o, SAC sac, Size size, Bool hasReservoirPermit)
235 Size blockSize; 244 Size blockSize;
236 Addr p, fl; 245 Addr p, fl;
237 Res res = ResOK; /* stop compiler complaining */ 246 Res res = ResOK; /* stop compiler complaining */
247 mps_sac_t esac;
238 248
239 AVER(p_o != NULL); 249 AVER(p_o != NULL);
240 AVERT(SAC, sac); 250 AVERT(SAC, sac);
241 AVER(size != 0); 251 AVER(size != 0);
242 AVER(BoolCheck(hasReservoirPermit)); 252 AVER(BoolCheck(hasReservoirPermit));
253 esac = ExternalSACOfSAC(sac);
243 254
244 sacFind(&i, &blockSize, sac, size); 255 sacFind(&i, &blockSize, sac, size);
245 /* Check it's empty (in the future, there will be other cases). */ 256 /* Check it's empty (in the future, there will be other cases). */
246 AVER(sac->esacStruct.freelists[i].count == 0); 257 AVER(esac->_freelists[i]._count == 0);
247 258
248 /* Fill 1/3 of the cache for this class. */ 259 /* Fill 1/3 of the cache for this class. */
249 blockCount = sac->esacStruct.freelists[i].countMax / 3; 260 blockCount = esac->_freelists[i]._count_max / 3;
250 /* Adjust size for the overlarge class. */ 261 /* Adjust size for the overlarge class. */
251 if (blockSize == SizeMAX) 262 if (blockSize == SizeMAX)
252 /* .align: align 'cause some classes don't accept unaligned. */ 263 /* .align: align 'cause some classes don't accept unaligned. */
253 blockSize = SizeAlignUp(size, PoolAlignment(sac->pool)); 264 blockSize = SizeAlignUp(size, PoolAlignment(sac->pool));
254 for (j = 0, fl = sac->esacStruct.freelists[i].blocks; 265 for (j = 0, fl = esac->_freelists[i]._blocks;
255 j <= blockCount; ++j) { 266 j <= blockCount; ++j) {
256 res = PoolAlloc(&p, sac->pool, blockSize, hasReservoirPermit); 267 res = PoolAlloc(&p, sac->pool, blockSize, hasReservoirPermit);
257 if (res != ResOK) 268 if (res != ResOK)
@@ -266,10 +277,10 @@ Res SACFill(Addr *p_o, SAC sac, Size size, Bool hasReservoirPermit)
266 } 277 }
267 278
268 /* Take the last one off, and return it. */ 279 /* Take the last one off, and return it. */
269 sac->esacStruct.freelists[i].count = j - 1; 280 esac->_freelists[i]._count = j - 1;
270 *p_o = fl; 281 *p_o = fl;
271 /* @@@@ ignoring shields for now */ 282 /* @@@@ ignoring shields for now */
272 sac->esacStruct.freelists[i].blocks = *ADDR_PTR(Addr, fl); 283 esac->_freelists[i]._blocks = *ADDR_PTR(Addr, fl);
273 return ResOK; 284 return ResOK;
274} 285}
275 286
@@ -284,15 +295,17 @@ static void sacClassFlush(SAC sac, Index i, Size blockSize,
284{ 295{
285 Addr cb, fl; 296 Addr cb, fl;
286 Count j; 297 Count j;
287 298 mps_sac_t esac;
288 for (j = 0, fl = sac->esacStruct.freelists[i].blocks; 299
300 esac = ExternalSACOfSAC(sac);
301 for (j = 0, fl = esac->_freelists[i]._blocks;
289 j < blockCount; ++j) { 302 j < blockCount; ++j) {
290 /* @@@@ ignoring shields for now */ 303 /* @@@@ ignoring shields for now */
291 cb = fl; fl = *ADDR_PTR(Addr, cb); 304 cb = fl; fl = *ADDR_PTR(Addr, cb);
292 PoolFree(sac->pool, cb, blockSize); 305 PoolFree(sac->pool, cb, blockSize);
293 } 306 }
294 sac->esacStruct.freelists[i].count -= blockCount; 307 esac->_freelists[i]._count -= blockCount;
295 sac->esacStruct.freelists[i].blocks = fl; 308 esac->_freelists[i]._blocks = fl;
296} 309}
297 310
298 311
@@ -302,34 +315,36 @@ void SACEmpty(SAC sac, Addr p, Size size)
302{ 315{
303 Index i; 316 Index i;
304 Size blockSize; 317 Size blockSize;
305 318 mps_sac_t esac;
319
306 AVERT(SAC, sac); 320 AVERT(SAC, sac);
307 AVER(p != NULL); 321 AVER(p != NULL);
308 AVER(PoolHasAddr(sac->pool, p)); 322 AVER(PoolHasAddr(sac->pool, p));
309 AVER(size > 0); 323 AVER(size > 0);
324 esac = ExternalSACOfSAC(sac);
310 325
311 sacFind(&i, &blockSize, sac, size); 326 sacFind(&i, &blockSize, sac, size);
312 /* Check it's full (in the future, there will be other cases). */ 327 /* Check it's full (in the future, there will be other cases). */
313 AVER(sac->esacStruct.freelists[i].count 328 AVER(esac->_freelists[i]._count
314 == sac->esacStruct.freelists[i].countMax); 329 == esac->_freelists[i]._count_max);
315 330
316 /* Adjust size for the overlarge class. */ 331 /* Adjust size for the overlarge class. */
317 if (blockSize == SizeMAX) 332 if (blockSize == SizeMAX)
318 /* see .align */ 333 /* see .align */
319 blockSize = SizeAlignUp(size, PoolAlignment(sac->pool)); 334 blockSize = SizeAlignUp(size, PoolAlignment(sac->pool));
320 if (sac->esacStruct.freelists[i].countMax > 0) { 335 if (esac->_freelists[i]._count_max > 0) {
321 Count blockCount; 336 Count blockCount;
322 337
323 /* Flush 2/3 of the cache for this class. */ 338 /* Flush 2/3 of the cache for this class. */
324 /* Computed as count - count/3, so that the rounding works out right. */ 339 /* Computed as count - count/3, so that the rounding works out right. */
325 blockCount = sac->esacStruct.freelists[i].count; 340 blockCount = esac->_freelists[i]._count;
326 blockCount -= sac->esacStruct.freelists[i].count / 3; 341 blockCount -= esac->_freelists[i]._count / 3;
327 sacClassFlush(sac, i, blockSize, (blockCount > 0) ? blockCount : 1); 342 sacClassFlush(sac, i, blockSize, (blockCount > 0) ? blockCount : 1);
328 /* Leave the current one in the cache. */ 343 /* Leave the current one in the cache. */
329 sac->esacStruct.freelists[i].count += 1; 344 esac->_freelists[i]._count += 1;
330 /* @@@@ ignoring shields for now */ 345 /* @@@@ ignoring shields for now */
331 *ADDR_PTR(Addr, p) = sac->esacStruct.freelists[i].blocks; 346 *ADDR_PTR(Addr, p) = esac->_freelists[i]._blocks;
332 sac->esacStruct.freelists[i].blocks = p; 347 esac->_freelists[i]._blocks = p;
333 } else { 348 } else {
334 /* Free even the current one. */ 349 /* Free even the current one. */
335 PoolFree(sac->pool, p, blockSize); 350 PoolFree(sac->pool, p, blockSize);
@@ -343,25 +358,27 @@ void SACFlush(SAC sac)
343{ 358{
344 Index i, j; 359 Index i, j;
345 Size prevSize; 360 Size prevSize;
361 mps_sac_t esac;
346 362
347 AVERT(SAC, sac); 363 AVERT(SAC, sac);
348 364
365 esac = ExternalSACOfSAC(sac);
349 for (j = sac->middleIndex + 1, i = 0; 366 for (j = sac->middleIndex + 1, i = 0;
350 j < sac->classesCount; ++j, i += 2) { 367 j < sac->classesCount; ++j, i += 2) {
351 sacClassFlush(sac, i, sac->esacStruct.freelists[i].size, 368 sacClassFlush(sac, i, esac->_freelists[i]._size,
352 sac->esacStruct.freelists[i].count); 369 esac->_freelists[i]._count);
353 AVER(sac->esacStruct.freelists[i].blocks == NULL); 370 AVER(esac->_freelists[i]._blocks == NULL);
354 } 371 }
355 /* no need to flush overlarge, there's nothing there */ 372 /* no need to flush overlarge, there's nothing there */
356 prevSize = sac->esacStruct.middle; 373 prevSize = esac->_middle;
357 for (j = sac->middleIndex, i = 1; j > 0; --j, i += 2) { 374 for (j = sac->middleIndex, i = 1; j > 0; --j, i += 2) {
358 sacClassFlush(sac, i, prevSize, sac->esacStruct.freelists[i].count); 375 sacClassFlush(sac, i, prevSize, esac->_freelists[i]._count);
359 AVER(sac->esacStruct.freelists[i].blocks == NULL); 376 AVER(esac->_freelists[i]._blocks == NULL);
360 prevSize = sac->esacStruct.freelists[i].size; 377 prevSize = esac->_freelists[i]._size;
361 } 378 }
362 /* flush smallest class */ 379 /* flush smallest class */
363 sacClassFlush(sac, i, prevSize, sac->esacStruct.freelists[i].count); 380 sacClassFlush(sac, i, prevSize, esac->_freelists[i]._count);
364 AVER(sac->esacStruct.freelists[i].blocks == NULL); 381 AVER(esac->_freelists[i]._blocks == NULL);
365} 382}
366 383
367 384
diff --git a/mps/code/sac.h b/mps/code/sac.h
index f570a38e767..78e676125d1 100644
--- a/mps/code/sac.h
+++ b/mps/code/sac.h
@@ -14,28 +14,6 @@
14#define sacClassLIMIT ((Count)8) 14#define sacClassLIMIT ((Count)8)
15 15
16 16
17/* ExternalSAC -- the external face of segregated allocation caches */
18/* .sac: This structure must match <code/mps.h#sac>. */
19
20typedef struct ExternalSACStruct *ExternalSAC;
21
22typedef struct SACFreeListBlockStruct {
23 Size size;
24 Count count;
25 Count countMax;
26 Addr blocks;
27} SACFreeListBlockStruct;
28
29typedef SACFreeListBlockStruct *SACFreeListBlock;
30
31typedef struct ExternalSACStruct {
32 size_t middle; /* block size for starting searches */
33 Bool trapped; /* trap status */
34 /* freelist, variable length */
35 SACFreeListBlockStruct freelists[2 * sacClassLIMIT];
36} ExternalSACStruct;
37
38
39/* SAC -- the real segregated allocation caches */ 17/* SAC -- the real segregated allocation caches */
40 18
41#define SACSig ((Sig)0x5195AC99) /* SIGnature SAC */ 19#define SACSig ((Sig)0x5195AC99) /* SIGnature SAC */
@@ -47,12 +25,12 @@ typedef struct SACStruct {
47 Pool pool; 25 Pool pool;
48 Count classesCount; /* number of classes */ 26 Count classesCount; /* number of classes */
49 Index middleIndex; /* index of the middle */ 27 Index middleIndex; /* index of the middle */
50 ExternalSACStruct esacStruct; /* variable length, must be last */ 28 mps_sac_s esac_s; /* variable length, must be last */
51} SACStruct; 29} SACStruct;
52 30
53#define SACOfExternalSAC(esac) PARENT(SACStruct, esacStruct, esac) 31#define SACOfExternalSAC(esac) PARENT(SACStruct, esac_s, esac)
54 32
55#define ExternalSACOfSAC(sac) (&((sac)->esacStruct)) 33#define ExternalSACOfSAC(sac) (&((sac)->esac_s))
56 34
57#define SACArena(sac) PoolArena((sac)->pool) 35#define SACArena(sac) PoolArena((sac)->pool)
58 36
@@ -60,13 +38,7 @@ typedef struct SACStruct {
60/* SACClasses -- structure for specifying classes in the cache */ 38/* SACClasses -- structure for specifying classes in the cache */
61/* .sacc: This structure must match <code/mps.h#sacc>. */ 39/* .sacc: This structure must match <code/mps.h#sacc>. */
62 40
63typedef struct SACClassesStruct *SACClasses; 41typedef struct mps_sac_classes_s *SACClasses;
64
65typedef struct SACClassesStruct {
66 Size blockSize;
67 Count cachedCount;
68 unsigned frequency;
69} SACClassesStruct;
70 42
71 43
72extern Res SACCreate(SAC *sac_o, Pool pool, Count classesCount, 44extern Res SACCreate(SAC *sac_o, Pool pool, Count classesCount,