diff options
| author | Richard Brooksby | 2012-09-07 23:48:14 +0100 |
|---|---|---|
| committer | Richard Brooksby | 2012-09-07 23:48:14 +0100 |
| commit | 5a604a2f5197e7c769638fadb98aa41d88faef7f (patch) | |
| tree | 8ba711da58dfd437f2cac5499dc01c31c07b8197 /mps/code | |
| parent | 6c887280e43265b347cdd9056c86271ad81e8c2a (diff) | |
| download | emacs-5a604a2f5197e7c769638fadb98aa41d88faef7f.tar.gz emacs-5a604a2f5197e7c769638fadb98aa41d88faef7f.zip | |
Fixing bugs introduced by type puns passed through scanning methods, discovered by offsetting mps_ss_s from the beginning of scanstatestruct.
Adding a pseudo-target "find-puns" which, on FreeBSD mostly, prints useful warnings about strict aliasing rule violations.
Fixing more strict aliasing rule violations found by the above.
Copied from Perforce
Change: 179358
ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
| -rw-r--r-- | mps/code/comm.gmk | 12 | ||||
| -rw-r--r-- | mps/code/mpm.h | 20 | ||||
| -rw-r--r-- | mps/code/mpmtypes.h | 6 | ||||
| -rw-r--r-- | mps/code/poolamc.c | 8 | ||||
| -rw-r--r-- | mps/code/poolams.c | 4 | ||||
| -rw-r--r-- | mps/code/poolawl.c | 2 | ||||
| -rw-r--r-- | mps/code/poolsnc.c | 2 | ||||
| -rw-r--r-- | mps/code/root.c | 6 | ||||
| -rw-r--r-- | mps/code/trace.c | 41 |
9 files changed, 60 insertions, 41 deletions
diff --git a/mps/code/comm.gmk b/mps/code/comm.gmk index 3b775882bc3..6ab9dec268c 100644 --- a/mps/code/comm.gmk +++ b/mps/code/comm.gmk | |||
| @@ -498,6 +498,18 @@ $(PFM)/$(VARIETY)/%: | |||
| 498 | $(CC) $(CFLAGS) $(LINKFLAGS) -o $@ $^ $(LIBS) | 498 | $(CC) $(CFLAGS) $(LINKFLAGS) -o $@ $^ $(LIBS) |
| 499 | 499 | ||
| 500 | 500 | ||
| 501 | # Special targets for development | ||
| 502 | |||
| 503 | # Currently FreeBSD 7 GCC 4.2.1 is the best platform we have for warning | ||
| 504 | # us about strict aliasing rule violations caused by type puns. This | ||
| 505 | # target reveals them, and produces an assembler output file that can be | ||
| 506 | # examined to see if they're actually dangerous. RB 2012-09-07 | ||
| 507 | |||
| 508 | find-puns: phony | ||
| 509 | { echo '#include "mps.c"'; echo '#include "fmtdy.c"'; } | \ | ||
| 510 | gcc -S -fverbose-asm -ansi -pedantic -Wall -Wstrict-aliasing=2 -O3 -x c -o pun.s - | ||
| 511 | |||
| 512 | |||
| 501 | # C. COPYRIGHT AND LICENSE | 513 | # C. COPYRIGHT AND LICENSE |
| 502 | # | 514 | # |
| 503 | # Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>. | 515 | # Copyright (C) 2001-2002 Ravenbrook Limited <http://www.ravenbrook.com/>. |
diff --git a/mps/code/mpm.h b/mps/code/mpm.h index bdf4ba79d74..d43e92d10a2 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h | |||
| @@ -154,9 +154,13 @@ extern Res WriteF_v(mps_lib_FILE *stream, va_list args); | |||
| 154 | extern Res WriteF_firstformat_v(mps_lib_FILE *stream, | 154 | extern Res WriteF_firstformat_v(mps_lib_FILE *stream, |
| 155 | const char *firstformat, va_list args); | 155 | const char *firstformat, va_list args); |
| 156 | 156 | ||
| 157 | #if defined(DIAG_WITH_STREAM_AND_WRITEF) | ||
| 157 | extern int Stream_fputc(int c, mps_lib_FILE *stream); | 158 | extern int Stream_fputc(int c, mps_lib_FILE *stream); |
| 158 | extern int Stream_fputs(const char *s, mps_lib_FILE *stream); | 159 | extern int Stream_fputs(const char *s, mps_lib_FILE *stream); |
| 159 | 160 | #else | |
| 161 | #define Stream_fputc mps_lib_fputc | ||
| 162 | #define Stream_fputs mps_lib_fputs | ||
| 163 | #endif | ||
| 160 | 164 | ||
| 161 | 165 | ||
| 162 | /* Miscellaneous support -- see <code/mpm.c> */ | 166 | /* Miscellaneous support -- see <code/mpm.c> */ |
| @@ -419,6 +423,8 @@ extern double TraceWorkFactor; | |||
| 419 | ZoneSet SCANwhite = ScanStateWhite(ss); \ | 423 | ZoneSet SCANwhite = ScanStateWhite(ss); \ |
| 420 | RefSet SCANsummary = ScanStateUnfixedSummary(ss); \ | 424 | RefSet SCANsummary = ScanStateUnfixedSummary(ss); \ |
| 421 | Word SCANt; \ | 425 | Word SCANt; \ |
| 426 | mps_addr_t SCANref; \ | ||
| 427 | Res SCANres; \ | ||
| 422 | { | 428 | { |
| 423 | 429 | ||
| 424 | /* Equivalent to <code/mps.h> MPS_FIX1 */ | 430 | /* Equivalent to <code/mps.h> MPS_FIX1 */ |
| @@ -430,7 +436,17 @@ extern double TraceWorkFactor; | |||
| 430 | 436 | ||
| 431 | /* Equivalent to <code/mps.h> MPS_FIX2 */ | 437 | /* Equivalent to <code/mps.h> MPS_FIX2 */ |
| 432 | 438 | ||
| 433 | #define TRACE_FIX2(ss, refIO) _mps_fix2((mps_ss_t)(ss), (mps_addr_t *)(refIO)) | 439 | /* TODO: The ref is copied to avoid breaking strict aliasing rules that could |
| 440 | well affect optimised scan loops. This code could be improved by | ||
| 441 | returning the fixed ref as a result and using longjmp to signal errors, | ||
| 442 | and that might well improve all scan loops too. The problem is whether | ||
| 443 | some embedded client platforms support longjmp. RB 2012-09-07 */ | ||
| 444 | |||
| 445 | #define TRACE_FIX2(ss, refIO) \ | ||
| 446 | (SCANref = (mps_addr_t)*(refIO), \ | ||
| 447 | SCANres = _mps_fix2(&(ss)->ss_s, &SCANref), \ | ||
| 448 | *(refIO) = SCANref, \ | ||
| 449 | SCANres) | ||
| 434 | 450 | ||
| 435 | /* Equivalent to <code/mps.h> MPS_FIX */ | 451 | /* Equivalent to <code/mps.h> MPS_FIX */ |
| 436 | 452 | ||
diff --git a/mps/code/mpmtypes.h b/mps/code/mpmtypes.h index a15098c53ee..b1853178cbb 100644 --- a/mps/code/mpmtypes.h +++ b/mps/code/mpmtypes.h | |||
| @@ -246,7 +246,7 @@ typedef struct TraceMessageStruct *TraceMessage; /* trace end */ | |||
| 246 | /* .fmt-methods: These methods must match those defined in the */ | 246 | /* .fmt-methods: These methods must match those defined in the */ |
| 247 | /* MPS C Interface. (See <code/mps.h#fmt-methods>.) */ | 247 | /* MPS C Interface. (See <code/mps.h#fmt-methods>.) */ |
| 248 | 248 | ||
| 249 | typedef Res (*FormatScanMethod)(ScanState ss, Addr base, Addr limit); | 249 | typedef Res (*FormatScanMethod)(mps_ss_t ss, Addr base, Addr limit); |
| 250 | typedef Addr (*FormatSkipMethod)(Addr object); | 250 | typedef Addr (*FormatSkipMethod)(Addr object); |
| 251 | typedef void (*FormatMoveMethod)(Addr object, Addr to); | 251 | typedef void (*FormatMoveMethod)(Addr object, Addr to); |
| 252 | typedef Addr (*FormatIsMovedMethod)(Addr object); | 252 | typedef Addr (*FormatIsMovedMethod)(Addr object); |
| @@ -259,8 +259,8 @@ typedef Addr (*FormatClassMethod)(Addr object); | |||
| 259 | /* .root-methods: These methods must match those defined in the */ | 259 | /* .root-methods: These methods must match those defined in the */ |
| 260 | /* MPS C Interface. (See <code/mps.h#root-methods>.) */ | 260 | /* MPS C Interface. (See <code/mps.h#root-methods>.) */ |
| 261 | 261 | ||
| 262 | typedef Res (*RootScanMethod)(ScanState ss, void *p, size_t s); | 262 | typedef Res (*RootScanMethod)(mps_ss_t ss, void *p, size_t s); |
| 263 | typedef Res (*RootScanRegMethod)(ScanState ss, Thread thread, void *p, size_t s); | 263 | typedef Res (*RootScanRegMethod)(mps_ss_t ss, Thread thread, void *p, size_t s); |
| 264 | 264 | ||
| 265 | 265 | ||
| 266 | /* CONSTANTS */ | 266 | /* CONSTANTS */ |
diff --git a/mps/code/poolamc.c b/mps/code/poolamc.c index c4500a811dd..fc71144ab84 100644 --- a/mps/code/poolamc.c +++ b/mps/code/poolamc.c | |||
| @@ -1453,7 +1453,7 @@ static Res amcScanNailedOnce(Bool *totalReturn, Bool *moreReturn, | |||
| 1453 | Addr q; | 1453 | Addr q; |
| 1454 | q = (*format->skip)(p); | 1454 | q = (*format->skip)(p); |
| 1455 | if(amcNailGetMark(seg, p)) { | 1455 | if(amcNailGetMark(seg, p)) { |
| 1456 | res = (*format->scan)(ss, p, q); | 1456 | res = (*format->scan)(&ss->ss_s, p, q); |
| 1457 | if(res != ResOK) { | 1457 | if(res != ResOK) { |
| 1458 | *totalReturn = FALSE; | 1458 | *totalReturn = FALSE; |
| 1459 | *moreReturn = TRUE; | 1459 | *moreReturn = TRUE; |
| @@ -1476,7 +1476,7 @@ static Res amcScanNailedOnce(Bool *totalReturn, Bool *moreReturn, | |||
| 1476 | Addr q; | 1476 | Addr q; |
| 1477 | q = (*format->skip)(p); | 1477 | q = (*format->skip)(p); |
| 1478 | if(amcNailGetMark(seg, p)) { | 1478 | if(amcNailGetMark(seg, p)) { |
| 1479 | res = (*format->scan)(ss, p, q); | 1479 | res = (*format->scan)(&ss->ss_s, p, q); |
| 1480 | if(res != ResOK) { | 1480 | if(res != ResOK) { |
| 1481 | *totalReturn = FALSE; | 1481 | *totalReturn = FALSE; |
| 1482 | *moreReturn = TRUE; | 1482 | *moreReturn = TRUE; |
| @@ -1601,7 +1601,7 @@ static Res AMCScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg) | |||
| 1601 | *totalReturn = TRUE; | 1601 | *totalReturn = TRUE; |
| 1602 | return ResOK; | 1602 | return ResOK; |
| 1603 | } | 1603 | } |
| 1604 | res = (*format->scan)(ss, base, limit); | 1604 | res = (*format->scan)(&ss->ss_s, base, limit); |
| 1605 | if(res != ResOK) { | 1605 | if(res != ResOK) { |
| 1606 | *totalReturn = FALSE; | 1606 | *totalReturn = FALSE; |
| 1607 | return res; | 1607 | return res; |
| @@ -1615,7 +1615,7 @@ static Res AMCScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg) | |||
| 1615 | AVER(SegBase(seg) <= base); | 1615 | AVER(SegBase(seg) <= base); |
| 1616 | AVER(base <= AddrAdd(SegLimit(seg), format->headerSize)); | 1616 | AVER(base <= AddrAdd(SegLimit(seg), format->headerSize)); |
| 1617 | if(base < limit) { | 1617 | if(base < limit) { |
| 1618 | res = (*format->scan)(ss, base, limit); | 1618 | res = (*format->scan)(&ss->ss_s, base, limit); |
| 1619 | if(res != ResOK) { | 1619 | if(res != ResOK) { |
| 1620 | *totalReturn = FALSE; | 1620 | *totalReturn = FALSE; |
| 1621 | return res; | 1621 | return res; |
diff --git a/mps/code/poolams.c b/mps/code/poolams.c index 880e20f7bb0..34e07fceccc 100644 --- a/mps/code/poolams.c +++ b/mps/code/poolams.c | |||
| @@ -1237,7 +1237,7 @@ static Res amsScanObject(Seg seg, Index i, Addr p, Addr next, void *clos) | |||
| 1237 | 1237 | ||
| 1238 | /* @@@@ This isn't quite right for multiple traces. */ | 1238 | /* @@@@ This isn't quite right for multiple traces. */ |
| 1239 | if (closure->scanAllObjects || AMS_IS_GREY(seg, i)) { | 1239 | if (closure->scanAllObjects || AMS_IS_GREY(seg, i)) { |
| 1240 | res = (*format->scan)(closure->ss, | 1240 | res = (*format->scan)(&closure->ss->ss_s, |
| 1241 | AddrAdd(p, format->headerSize), | 1241 | AddrAdd(p, format->headerSize), |
| 1242 | AddrAdd(next, format->headerSize)); | 1242 | AddrAdd(next, format->headerSize)); |
| 1243 | if (res != ResOK) | 1243 | if (res != ResOK) |
| @@ -1331,7 +1331,7 @@ Res AMSScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg) | |||
| 1331 | next = AddrAdd(p, alignment); | 1331 | next = AddrAdd(p, alignment); |
| 1332 | } | 1332 | } |
| 1333 | j = AMS_ADDR_INDEX(seg, next); | 1333 | j = AMS_ADDR_INDEX(seg, next); |
| 1334 | res = (*format->scan)(ss, clientP, clientNext); | 1334 | res = (*format->scan)(&ss->ss_s, clientP, clientNext); |
| 1335 | if (res != ResOK) { | 1335 | if (res != ResOK) { |
| 1336 | /* <design/poolams/#marked.scan.fail> */ | 1336 | /* <design/poolams/#marked.scan.fail> */ |
| 1337 | amsseg->marksChanged = TRUE; | 1337 | amsseg->marksChanged = TRUE; |
diff --git a/mps/code/poolawl.c b/mps/code/poolawl.c index e1fcbd94b4e..da63a4374d3 100644 --- a/mps/code/poolawl.c +++ b/mps/code/poolawl.c | |||
| @@ -820,7 +820,7 @@ static Res awlScanObject(Arena arena, AWL awl, ScanState ss, | |||
| 820 | SegSetSummary(dependentSeg, RefSetUNIV); | 820 | SegSetSummary(dependentSeg, RefSetUNIV); |
| 821 | } | 821 | } |
| 822 | 822 | ||
| 823 | res = (*format->scan)(ss, base, limit); | 823 | res = (*format->scan)(&ss->ss_s, base, limit); |
| 824 | if (res == ResOK) | 824 | if (res == ResOK) |
| 825 | ss->scannedSize += AddrOffset(base, limit); | 825 | ss->scannedSize += AddrOffset(base, limit); |
| 826 | 826 | ||
diff --git a/mps/code/poolsnc.c b/mps/code/poolsnc.c index 657c0f54843..4dcb7115902 100644 --- a/mps/code/poolsnc.c +++ b/mps/code/poolsnc.c | |||
| @@ -516,7 +516,7 @@ static Res SNCScan(Bool *totalReturn, ScanState ss, Pool pool, Seg seg) | |||
| 516 | } | 516 | } |
| 517 | 517 | ||
| 518 | if (base < limit) { | 518 | if (base < limit) { |
| 519 | res = (*format->scan)(ss, base, limit); | 519 | res = (*format->scan)(&ss->ss_s, base, limit); |
| 520 | if (res != ResOK) { | 520 | if (res != ResOK) { |
| 521 | *totalReturn = FALSE; | 521 | *totalReturn = FALSE; |
| 522 | return res; | 522 | return res; |
diff --git a/mps/code/root.c b/mps/code/root.c index 9484c4bfa36..9ce385a124c 100644 --- a/mps/code/root.c +++ b/mps/code/root.c | |||
| @@ -478,20 +478,20 @@ Res RootScan(ScanState ss, Root root) | |||
| 478 | break; | 478 | break; |
| 479 | 479 | ||
| 480 | case RootFUN: | 480 | case RootFUN: |
| 481 | res = (*root->the.fun.scan)(ss, root->the.fun.p, root->the.fun.s); | 481 | res = (*root->the.fun.scan)(&ss->ss_s, root->the.fun.p, root->the.fun.s); |
| 482 | if (res != ResOK) | 482 | if (res != ResOK) |
| 483 | goto failScan; | 483 | goto failScan; |
| 484 | break; | 484 | break; |
| 485 | 485 | ||
| 486 | case RootREG: | 486 | case RootREG: |
| 487 | res = (*root->the.reg.scan)(ss, root->the.reg.thread, | 487 | res = (*root->the.reg.scan)(&ss->ss_s, root->the.reg.thread, |
| 488 | root->the.reg.p, root->the.reg.s); | 488 | root->the.reg.p, root->the.reg.s); |
| 489 | if (res != ResOK) | 489 | if (res != ResOK) |
| 490 | goto failScan; | 490 | goto failScan; |
| 491 | break; | 491 | break; |
| 492 | 492 | ||
| 493 | case RootFMT: | 493 | case RootFMT: |
| 494 | res = (*root->the.fmt.scan)(ss, root->the.fmt.base, root->the.fmt.limit); | 494 | res = (*root->the.fmt.scan)(&ss->ss_s, root->the.fmt.base, root->the.fmt.limit); |
| 495 | ss->scannedSize += AddrOffset(root->the.fmt.base, root->the.fmt.limit); | 495 | ss->scannedSize += AddrOffset(root->the.fmt.base, root->the.fmt.limit); |
| 496 | if (res != ResOK) | 496 | if (res != ResOK) |
| 497 | goto failScan; | 497 | goto failScan; |
diff --git a/mps/code/trace.c b/mps/code/trace.c index 09fb803b2cc..ffe800e151e 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c | |||
| @@ -1295,26 +1295,31 @@ void TraceSegAccess(Arena arena, Seg seg, AccessSet mode) | |||
| 1295 | } | 1295 | } |
| 1296 | 1296 | ||
| 1297 | 1297 | ||
| 1298 | /* TraceFix2 -- second stage of fixing a reference | 1298 | /* _mps_fix2 (a.k.a. "TraceFix") -- second stage of fixing a reference |
| 1299 | * | 1299 | * |
| 1300 | * TraceFix is on the [critical path](../design/critical-path.txt). A | 1300 | * _mps_fix2 is on the [critical path](../design/critical-path.txt). A |
| 1301 | * one-instruction difference in the early parts of this code will have a | 1301 | * one-instruction difference in the early parts of this code will have a |
| 1302 | * significant impact on overall run time. The priority is to eliminate | 1302 | * significant impact on overall run time. The priority is to eliminate |
| 1303 | * irrelevant references early and fast using the colour information stored | 1303 | * irrelevant references early and fast using the colour information stored |
| 1304 | * in the tract table. | 1304 | * in the tract table. |
| 1305 | * | ||
| 1306 | * The name "TraceFix" is pervasive in the MPS and its documents to describe | ||
| 1307 | * this function. Optimisation and strict aliasing rules have meant that we | ||
| 1308 | * need to use the external name for it here. | ||
| 1305 | */ | 1309 | */ |
| 1306 | 1310 | ||
| 1307 | static Res TraceFix2(ScanState ss, Ref *refIO) | 1311 | mps_res_t _mps_fix2(mps_ss_t mps_ss, mps_addr_t *mps_ref_io) |
| 1308 | { | 1312 | { |
| 1313 | ScanState ss = PARENT(ScanStateStruct, ss_s, mps_ss); | ||
| 1309 | Ref ref; | 1314 | Ref ref; |
| 1310 | Tract tract; | 1315 | Tract tract; |
| 1311 | 1316 | ||
| 1312 | /* Special AVER macros are used on the critical path. */ | 1317 | /* Special AVER macros are used on the critical path. */ |
| 1313 | /* See <design/trace/#fix.noaver> */ | 1318 | /* See <design/trace/#fix.noaver> */ |
| 1314 | AVERT_CRITICAL(ScanState, ss); | 1319 | AVERT_CRITICAL(ScanState, ss); |
| 1315 | AVER_CRITICAL(refIO != NULL); | 1320 | AVER_CRITICAL(mps_ref_io != NULL); |
| 1316 | 1321 | ||
| 1317 | ref = *refIO; | 1322 | ref = (Ref)*mps_ref_io; |
| 1318 | 1323 | ||
| 1319 | /* The zone test should already have been passed by MPS_FIX1 in mps.h. */ | 1324 | /* The zone test should already have been passed by MPS_FIX1 in mps.h. */ |
| 1320 | AVER_CRITICAL(ZoneSetInter(ScanStateWhite(ss), | 1325 | AVER_CRITICAL(ZoneSetInter(ScanStateWhite(ss), |
| @@ -1322,7 +1327,7 @@ static Res TraceFix2(ScanState ss, Ref *refIO) | |||
| 1322 | ZoneSetEMPTY); | 1327 | ZoneSetEMPTY); |
| 1323 | 1328 | ||
| 1324 | STATISTIC(++ss->fixRefCount); | 1329 | STATISTIC(++ss->fixRefCount); |
| 1325 | EVENT4(TraceFix, ss, refIO, ref, ss->rank); | 1330 | EVENT4(TraceFix, ss, mps_ref_io, ref, ss->rank); |
| 1326 | 1331 | ||
| 1327 | TRACT_OF_ADDR(&tract, ss->arena, ref); | 1332 | TRACT_OF_ADDR(&tract, ss->arena, ref); |
| 1328 | if(tract) { | 1333 | if(tract) { |
| @@ -1336,7 +1341,7 @@ static Res TraceFix2(ScanState ss, Ref *refIO) | |||
| 1336 | EVENT1(TraceFixSeg, seg); | 1341 | EVENT1(TraceFixSeg, seg); |
| 1337 | EVENT0(TraceFixWhite); | 1342 | EVENT0(TraceFixWhite); |
| 1338 | pool = TractPool(tract); | 1343 | pool = TractPool(tract); |
| 1339 | res = (*ss->fix)(pool, ss, seg, refIO); | 1344 | res = (*ss->fix)(pool, ss, seg, &ref); |
| 1340 | if(res != ResOK) { | 1345 | if(res != ResOK) { |
| 1341 | /* PoolFixEmergency should never fail. */ | 1346 | /* PoolFixEmergency should never fail. */ |
| 1342 | AVER_CRITICAL(ss->fix != PoolFixEmergency); | 1347 | AVER_CRITICAL(ss->fix != PoolFixEmergency); |
| @@ -1347,7 +1352,7 @@ static Res TraceFix2(ScanState ss, Ref *refIO) | |||
| 1347 | * C: the code (here) already assumes this: it returns without | 1352 | * C: the code (here) already assumes this: it returns without |
| 1348 | * updating ss->fixedSummary. RHSK 2007-03-21. | 1353 | * updating ss->fixedSummary. RHSK 2007-03-21. |
| 1349 | */ | 1354 | */ |
| 1350 | AVER(*refIO == ref); | 1355 | AVER(ref == (Ref)*mps_ref_io); |
| 1351 | return res; | 1356 | return res; |
| 1352 | } | 1357 | } |
| 1353 | } else { | 1358 | } else { |
| @@ -1378,27 +1383,13 @@ static Res TraceFix2(ScanState ss, Ref *refIO) | |||
| 1378 | } | 1383 | } |
| 1379 | 1384 | ||
| 1380 | /* See <design/trace/#fix.fixed.all> */ | 1385 | /* See <design/trace/#fix.fixed.all> */ |
| 1381 | ss->fixedSummary = RefSetAdd(ss->arena, ss->fixedSummary, *refIO); | 1386 | ss->fixedSummary = RefSetAdd(ss->arena, ss->fixedSummary, ref); |
| 1382 | 1387 | ||
| 1388 | *mps_ref_io = (mps_addr_t)ref; | ||
| 1383 | return ResOK; | 1389 | return ResOK; |
| 1384 | } | 1390 | } |
| 1385 | 1391 | ||
| 1386 | 1392 | ||
| 1387 | /* mps_fix2 -- external interface to TraceFix | ||
| 1388 | * | ||
| 1389 | * We rely on compiler inlining to make this equivalent to TraceFix, because | ||
| 1390 | * the name "TraceFix" is pervasive in the MPS. That's also why this | ||
| 1391 | * function is in trace.c and not mpsi.c. | ||
| 1392 | */ | ||
| 1393 | |||
| 1394 | mps_res_t _mps_fix2(mps_ss_t mps_ss, mps_addr_t *mps_ref_io) | ||
| 1395 | { | ||
| 1396 | ScanState ss = PARENT(ScanStateStruct, ss_s, mps_ss); | ||
| 1397 | Ref *refIO = (Ref *)mps_ref_io; | ||
| 1398 | return TraceFix2(ss, refIO); | ||
| 1399 | } | ||
| 1400 | |||
| 1401 | |||
| 1402 | /* traceScanSingleRefRes -- scan a single reference, with result code */ | 1393 | /* traceScanSingleRefRes -- scan a single reference, with result code */ |
| 1403 | 1394 | ||
| 1404 | static Res traceScanSingleRefRes(TraceSet ts, Rank rank, Arena arena, | 1395 | static Res traceScanSingleRefRes(TraceSet ts, Rank rank, Arena arena, |