diff options
| author | Nick Barnes | 2002-02-07 22:48:09 +0000 |
|---|---|---|
| committer | Nick Barnes | 2002-02-07 22:48:09 +0000 |
| commit | 5da4c1e316636ee7218ca97bac693a06784808b7 (patch) | |
| tree | 7b498c60aae2de7f29de6a142a57dbceb85055c5 /mps/code | |
| parent | e29b111ad56eaf25696a839e6f9293b70a86a653 (diff) | |
| download | emacs-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.c | 5 | ||||
| -rw-r--r-- | mps/code/awlutth.c | 3 | ||||
| -rw-r--r-- | mps/code/fmtdy.c | 28 | ||||
| -rw-r--r-- | mps/code/fmtdy.h | 1 | ||||
| -rw-r--r-- | mps/code/poolawl.c | 74 |
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 | |||
| 247 | extern 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); | |||
| 17 | extern mps_res_t dylan_fmt(mps_fmt_t *, mps_arena_t); | 17 | extern mps_res_t dylan_fmt(mps_fmt_t *, mps_arena_t); |
| 18 | extern mps_res_t dylan_fmt_weak(mps_fmt_t *, mps_arena_t); | 18 | extern mps_res_t dylan_fmt_weak(mps_fmt_t *, mps_arena_t); |
| 19 | 19 | ||
| 20 | extern mps_addr_t dylan_weak_dependent(mps_addr_t); | ||
| 20 | 21 | ||
| 21 | /* Used only for debugging / testing */ | 22 | /* Used only for debugging / testing */ |
| 22 | extern mps_res_t dylan_init(mps_addr_t addr, size_t size, | 23 | extern 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 | |||
| 81 | typedef 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 | |||
| 791 | static 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 | ||
| 825 | static Res awlScanObject(Arena arena, ScanState ss, | 796 | static 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 | } |