Generalising tracescanarea to be a checking wrapper for all area scanners.

Copied from Perforce
 Change: 189190
 ServerID: perforce.ravenbrook.com
This commit is contained in:
Richard Brooksby 2016-02-15 15:44:57 +00:00
parent a3fdda4678
commit 16bde84a68
14 changed files with 50 additions and 72 deletions

View file

@ -473,9 +473,9 @@ extern double TraceWorkFactor;
} \
END
extern Res TraceScanArea(ScanState ss, Word *base, Word *limit);
extern Res TraceScanAreaTagged(ScanState ss, Word *base, Word *limit,
Word mask, Word value);
extern Res TraceScanArea(ScanState ss, Word *base, Word *limit,
mps_area_scan_t scan_area,
void *closure, size_t closure_size);
extern void TraceScanSingleRef(TraceSet ts, Rank rank, Arena arena,
Seg seg, Ref *refIO);

View file

@ -47,11 +47,11 @@ Res MutatorFaultContextScan(ScanState ss, MutatorFaultContext mfc,
/* This scans the root registers (.context.regroots). It also unnecessarily
scans the rest of the context. The optimisation to scan only relevant
parts would be machine dependent. */
res = scan_area(
res = TraceScanArea(
ss,
(Word *)mfc->ucontext,
(Word *)((char *)mfc->ucontext + sizeof(*(mfc->ucontext))),
closure, closure_size
scan_area, closure, closure_size
);
return res;

View file

@ -112,10 +112,10 @@ Res MutatorFaultContextScan(ScanState ss, MutatorFaultContext mfc,
unnecessarily scans the rest of the context. The optimisation
to scan only relevant parts would be machine dependent. */
mc = &mfc->ucontext->uc_mcontext;
res = scan_area(ss,
(Word *)mc,
(Word *)((char *)mc + sizeof(*mc)),
closure, closure_size);
res = TraceScanArea(ss,
(Word *)mc,
(Word *)((char *)mc + sizeof(*mc)),
scan_area, closure, closure_size);
return res;
}

View file

@ -107,10 +107,10 @@ Res MutatorFaultContextScan(ScanState ss, MutatorFaultContext mfc,
unnecessarily scans the rest of the context. The optimisation
to scan only relevant parts would be machine dependent. */
mc = mfc->threadState;
res = scan_area(ss,
(Word *)mc,
(Word *)((char *)mc + sizeof(*mc)),
closure, closure_size);
res = TraceScanArea(ss,
(Word *)mc,
(Word *)((char *)mc + sizeof(*mc)),
scan_area, closure, closure_size);
return res;
}

View file

@ -41,11 +41,11 @@ Res MutatorFaultContextScan(ScanState ss, MutatorFaultContext mfc,
/* This scans the root registers (.context.regroots). It also unnecessarily
scans the rest of the context. The optimisation to scan only relevant
parts would be machine dependent. */
res = scan_area(
res = TraceScanArea(
ss,
(Word *)mfc->ucontext,
(Word *)((char *)mfc->ucontext + sizeof(*(mfc->ucontext))),
closure, closure_size
scan_area, closure, closure_size
);
return res;

View file

@ -116,10 +116,10 @@ Res MutatorFaultContextScan(ScanState ss, MutatorFaultContext mfc,
unnecessarily scans the rest of the context. The optimisation
to scan only relevant parts would be machine dependent. */
mc = &mfc->ucontext->uc_mcontext;
res = scan_area(&ss->ss_s,
(Word *)mc,
(Word *)((char *)mc + sizeof(*mc)),
closure, closure_size);
res = TraceScanArea(ss,
(Word *)mc,
(Word *)((char *)mc + sizeof(*mc)),
scan_area, closure, closure_size);
return res;
}

View file

@ -110,10 +110,10 @@ Res MutatorFaultContextScan(ScanState ss, MutatorFaultContext mfc,
unnecessarily scans the rest of the context. The optimisation
to scan only relevant parts would be machine dependent. */
mc = mfc->threadState;
res = scan_area(ss,
(Word *)mc,
(Word *)((char *)mc + sizeof(*mc)),
closure, closure_size);
res = TraceScanArea(ss,
(Word *)mc,
(Word *)((char *)mc + sizeof(*mc)),
scan_area, closure, closure_size);
return res;
}

View file

@ -507,7 +507,8 @@ Res RootScan(ScanState ss, Root root)
switch(root->var) {
case RootTABLE:
res = TraceScanArea(ss, root->the.table.base, root->the.table.limit);
res = TraceScanArea(ss, root->the.table.base, root->the.table.limit,
mps_scan_area, NULL, 0);
ss->scannedSize += AddrOffset(root->the.table.base, root->the.table.limit);
if (res != ResOK)
goto failScan;

View file

@ -49,16 +49,17 @@ Res StackScanInner(ScanState ss, Word *stackBot, Word *stackTop,
if (arena->stackAtArenaEnter != NULL) {
AVER(stackTop < arena->stackAtArenaEnter);
AVER(arena->stackAtArenaEnter < stackBot);
res = scan_area(&ss->ss_s, stackTop, stackTop + nSavedRegs,
closure, closure_size);
res = TraceScanArea(ss, stackTop, stackTop + nSavedRegs,
scan_area, closure, closure_size);
if (res != ResOK)
return res;
res = scan_area(&ss->ss_s, arena->stackAtArenaEnter, stackBot,
closure, closure_size);
res = TraceScanArea(ss, arena->stackAtArenaEnter, stackBot,
scan_area, closure, closure_size);
if (res != ResOK)
return res;
} else {
res = scan_area(&ss->ss_s, stackTop, stackBot, closure, closure_size);
res = TraceScanArea(ss, stackTop, stackBot,
scan_area, closure, closure_size);
if (res != ResOK)
return res;
}

View file

@ -272,7 +272,8 @@ Res ThreadScan(ScanState ss, Thread thread, Word *stackBot,
/* scan stack inclusive of current sp and exclusive of
* stackBot (.stack.full-descend)
*/
res = scan_area(&ss->ss_s, stackBase, stackLimit, closure, closure_size);
res = TraceScanArea(ss, stackBase, stackLimit,
scan_area, closure, closure_size);
if(res != ResOK)
return res;

View file

@ -106,7 +106,8 @@ Res ThreadScan(ScanState ss, Thread thread, Word *stackBot,
/* scan stack inclusive of current sp and exclusive of
* stackBot (.stack.full-descend)
*/
res = scan_area(ss, stackBase, stackLimit, closure, closure_size);
res = TraceScanArea(ss, stackBase, stackLimit,
scan_area, closure, closure_size);
if(res != ResOK)
return res;
@ -115,9 +116,9 @@ Res ThreadScan(ScanState ss, Thread thread, Word *stackBot,
* unnecessarily scans the rest of the context. The optimisation
* to scan only relevant parts would be machine dependent.
*/
res = scan_area(ss, (Word *)&context,
(Word *)((char *)&context + sizeof(CONTEXT)),
closure, closure_size);
res = TraceScanArea(ss, (Word *)&context,
(Word *)((char *)&context + sizeof(CONTEXT)),
scan_area, closure, closure_size);
if(res != ResOK)
return res;

View file

@ -106,8 +106,8 @@ Res ThreadScan(ScanState ss, Thread thread, Word *stackBot,
/* scan stack inclusive of current sp and exclusive of
* stackBot (.stack.full-descend)
*/
res = scan_area(ss, stackBase, stackLimit,
void *closure, size_t closure_size);
res = TraceScanArea(ss, stackBase, stackLimit,
scan_area, closure, closure_size);
if(res != ResOK)
return res;
@ -116,9 +116,9 @@ Res ThreadScan(ScanState ss, Thread thread, Word *stackBot,
* unnecessarily scans the rest of the context. The optimisation
* to scan only relevant parts would be machine dependent.
*/
res = scan_area(ss, (Word *)&context,
(Word *)((char *)&context + sizeof(CONTEXT)),
closure, closure_size);
res = TraceScanArea(ss, (Word *)&context,
(Word *)((char *)&context + sizeof(CONTEXT)),
scan_area, closure, closure_size);
if(res != ResOK)
return res;

View file

@ -260,7 +260,8 @@ Res ThreadScan(ScanState ss, Thread thread, Word *stackBot,
/* scan stack inclusive of current sp and exclusive of
* stackBot (.stack.full-descend)
*/
res = scan_area(ss, stackBase, stackLimit, closure, closure_sized);
res = TraceScanArea(ss, stackBase, stackLimit,
scan_area, closure, closure_size);
if(res != ResOK)
return res;

View file

@ -1427,48 +1427,21 @@ void TraceScanSingleRef(TraceSet ts, Rank rank, Arena arena,
* limit, inclusive of base and exclusive of limit. */
Res TraceScanArea(ScanState ss, Word *base, Word *limit)
Res TraceScanArea(ScanState ss, Word *base, Word *limit,
mps_area_scan_t scan_area,
void *closure, size_t closure_size)
{
AVERT(ScanState, ss);
AVER(base != NULL);
AVER(limit != NULL);
AVER(base < limit);
EVENT3(TraceScanArea, ss, base, limit);
return mps_scan_area(&ss->ss_s, base, limit, NULL, 0);
return scan_area(&ss->ss_s, base, limit, closure, closure_size);
}
#if 0
/* TraceScanAreaTagged -- scan contiguous area of tagged references
*
* This is as TraceScanArea except words are only fixed if they have
* the given value when masked with a mask.
*
* This has ATTRIBUTE_NO_SANITIZE_ADDRESS otherwise Clang's address
* sanitizer will think we have run off the end of an array.
*/
Res TraceScanAreaTagged(ScanState ss, Word *base, Word *limit,Word mask,
Word pattern)
{
mps_scan_tag_s tag;
AVERT(ScanState, ss);
AVER(base != NULL);
AVER(limit != NULL);
AVER(base < limit);
EVENT3(TraceScanAreaTagged, ss, base, limit);
tag.mask = mask;
tag.pattern = pattern;
return mps_scan_area_tagged(&ss->ss_s, base, limit, &tag, 0);
}
#endif
/* traceCondemnAll -- condemn everything and notify all the chains */
static Res traceCondemnAll(Trace trace)