-
Notifications
You must be signed in to change notification settings - Fork 84
New API function mps_pool_walk #34
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
78baf72
18898cd
c23173d
ef4d719
1dd501e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,9 +5,9 @@ | |
| * Portions copyright (c) 2002 Global Graphics Software. | ||
| * | ||
| * The main thread parks the arena half way through the test case and | ||
| * runs mps_arena_formatted_objects_walk(). This checks that walking | ||
| * works while the other threads continue to allocate in the | ||
| * background. | ||
| * runs mps_pool_walk() and mps_arena_formatted_objects_walk(). This | ||
| * checks that walking works while the other threads continue to | ||
| * allocate in the background. | ||
| */ | ||
|
|
||
| #include "fmtdy.h" | ||
|
|
@@ -86,6 +86,24 @@ static void test_stepper(mps_addr_t object, mps_fmt_t fmt, mps_pool_t pool, | |
| } | ||
|
|
||
|
|
||
| /* area_scan -- area scanning function for mps_pool_walk */ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. m. Duplicate of code in amcss.c. Move both to fmtdy,c? |
||
|
|
||
| static mps_res_t area_scan(mps_ss_t ss, void *base, void *limit, void *closure) | ||
| { | ||
| unsigned long *count = closure; | ||
| mps_res_t res; | ||
| while (base < limit) { | ||
| mps_addr_t prev = base; | ||
| ++ *count; | ||
| res = dylan_scan1(ss, &base); | ||
| if (res != MPS_RES_OK) return res; | ||
| Insist(prev < base); | ||
| } | ||
| Insist(base == limit); | ||
| return MPS_RES_OK; | ||
| } | ||
|
|
||
|
|
||
| /* churn -- create an object and install into roots */ | ||
|
|
||
| static void churn(mps_ap_t ap, size_t roots_count) | ||
|
|
@@ -209,11 +227,13 @@ static void test_pool(const char *name, mps_pool_t pool, size_t roots_count) | |
|
|
||
| if (collections >= collectionsCOUNT / 2 && !walked) | ||
| { | ||
| unsigned long count = 0; | ||
| unsigned long count1 = 0, count2 = 0; | ||
| mps_arena_park(arena); | ||
| mps_arena_formatted_objects_walk(arena, test_stepper, &count, 0); | ||
| mps_arena_formatted_objects_walk(arena, test_stepper, &count1, 0); | ||
| die(mps_pool_walk(pool, area_scan, &count2), "mps_pool_walk"); | ||
| mps_arena_release(arena); | ||
| printf("stepped on %lu objects.\n", count); | ||
| printf("stepped on %lu objects.\n", count1); | ||
| printf("walked %lu objects.\n", count2); | ||
| walked = TRUE; | ||
| } | ||
| if (collections >= rampSwitch && !ramped) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -402,6 +402,9 @@ typedef struct ScanStateStruct { | |
| Sig sig; /* <design/sig> */ | ||
| struct mps_ss_s ss_s; /* .ss <http://bash.org/?400459> */ | ||
| Arena arena; /* owning arena */ | ||
| mps_fmt_scan_t formatScan; /* callback for scanning formatted objects */ | ||
| mps_area_scan_t areaScan; /* ditto via the area scanning interface */ | ||
| void *areaScanClosure; /* closure argument for areaScan */ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. C. Rather than adding fields to the ScanStateStruct that are only used in Pool Walk, why not extend ScanStateStruct locally, like rootsStepClosureStruct
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. m. In fact, why is Pool Walk different from Roots Walk, when it's basically using the same trick? Why don't they share more code?
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. m. The comment about improvement in Root Walking seems to have been ignored. "there's no direct support for creating a trace without also condemning part of the heap. (@@@@ This looks like a useful candidate for inclusion in the future)" |
||
| SegFixMethod fix; /* third stage fix function */ | ||
| void *fixClosure; /* see .ss.fix-closure */ | ||
| TraceSet traces; /* traces to scan for */ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -71,6 +71,7 @@ static Bool loSegBufferFill(Addr *baseReturn, Addr *limitReturn, | |
| Seg seg, Size size, RankSet rankSet); | ||
| static void loSegBufferEmpty(Seg seg, Buffer buffer); | ||
| static Res loSegWhiten(Seg seg, Trace trace); | ||
| static Res loSegScan(Bool *totalReturn, Seg seg, ScanState ss); | ||
| static Res loSegFix(Seg seg, ScanState ss, Ref *refIO); | ||
| static void loSegReclaim(Seg seg, Trace trace); | ||
| static void loSegWalk(Seg seg, Format format, FormattedObjectsVisitor f, | ||
|
|
@@ -89,6 +90,7 @@ DEFINE_CLASS(Seg, LOSeg, klass) | |
| klass->bufferFill = loSegBufferFill; | ||
| klass->bufferEmpty = loSegBufferEmpty; | ||
| klass->whiten = loSegWhiten; | ||
| klass->scan = loSegScan; | ||
| klass->fix = loSegFix; | ||
| klass->fixEmergency = loSegFix; | ||
| klass->reclaim = loSegReclaim; | ||
|
|
@@ -646,6 +648,62 @@ static Res loSegWhiten(Seg seg, Trace trace) | |
| } | ||
|
|
||
|
|
||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. m. There should be a comment on this function that at least explains why a Leaf Only pool has a scanner. (Edit: found it! design.mps.seg.method.scan.required) rule.generic.clear, rule.code.justified |
||
| static Res loSegScan(Bool *totalReturn, Seg seg, ScanState ss) | ||
| { | ||
| LOSeg loseg = MustBeA(LOSeg, seg); | ||
| Pool pool = SegPool(seg); | ||
| Addr p, base, limit; | ||
| Buffer buffer; | ||
| Bool hasBuffer = SegBuffer(&buffer, seg); | ||
| Format format = NULL; /* suppress "may be used uninitialized" warning */ | ||
| Bool b; | ||
|
|
||
| AVER(totalReturn != NULL); | ||
| AVERT(Seg, seg); | ||
| AVERT(ScanState, ss); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. m. If we expect loSegScan to only be called during a Pool Walk, then it should assert that it's in a Pool Walk. rule.code.minimal. |
||
|
|
||
| base = SegBase(seg); | ||
| limit = SegLimit(seg); | ||
|
|
||
| b = PoolFormat(&format, pool); | ||
| AVER(b); | ||
|
|
||
| p = base; | ||
| while (p < limit) { | ||
| Addr q; | ||
| Index i; | ||
|
|
||
| if (hasBuffer) { | ||
| if (p == BufferScanLimit(buffer) | ||
| && BufferScanLimit(buffer) != BufferLimit(buffer)) { | ||
| /* skip over buffered area */ | ||
| p = BufferLimit(buffer); | ||
| continue; | ||
| } | ||
| /* since we skip over the buffered area we are always */ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. m. This logic is duplicated several times. Grep for the string above. Copy-paste coding? |
||
| /* either before the buffer, or after it, never in it */ | ||
| AVER(p < BufferGetInit(buffer) || BufferLimit(buffer) <= p); | ||
| } | ||
| i = PoolIndexOfAddr(base, pool, p); | ||
| if (!BTGet(loseg->alloc, i)) { | ||
| p = AddrAdd(p, PoolAlignment(pool)); | ||
| continue; | ||
| } | ||
| q = (*format->skip)(AddrAdd(p, format->headerSize)); | ||
| q = AddrSub(q, format->headerSize); | ||
| if (BTGet(loseg->mark, i)) { | ||
| Res res = TraceScanFormat(ss, p, q); | ||
| if (res != ResOK) | ||
| return res; | ||
| } | ||
| p = q; | ||
| } | ||
| AVER(p == limit); | ||
|
|
||
| return ResOK; | ||
| } | ||
|
|
||
|
|
||
| static Res loSegFix(Seg seg, ScanState ss, Ref *refIO) | ||
| { | ||
| LOSeg loseg = MustBeA_CRITICAL(LOSeg, seg); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.