aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code
diff options
context:
space:
mode:
authorNick Barnes2002-02-07 22:48:09 +0000
committerNick Barnes2002-02-07 22:48:09 +0000
commit5da4c1e316636ee7218ca97bac693a06784808b7 (patch)
tree7b498c60aae2de7f29de6a142a57dbceb85055c5 /mps/code
parente29b111ad56eaf25696a839e6f9293b70a86a653 (diff)
downloademacs-5da4c1e316636ee7218ca97bac693a06784808b7.tar.gz
emacs-5da4c1e316636ee7218ca97bac693a06784808b7.zip
Poolawl now takes an additional argument: the find_dependent_object method.
Copied from Perforce Change: 26536 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
-rw-r--r--mps/code/awlut.c5
-rw-r--r--mps/code/awlutth.c3
-rw-r--r--mps/code/fmtdy.c28
-rw-r--r--mps/code/fmtdy.h1
-rw-r--r--mps/code/poolawl.c74
5 files changed, 56 insertions, 55 deletions
diff --git a/mps/code/awlut.c b/mps/code/awlut.c
index 1ae9f11f49c..d2d5ebe7db5 100644
--- a/mps/code/awlut.c
+++ b/mps/code/awlut.c
@@ -268,7 +268,8 @@ static void *setup(void *v, size_t s)
268 "Format Create (weak)\n"); 268 "Format Create (weak)\n");
269 die(mps_pool_create(&leafpool, arena, mps_class_lo(), dylanfmt), 269 die(mps_pool_create(&leafpool, arena, mps_class_lo(), dylanfmt),
270 "Leaf Pool Create\n"); 270 "Leaf Pool Create\n");
271 die(mps_pool_create(&tablepool, arena, mps_class_awl(), dylanweakfmt), 271 die(mps_pool_create(&tablepool, arena, mps_class_awl(), dylanweakfmt,
272 dylan_weak_dependent),
272 "Table Pool Create\n"); 273 "Table Pool Create\n");
273 die(mps_ap_create(&leafap, leafpool, MPS_RANK_EXACT), 274 die(mps_ap_create(&leafap, leafpool, MPS_RANK_EXACT),
274 "Leaf AP Create\n"); 275 "Leaf AP Create\n");
@@ -278,7 +279,7 @@ static void *setup(void *v, size_t s)
278 "Weak AP Create\n"); 279 "Weak AP Create\n");
279 die(mps_ap_create(&bogusap, tablepool, MPS_RANK_EXACT), 280 die(mps_ap_create(&bogusap, tablepool, MPS_RANK_EXACT),
280 "Bogus AP Create\n"); 281 "Bogus AP Create\n");
281 282
282 test(leafap, exactap, weakap, bogusap); 283 test(leafap, exactap, weakap, bogusap);
283 284
284 mps_ap_destroy(bogusap); 285 mps_ap_destroy(bogusap);
diff --git a/mps/code/awlutth.c b/mps/code/awlutth.c
index bcb4ddd0c4e..9d7f2e41855 100644
--- a/mps/code/awlutth.c
+++ b/mps/code/awlutth.c
@@ -264,7 +264,8 @@ static void *setup(void *v, size_t s)
264 "Format Create (weak)\n"); 264 "Format Create (weak)\n");
265 die(mps_pool_create(&leafpool, arena, mps_class_lo(), dylanfmt), 265 die(mps_pool_create(&leafpool, arena, mps_class_lo(), dylanfmt),
266 "Leaf Pool Create\n"); 266 "Leaf Pool Create\n");
267 die(mps_pool_create(&tablepool, arena, mps_class_awl(), dylanweakfmt), 267 die(mps_pool_create(&tablepool, arena, mps_class_awl(), dylanweakfmt,
268 dylan_weak_dependent),
268 "Table Pool Create\n"); 269 "Table Pool Create\n");
269 die(mps_ap_create(&leafap, leafpool, MPS_RANK_EXACT), 270 die(mps_ap_create(&leafap, leafpool, MPS_RANK_EXACT),
270 "Leaf AP Create\n"); 271 "Leaf AP Create\n");
diff --git a/mps/code/fmtdy.c b/mps/code/fmtdy.c
index dae0dc64e70..84db8101257 100644
--- a/mps/code/fmtdy.c
+++ b/mps/code/fmtdy.c
@@ -182,7 +182,7 @@ int dylan_wrapper_check(mps_word_t *w)
182 /* size. This assumes that DylanWorks is only going to use byte */ 182 /* size. This assumes that DylanWorks is only going to use byte */
183 /* vectors in the non-word case. */ 183 /* vectors in the non-word case. */
184 184
185 /* Variable part format 6 is reserved. */ 185 /* Variable part format 6 is reserved. */
186 assert(vf != 6); 186 assert(vf != 6);
187 187
188 /* There should be no shift in word vector formats. */ 188 /* There should be no shift in word vector formats. */
@@ -241,6 +241,32 @@ static mps_res_t dylan_scan_contig(mps_ss_t mps_ss,
241 return MPS_RES_OK; 241 return MPS_RES_OK;
242} 242}
243 243
244/* dylan_weak_dependent -- returns the linked object, if any.
245 */
246
247extern mps_addr_t dylan_weak_dependent(mps_addr_t parent)
248{
249 mps_word_t *object;
250 mps_word_t *wrapper;
251 mps_word_t fword;
252 mps_word_t fl;
253 mps_word_t ff;
254
255 assert(parent != NULL);
256 object = (mps_word_t *)parent;
257 wrapper = (mps_word_t *)object[0];
258 assert(dylan_wrapper_check(wrapper));
259 fword = wrapper[3];
260 ff = fword & 3;
261 /* traceable fixed part */
262 assert(ff == 1);
263 fl = fword & ~3uL;
264 /* at least one fixed field */
265 assert(fl >= 1);
266 return (mps_addr_t) object[1];
267}
268
269
244/* Scan weakly a contiguous array of references in [base, limit). */ 270/* Scan weakly a contiguous array of references in [base, limit). */
245/* Only required to scan vectors for Dylan Weak Tables. */ 271/* Only required to scan vectors for Dylan Weak Tables. */
246/* Depends on the vector length field being scannable (ie a tagged */ 272/* Depends on the vector length field being scannable (ie a tagged */
diff --git a/mps/code/fmtdy.h b/mps/code/fmtdy.h
index 39ca3130208..e174121c06f 100644
--- a/mps/code/fmtdy.h
+++ b/mps/code/fmtdy.h
@@ -17,6 +17,7 @@ extern mps_fmt_B_s *dylan_fmt_B_weak(void);
17extern mps_res_t dylan_fmt(mps_fmt_t *, mps_arena_t); 17extern mps_res_t dylan_fmt(mps_fmt_t *, mps_arena_t);
18extern mps_res_t dylan_fmt_weak(mps_fmt_t *, mps_arena_t); 18extern mps_res_t dylan_fmt_weak(mps_fmt_t *, mps_arena_t);
19 19
20extern mps_addr_t dylan_weak_dependent(mps_addr_t);
20 21
21/* Used only for debugging / testing */ 22/* Used only for debugging / testing */
22extern mps_res_t dylan_init(mps_addr_t addr, size_t size, 23extern mps_res_t dylan_init(mps_addr_t addr, size_t size,
diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c
index 482581d37b8..ca7954c5791 100644
--- a/mps/code/poolawl.c
+++ b/mps/code/poolawl.c
@@ -76,6 +76,9 @@ typedef struct awlStatTotalStruct {
76 Count declined; /* number of declined single accesses */ 76 Count declined; /* number of declined single accesses */
77} awlStatTotalStruct, *awlStatTotal; 77} awlStatTotalStruct, *awlStatTotal;
78 78
79/* the type of a function to find an object's dependent object */
80
81typedef Addr (*FindDependentMethod)(Addr object);
79 82
80/* AWLStruct -- AWL pool structure 83/* AWLStruct -- AWL pool structure
81 * 84 *
@@ -90,6 +93,7 @@ typedef struct AWLStruct {
90 Size size; /* allocated size in bytes */ 93 Size size; /* allocated size in bytes */
91 Serial gen; /* associated generation (for SegAlloc) */ 94 Serial gen; /* associated generation (for SegAlloc) */
92 Count succAccesses; /* number of successive single accesses */ 95 Count succAccesses; /* number of successive single accesses */
96 FindDependentMethod findDependent; /* to find a dependent object */
93 awlStatTotalStruct stats; 97 awlStatTotalStruct stats;
94 Sig sig; 98 Sig sig;
95} AWLStruct, *AWL; 99} AWLStruct, *AWL;
@@ -271,7 +275,7 @@ static void AWLSegFinish(Seg seg)
271 super = SEG_SUPERCLASS(AWLSegClass); 275 super = SEG_SUPERCLASS(AWLSegClass);
272 super->finish(seg); 276 super->finish(seg);
273} 277}
274 278
275 279
276/* AWLSegClass -- Class definition for AWL segments */ 280/* AWLSegClass -- Class definition for AWL segments */
277 281
@@ -310,7 +314,7 @@ static Bool AWLCanTrySingleAccess(AWL awl, Seg seg, Addr addr)
310 314
311 awlseg = Seg2AWLSeg(seg); 315 awlseg = Seg2AWLSeg(seg);
312 AVERT(AWLSeg, awlseg); 316 AVERT(AWLSeg, awlseg);
313 317
314 if (AWLHaveTotalSALimit) { 318 if (AWLHaveTotalSALimit) {
315 if (AWLTotalSALimit < awl->succAccesses) { 319 if (AWLTotalSALimit < awl->succAccesses) {
316 STATISTIC(awl->stats.declined++); 320 STATISTIC(awl->stats.declined++);
@@ -483,6 +487,7 @@ static Res AWLInit(Pool pool, va_list arg)
483{ 487{
484 AWL awl; 488 AWL awl;
485 Format format; 489 Format format;
490 FindDependentMethod findDependent;
486 Chain chain; 491 Chain chain;
487 Res res; 492 Res res;
488 static GenParamStruct genParam = { SizeMAX, 0.5 /* dummy */ }; 493 static GenParamStruct genParam = { SizeMAX, 0.5 /* dummy */ };
@@ -496,6 +501,10 @@ static Res AWLInit(Pool pool, va_list arg)
496 AVERT(Format, format); 501 AVERT(Format, format);
497 pool->format = format; 502 pool->format = format;
498 503
504 findDependent = va_arg(arg, FindDependentMethod);
505 AVER(FUNCHECK(findDependent));
506 awl->findDependent = findDependent;
507
499 res = ChainCreate(&chain, pool->arena, 1, &genParam); 508 res = ChainCreate(&chain, pool->arena, 1, &genParam);
500 if (res != ResOK) 509 if (res != ResOK)
501 return res; 510 return res;
@@ -777,52 +786,14 @@ static void AWLBlacken(Pool pool, TraceSet traceSet, Seg seg)
777 AVERT(AWL, awl); 786 AVERT(AWL, awl);
778 awlseg = Seg2AWLSeg(seg); 787 awlseg = Seg2AWLSeg(seg);
779 AVERT(AWLSeg, awlseg); 788 AVERT(AWLSeg, awlseg);
780
781 BTSetRange(awlseg->scanned, 0, awlseg->grains);
782}
783
784 789
785/* AWLDependentObject -- returns the linked object, if any 790 BTSetRange(awlseg->scanned, 0, awlseg->grains);
786 *
787 * see design.mps.poolawl.fun.dependent-object, and
788 * analysis.mps.poolawl.improve.dependent.abstract
789 */
790
791static Bool AWLDependentObject(Addr *objReturn, Addr parent)
792{
793 Word *object;
794 Word *wrapper;
795 Word fword;
796 Word fl;
797 Word ff;
798
799 AVER(objReturn != NULL);
800 AVER(parent != (Addr)0);
801
802 object = (Word *)parent;
803 wrapper = (Word *)object[0];
804 AVER(wrapper != NULL);
805 /* check wrapper wrapper is non-NULL */
806 AVER(wrapper[0] != 0);
807 /* check wrapper wrapper is wrapper wrapper wrapper */
808 AVER(wrapper[0] == ((Word *)wrapper[0])[0]);
809 fword = wrapper[3];
810 ff = fword & 3;
811 /* Traceable Fixed part */
812 AVER(ff == 1);
813 fl = fword & ~3uL;
814 /* At least one fixed field */
815 AVER(fl >= 1);
816 if (object[1] == 0)
817 return FALSE;
818 *objReturn = (Addr)object[1];
819 return TRUE;
820} 791}
821 792
822 793
823/* awlScanObject -- scan a single object */ 794/* awlScanObject -- scan a single object */
824 795
825static Res awlScanObject(Arena arena, ScanState ss, 796static Res awlScanObject(Arena arena, AWL awl, ScanState ss,
826 FormatScanMethod scan, Addr base, Addr limit) 797 FormatScanMethod scan, Addr base, Addr limit)
827{ 798{
828 Res res; 799 Res res;
@@ -831,19 +802,19 @@ static Res awlScanObject(Arena arena, ScanState ss,
831 Seg dependentSeg = NULL; /* segment of dependent object */ 802 Seg dependentSeg = NULL; /* segment of dependent object */
832 803
833 AVERT(Arena, arena); 804 AVERT(Arena, arena);
805 AVERT(AWL, awl);
834 AVERT(ScanState, ss); 806 AVERT(ScanState, ss);
835 AVER(FUNCHECK(scan)); 807 AVER(FUNCHECK(scan));
836 AVER(base != 0); 808 AVER(base != 0);
837 AVER(base < limit); 809 AVER(base < limit);
838 810
839 dependent = AWLDependentObject(&dependentObject, base) 811 dependentObject = awl->findDependent(base);
840 && SegOfAddr(&dependentSeg, arena, dependentObject); 812 dependent = SegOfAddr(&dependentSeg, arena, dependentObject);
841
842 if (dependent) { 813 if (dependent) {
843 /* design.mps.poolawl.fun.scan.pass.object.dependent.expose */ 814 /* design.mps.poolawl.fun.scan.pass.object.dependent.expose */
844 ShieldExpose(arena, dependentSeg); 815 ShieldExpose(arena, dependentSeg);
845 /* design.mps.poolawl.fun.scan.pass.object.dependent.summary */ 816 /* design.mps.poolawl.fun.scan.pass.object.dependent.summary */
846 SegSetSummary(dependentSeg, RefSetUNIV); 817 SegSetSummary(dependentSeg, RefSetUNIV);
847 } 818 }
848 819
849 res = (*scan)(ss, base, limit); 820 res = (*scan)(ss, base, limit);
@@ -911,7 +882,7 @@ static Res awlScanSinglePass(Bool *anyScannedReturn,
911 /* design.mps.poolawl.fun.scan.pass.object */ 882 /* design.mps.poolawl.fun.scan.pass.object */
912 if (scanAllObjects 883 if (scanAllObjects
913 || (BTGet(awlseg->mark, i) && !BTGet(awlseg->scanned, i))) { 884 || (BTGet(awlseg->mark, i) && !BTGet(awlseg->scanned, i))) {
914 Res res = awlScanObject(arena, ss, pool->format->scan, 885 Res res = awlScanObject(arena, awl, ss, pool->format->scan,
915 p, objectLimit); 886 p, objectLimit);
916 if (res != ResOK) 887 if (res != ResOK)
917 return res; 888 return res;
@@ -1001,7 +972,7 @@ static Res AWLFix(Pool pool, ScanState ss, Seg seg, Ref *refIO)
1001 972
1002 ref = *refIO; 973 ref = *refIO;
1003 i = awlIndexOfAddr(SegBase(seg), awl, ref); 974 i = awlIndexOfAddr(SegBase(seg), awl, ref);
1004 975
1005 ss->wasMarked = TRUE; 976 ss->wasMarked = TRUE;
1006 977
1007 switch(ss->rank) { 978 switch(ss->rank) {
@@ -1243,6 +1214,7 @@ static Bool AWLCheck(AWL awl)
1243 /* 30 is just a sanity check really, not a constraint. */ 1214 /* 30 is just a sanity check really, not a constraint. */
1244 CHECKL(0 <= awl->gen && awl->gen <= 30); 1215 CHECKL(0 <= awl->gen && awl->gen <= 30);
1245 /* Nothing to check about succAccesses. */ 1216 /* Nothing to check about succAccesses. */
1217 CHECKL(FUNCHECK(awl->findDependent));
1246 /* Don't bother to check stats. */ 1218 /* Don't bother to check stats. */
1247 return TRUE; 1219 return TRUE;
1248} 1220}