aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Kistruck2007-08-07 19:09:43 +0100
committerRichard Kistruck2007-08-07 19:09:43 +0100
commit5cbd84f9b46384ee08da255db816a0971fd5bf3f (patch)
treeab667435bae3f2b2659fcc561f0473e24cf7bc9f
parent5a478d9a7d637d87a07625ad1c37bac5c3633573 (diff)
downloademacs-5cbd84f9b46384ee08da255db816a0971fd5bf3f.tar.gz
emacs-5cbd84f9b46384ee08da255db816a0971fd5bf3f.zip
Mps br/diagtag:
diag.c: support tagging of diagnostics, and avoid having to say DIAG_STREAM every time, with new macros: DIAG_SINGLEF, DIAG_FIRSTF, DIAG_MOREF, DIAG_END. mpm.c: new WriteF_firstformat_v required by DIAG_MOREF. Copied from Perforce Change: 163059 ServerID: perforce.ravenbrook.com
-rw-r--r--mps/code/diag.c86
-rw-r--r--mps/code/mpm.c41
-rw-r--r--mps/code/mpm.h49
-rw-r--r--mps/code/trace.c8
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
31const char *DiagTagGlobal = NULL;
32
33static 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
43static 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
54void 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
69void 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
82void 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
98void DiagEnd(const char *tag)
99{
100 DiagTagEnd(tag);
101}
102
103extern void diag_test(void);
104
105void 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
415Res WriteF(mps_lib_FILE *stream, ...) 424Res 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
435Res 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
440Res WriteF_v(mps_lib_FILE *stream, va_list args) 447Res 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
145extern Res WriteF(mps_lib_FILE *stream, ...); 145extern Res WriteF(mps_lib_FILE *stream, ...);
146extern Res WriteF_v(mps_lib_FILE *stream, va_list args); 146extern Res WriteF_v(mps_lib_FILE *stream, va_list args);
147extern 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);
953Bool DiagIsOn(void); 955Bool DiagIsOn(void);
954mps_lib_FILE *DiagStream(void); 956mps_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
964extern void DiagSingleF(const char *tag, ...);
965extern void DiagFirstF(const char *tag, ...);
966extern void DiagMoreF(const char *format, ...);
967extern 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);