diff options
Diffstat (limited to 'mps/code')
| -rw-r--r-- | mps/code/diag.c | 86 | ||||
| -rw-r--r-- | mps/code/mpm.c | 41 | ||||
| -rw-r--r-- | mps/code/mpm.h | 49 | ||||
| -rw-r--r-- | mps/code/trace.c | 8 |
4 files changed, 161 insertions, 23 deletions
diff --git a/mps/code/diag.c b/mps/code/diag.c index 639401b4169..6c369cce110 100644 --- a/mps/code/diag.c +++ b/mps/code/diag.c | |||
| @@ -28,6 +28,92 @@ mps_lib_FILE *DiagStream(void) | |||
| 28 | return mps_lib_stdout; | 28 | return mps_lib_stdout; |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | const char *DiagTagGlobal = NULL; | ||
| 32 | |||
| 33 | static void DiagTagBegin(const char *tag) | ||
| 34 | { | ||
| 35 | Res res; | ||
| 36 | |||
| 37 | AVER(DiagTagGlobal == NULL); | ||
| 38 | DiagTagGlobal = tag; | ||
| 39 | res = WriteF(DiagStream(), "MPS.$S { ", tag, NULL); | ||
| 40 | AVER(res == ResOK); | ||
| 41 | } | ||
| 42 | |||
| 43 | static void DiagTagEnd(const char *tag) | ||
| 44 | { | ||
| 45 | Res res; | ||
| 46 | |||
| 47 | AVER(DiagTagGlobal != NULL); | ||
| 48 | /* AVER(strequal(DiagTagGlobal, tag)); */ | ||
| 49 | res = WriteF(DiagStream(), "} MPS.$S\n", tag, NULL); | ||
| 50 | DiagTagGlobal = NULL; | ||
| 51 | AVER(DiagTagGlobal == NULL); | ||
| 52 | } | ||
| 53 | |||
| 54 | void DiagSingleF(const char *tag, ...) | ||
| 55 | { | ||
| 56 | va_list args; | ||
| 57 | Res res; | ||
| 58 | |||
| 59 | DiagTagBegin(tag); | ||
| 60 | |||
| 61 | va_start(args, tag); | ||
| 62 | res = WriteF_v(DiagStream(), args); | ||
| 63 | AVER(res == ResOK); | ||
| 64 | va_end(args); | ||
| 65 | |||
| 66 | DiagTagEnd(tag); | ||
| 67 | } | ||
| 68 | |||
| 69 | void DiagFirstF(const char *tag, ...) | ||
| 70 | { | ||
| 71 | va_list args; | ||
| 72 | Res res; | ||
| 73 | |||
| 74 | DiagTagBegin(tag); | ||
| 75 | |||
| 76 | va_start(args, tag); | ||
| 77 | res = WriteF_v(DiagStream(), args); | ||
| 78 | AVER(res == ResOK); | ||
| 79 | va_end(args); | ||
| 80 | } | ||
| 81 | |||
| 82 | void DiagMoreF(const char *firstformat, ...) | ||
| 83 | { | ||
| 84 | va_list args; | ||
| 85 | Res res; | ||
| 86 | |||
| 87 | /* ISO C says there must be at least one named parameter: hence */ | ||
| 88 | /* the named firstformat. It only looks different: there is no */ | ||
| 89 | /* change from the expected WriteF protocol. (In particular, */ | ||
| 90 | /* firstformat may legally be NULL, with the variable part empty). */ | ||
| 91 | |||
| 92 | va_start(args, firstformat); | ||
| 93 | res = WriteF_firstformat_v(DiagStream(), firstformat, args); | ||
| 94 | AVER(res == ResOK); | ||
| 95 | va_end(args); | ||
| 96 | } | ||
| 97 | |||
| 98 | void DiagEnd(const char *tag) | ||
| 99 | { | ||
| 100 | DiagTagEnd(tag); | ||
| 101 | } | ||
| 102 | |||
| 103 | extern void diag_test(void); | ||
| 104 | |||
| 105 | void diag_test(void) | ||
| 106 | { | ||
| 107 | DIAG_SINGLEF(( "TestTag1", "text $U.\n", 42, NULL )); | ||
| 108 | |||
| 109 | DIAG_FIRSTF(( "TestTag2", "text $U.\n", 42, NULL )); | ||
| 110 | DIAG_MOREF(( NULL )); | ||
| 111 | DIAG_MOREF(( "string $S.\n", "fooey!", NULL )); | ||
| 112 | DIAG_MOREF(( NULL )); | ||
| 113 | DIAG_MOREF(( "Another string $S.\n", "baloney!", NULL )); | ||
| 114 | DIAG_END( "TestTag2" ); | ||
| 115 | } | ||
| 116 | |||
| 31 | /* C. COPYRIGHT AND LICENSE | 117 | /* C. COPYRIGHT AND LICENSE |
| 32 | * | 118 | * |
| 33 | * Copyright (C) 2007 Ravenbrook Limited <http://www.ravenbrook.com/>. | 119 | * Copyright (C) 2007 Ravenbrook Limited <http://www.ravenbrook.com/>. |
diff --git a/mps/code/mpm.c b/mps/code/mpm.c index 4282a06b937..04bb8418f61 100644 --- a/mps/code/mpm.c +++ b/mps/code/mpm.c | |||
| @@ -409,7 +409,16 @@ static Res WriteDouble(mps_lib_FILE *stream, double d) | |||
| 409 | 409 | ||
| 410 | /* WriteF -- write formatted output | 410 | /* WriteF -- write formatted output |
| 411 | * | 411 | * |
| 412 | * Calls WriteF_v. | 412 | * .writef.des: See <design/writef/>, also <design/lib/> |
| 413 | * | ||
| 414 | * .writef.p: There is an assumption that void * fits in Word in | ||
| 415 | * the case of $P, and unsigned long for $U and $B. This is checked in | ||
| 416 | * MPMCheck. | ||
| 417 | * | ||
| 418 | * .writef.div: Although MPS_WORD_WIDTH/4 appears three times, there | ||
| 419 | * are effectively three separate decisions to format at this width. | ||
| 420 | * | ||
| 421 | * .writef.check: See .check.writef. | ||
| 413 | */ | 422 | */ |
| 414 | 423 | ||
| 415 | Res WriteF(mps_lib_FILE *stream, ...) | 424 | Res WriteF(mps_lib_FILE *stream, ...) |
| @@ -423,21 +432,20 @@ Res WriteF(mps_lib_FILE *stream, ...) | |||
| 423 | return res; | 432 | return res; |
| 424 | } | 433 | } |
| 425 | 434 | ||
| 435 | Res WriteF_v(mps_lib_FILE *stream, va_list args) | ||
| 436 | { | ||
| 437 | const char *firstformat; | ||
| 438 | int r; | ||
| 439 | size_t i; | ||
| 440 | Res res; | ||
| 426 | 441 | ||
| 427 | /* WriteF_v -- write formatted output | 442 | firstformat = va_arg(args, const char *); |
| 428 | * | 443 | res = WriteF_firstformat_v(stream, firstformat, args); |
| 429 | * .writef.des: See <design/writef/>, also <design/lib/> | 444 | return res; |
| 430 | * | 445 | } |
| 431 | * .writef.p: There is an assumption that void * fits in Word in | ||
| 432 | * the case of $P, and unsigned long for $U and $B. This is checked in | ||
| 433 | * MPMCheck. | ||
| 434 | * | ||
| 435 | * .writef.div: Although MPS_WORD_WIDTH/4 appears three times, there | ||
| 436 | * are effectively three separate decisions to format at this width. | ||
| 437 | * | ||
| 438 | * .writef.check: See .check.writef. */ | ||
| 439 | 446 | ||
| 440 | Res WriteF_v(mps_lib_FILE *stream, va_list args) | 447 | Res WriteF_firstformat_v(mps_lib_FILE *stream, |
| 448 | const char *firstformat, va_list args) | ||
| 441 | { | 449 | { |
| 442 | const char *format; | 450 | const char *format; |
| 443 | int r; | 451 | int r; |
| @@ -445,9 +453,10 @@ Res WriteF_v(mps_lib_FILE *stream, va_list args) | |||
| 445 | Res res; | 453 | Res res; |
| 446 | 454 | ||
| 447 | AVER(stream != NULL); | 455 | AVER(stream != NULL); |
| 456 | |||
| 457 | format = firstformat; | ||
| 448 | 458 | ||
| 449 | for(;;) { | 459 | for(;;) { |
| 450 | format = va_arg(args, const char *); | ||
| 451 | if (format == NULL) | 460 | if (format == NULL) |
| 452 | break; | 461 | break; |
| 453 | 462 | ||
| @@ -534,6 +543,8 @@ Res WriteF_v(mps_lib_FILE *stream, va_list args) | |||
| 534 | 543 | ||
| 535 | ++format; | 544 | ++format; |
| 536 | } | 545 | } |
| 546 | |||
| 547 | format = va_arg(args, const char *); | ||
| 537 | } | 548 | } |
| 538 | 549 | ||
| 539 | return ResOK; | 550 | return ResOK; |
diff --git a/mps/code/mpm.h b/mps/code/mpm.h index 8c1a61617ca..02bb0659915 100644 --- a/mps/code/mpm.h +++ b/mps/code/mpm.h | |||
| @@ -144,6 +144,8 @@ extern Shift SizeFloorLog2(Size size); | |||
| 144 | 144 | ||
| 145 | extern Res WriteF(mps_lib_FILE *stream, ...); | 145 | extern Res WriteF(mps_lib_FILE *stream, ...); |
| 146 | extern Res WriteF_v(mps_lib_FILE *stream, va_list args); | 146 | extern Res WriteF_v(mps_lib_FILE *stream, va_list args); |
| 147 | extern Res WriteF_firstformat_v(mps_lib_FILE *stream, | ||
| 148 | const char *firstformat, va_list args); | ||
| 147 | 149 | ||
| 148 | 150 | ||
| 149 | /* Miscellaneous support -- see <code/mpm.c> */ | 151 | /* Miscellaneous support -- see <code/mpm.c> */ |
| @@ -953,6 +955,18 @@ extern void StackProbe(Size depth); | |||
| 953 | Bool DiagIsOn(void); | 955 | Bool DiagIsOn(void); |
| 954 | mps_lib_FILE *DiagStream(void); | 956 | mps_lib_FILE *DiagStream(void); |
| 955 | 957 | ||
| 958 | |||
| 959 | /* Diag*F functions -- formatted diagnostic output | ||
| 960 | * | ||
| 961 | * Note: do not call these directly; use the DIAG_*F macros below. | ||
| 962 | */ | ||
| 963 | |||
| 964 | extern void DiagSingleF(const char *tag, ...); | ||
| 965 | extern void DiagFirstF(const char *tag, ...); | ||
| 966 | extern void DiagMoreF(const char *format, ...); | ||
| 967 | extern void DiagEnd(const char *tag); | ||
| 968 | |||
| 969 | |||
| 956 | #if defined(DIAG_WITH_STREAM_AND_WRITEF) | 970 | #if defined(DIAG_WITH_STREAM_AND_WRITEF) |
| 957 | 971 | ||
| 958 | /* Diagnostic Calculation and Output */ | 972 | /* Diagnostic Calculation and Output */ |
| @@ -961,17 +975,36 @@ mps_lib_FILE *DiagStream(void); | |||
| 961 | #define DIAG(s) BEGIN \ | 975 | #define DIAG(s) BEGIN \ |
| 962 | s \ | 976 | s \ |
| 963 | END | 977 | END |
| 964 | /* | 978 | |
| 965 | * Note the macro argument args should have parens around it (in the | 979 | |
| 966 | * invocation); it is a variable number of arguments that we pass | 980 | /* DIAG_*F macros -- formatted diagnostic output |
| 967 | * to another function. | 981 | * |
| 968 | * That makes this macro unclean in all sorts of ways. | 982 | * Note: when invoking these macros, the value passed as macro |
| 983 | * argument "args" might contain commas; it must therefore be | ||
| 984 | * enclosed in parentheses. That makes these macros unclean in | ||
| 985 | * all sorts of ways. | ||
| 969 | */ | 986 | */ |
| 987 | |||
| 970 | #define DIAG_WRITEF(args) DIAG( \ | 988 | #define DIAG_WRITEF(args) DIAG( \ |
| 971 | if(DiagIsOn()) { \ | 989 | if(DiagIsOn()) { \ |
| 972 | WriteF args; \ | 990 | WriteF args; \ |
| 973 | } \ | 991 | } \ |
| 974 | ) | 992 | ) |
| 993 | #define DIAG_SINGLEF(args) DIAG( \ | ||
| 994 | DiagSingleF args; \ | ||
| 995 | ) | ||
| 996 | #define DIAG_FIRSTF(args) DIAG( \ | ||
| 997 | DiagFirstF args; \ | ||
| 998 | ) | ||
| 999 | #define DIAG_MOREF(args) DIAG( \ | ||
| 1000 | DiagMoreF args; \ | ||
| 1001 | ) | ||
| 1002 | |||
| 1003 | /* Note: extra parens *not* required when invoking DIAG_END */ | ||
| 1004 | #define DIAG_END(tag) DIAG( \ | ||
| 1005 | DiagEnd(tag); \ | ||
| 1006 | ) | ||
| 1007 | |||
| 975 | 1008 | ||
| 976 | #else | 1009 | #else |
| 977 | 1010 | ||
| @@ -980,6 +1013,12 @@ mps_lib_FILE *DiagStream(void); | |||
| 980 | #define DIAG(s) BEGIN END | 1013 | #define DIAG(s) BEGIN END |
| 981 | #define DIAG_WRITEF(args) BEGIN END | 1014 | #define DIAG_WRITEF(args) BEGIN END |
| 982 | 1015 | ||
| 1016 | /* DIAG_*F macros */ | ||
| 1017 | #define DIAG_SINGLEF(args) BEGIN END | ||
| 1018 | #define DIAG_FIRSTF(args) BEGIN END | ||
| 1019 | #define DIAG_MOREF(args) BEGIN END | ||
| 1020 | #define DIAG_END(tag) BEGIN END | ||
| 1021 | |||
| 983 | #endif | 1022 | #endif |
| 984 | 1023 | ||
| 985 | /* ------------ DIAG_WITH_PRINTF --------------- */ | 1024 | /* ------------ DIAG_WITH_PRINTF --------------- */ |
diff --git a/mps/code/trace.c b/mps/code/trace.c index da1952a5c37..d4ad1d25903 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c | |||
| @@ -1903,14 +1903,14 @@ void TraceStart(Trace trace, double mortality, double finishingTime) | |||
| 1903 | } while (SegNext(&seg, arena, base)); | 1903 | } while (SegNext(&seg, arena, base)); |
| 1904 | } | 1904 | } |
| 1905 | 1905 | ||
| 1906 | DIAG_WRITEF(( DIAG_STREAM, | 1906 | DIAG_FIRSTF(( "TraceStart", |
| 1907 | "MPS: TraceStart, because code $U: $S\n", | 1907 | "because code $U: $S\n", |
| 1908 | trace->why, traceStartWhyToString(trace->why), | 1908 | trace->why, traceStartWhyToString(trace->why), |
| 1909 | NULL )); | 1909 | NULL )); |
| 1910 | 1910 | ||
| 1911 | DIAG( ArenaDescribe(arena, DIAG_STREAM); ); | 1911 | DIAG( ArenaDescribe(arena, DIAG_STREAM); ); |
| 1912 | 1912 | ||
| 1913 | DIAG_WRITEF(( DIAG_STREAM, | 1913 | DIAG_MOREF(( |
| 1914 | "MPS: white set:$B\n", | 1914 | "MPS: white set:$B\n", |
| 1915 | trace->white, | 1915 | trace->white, |
| 1916 | NULL )); | 1916 | NULL )); |
| @@ -1940,6 +1940,8 @@ void TraceStart(Trace trace, double mortality, double finishingTime) | |||
| 1940 | NULL )); | 1940 | NULL )); |
| 1941 | TraceStartGenDesc_diag(&arena->topGen, -1); | 1941 | TraceStartGenDesc_diag(&arena->topGen, -1); |
| 1942 | } | 1942 | } |
| 1943 | |||
| 1944 | DIAG_END( "TraceStart" ); | ||
| 1943 | 1945 | ||
| 1944 | res = RootsIterate(ArenaGlobals(arena), rootGrey, (void *)trace); | 1946 | res = RootsIterate(ArenaGlobals(arena), rootGrey, (void *)trace); |
| 1945 | AVER(res == ResOK); | 1947 | AVER(res == ResOK); |