diff options
| author | Richard Brooksby | 2012-08-31 14:12:23 +0100 |
|---|---|---|
| committer | Richard Brooksby | 2012-08-31 14:12:23 +0100 |
| commit | 09dc2bca88079b32d042061b3f1ec51b0083cc6e (patch) | |
| tree | 1684bf03428346059cd777e04faadc5d1e903a30 /mps/code | |
| parent | a7a9ed15ff91778f01d6884ef40a97443f7417a1 (diff) | |
| download | emacs-09dc2bca88079b32d042061b3f1ec51b0083cc6e.tar.gz emacs-09dc2bca88079b32d042061b3f1ec51b0083cc6e.zip | |
Writing event dumper to print recent events, and adding it to the default assertion handler.
NUL-terminating event strings to make them easier to print.
Copied from Perforce
Change: 179132
ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code')
| -rw-r--r-- | mps/code/event.c | 56 | ||||
| -rw-r--r-- | mps/code/event.h | 7 | ||||
| -rw-r--r-- | mps/code/eventcom.h | 9 | ||||
| -rw-r--r-- | mps/code/mpsliban.c | 4 | ||||
| -rw-r--r-- | mps/code/trace.c | 2 |
5 files changed, 74 insertions, 4 deletions
diff --git a/mps/code/event.c b/mps/code/event.c index d3ea72277fc..4a3c7b1a457 100644 --- a/mps/code/event.c +++ b/mps/code/event.c | |||
| @@ -48,6 +48,8 @@ Res EventFlush(void) | |||
| 48 | Res res; | 48 | Res res; |
| 49 | size_t size; | 49 | size_t size; |
| 50 | 50 | ||
| 51 | EventDump(mps_lib_get_stdout()); | ||
| 52 | |||
| 51 | AVER(eventInited); | 53 | AVER(eventInited); |
| 52 | 54 | ||
| 53 | AVER(EventBuffer <= EventLast); | 55 | AVER(EventBuffer <= EventLast); |
| @@ -112,7 +114,9 @@ Res EventInit(void) | |||
| 112 | #define EVENT_PARAM_CHECK_B(name, index, ident) | 114 | #define EVENT_PARAM_CHECK_B(name, index, ident) |
| 113 | #define EVENT_PARAM_CHECK_S(name, index, ident) \ | 115 | #define EVENT_PARAM_CHECK_S(name, index, ident) \ |
| 114 | AVER(index + 1 == Event##name##ParamLIMIT); /* strings must come last */ \ | 116 | AVER(index + 1 == Event##name##ParamLIMIT); /* strings must come last */ \ |
| 115 | AVER(offsetof(Event##name##Struct, f##index.str) + EventStringLengthMAX \ | 117 | AVER(offsetof(Event##name##Struct, f##index.str) \ |
| 118 | + EventStringLengthMAX \ | ||
| 119 | + sizeof('\0') \ | ||
| 116 | <= EventSizeMAX); | 120 | <= EventSizeMAX); |
| 117 | 121 | ||
| 118 | #define EVENT_PARAM_CHECK(name, index, sort, ident) \ | 122 | #define EVENT_PARAM_CHECK(name, index, sort, ident) \ |
| @@ -231,6 +235,50 @@ void EventLabelAddr(Addr addr, EventStringId id) | |||
| 231 | } | 235 | } |
| 232 | 236 | ||
| 233 | 237 | ||
| 238 | void EventDump(mps_lib_FILE *stream) | ||
| 239 | { | ||
| 240 | Event event; | ||
| 241 | |||
| 242 | AVER(stream != NULL); | ||
| 243 | |||
| 244 | for (event = (Event)EventLast; | ||
| 245 | event < (Event)(EventBuffer + EventBufferSIZE); | ||
| 246 | event = (Event)((char *)event + event->any.size)) { | ||
| 247 | EVENT_CLOCK_WRITE(stream, event->any.clock); | ||
| 248 | |||
| 249 | switch (event->any.code) { | ||
| 250 | |||
| 251 | #define EVENT_DUMP_PARAM_MOST(name, index, sort, ident) \ | ||
| 252 | " $"#sort, (WriteF##sort)event->name.f##index, | ||
| 253 | #define EVENT_DUMP_PARAM_A EVENT_DUMP_PARAM_MOST | ||
| 254 | #define EVENT_DUMP_PARAM_P EVENT_DUMP_PARAM_MOST | ||
| 255 | #define EVENT_DUMP_PARAM_U EVENT_DUMP_PARAM_MOST | ||
| 256 | #define EVENT_DUMP_PARAM_W EVENT_DUMP_PARAM_MOST | ||
| 257 | #define EVENT_DUMP_PARAM_D EVENT_DUMP_PARAM_MOST | ||
| 258 | #define EVENT_DUMP_PARAM_B(name, index, sort, ident) \ | ||
| 259 | " $U", (WriteFU)event->name.f##index, | ||
| 260 | #define EVENT_DUMP_PARAM_S(name, index, sort, ident) \ | ||
| 261 | " $S", (WriteFS)event->name.f##index.str, /* FIXME: relies on NUL? */ | ||
| 262 | #define EVENT_DUMP_PARAM(name, index, sort, ident) \ | ||
| 263 | EVENT_DUMP_PARAM_##sort(name, index, sort, ident) | ||
| 264 | #define EVENT_DUMP(X, name, code, always, kind) \ | ||
| 265 | case code: \ | ||
| 266 | WriteF(stream, " "#name, \ | ||
| 267 | EVENT_##name##_PARAMS(EVENT_DUMP_PARAM, name) \ | ||
| 268 | NULL); \ | ||
| 269 | break; | ||
| 270 | EVENT_LIST(EVENT_DUMP, X) | ||
| 271 | |||
| 272 | default: | ||
| 273 | WriteF(stream, " <unknown code $U>", event->any.code, NULL); | ||
| 274 | /* FIXME: Should dump contents in hex. */ | ||
| 275 | break; | ||
| 276 | } | ||
| 277 | WriteF(stream, "\n", NULL); | ||
| 278 | } | ||
| 279 | } | ||
| 280 | |||
| 281 | |||
| 234 | #else /* EVENT, not */ | 282 | #else /* EVENT, not */ |
| 235 | 283 | ||
| 236 | 284 | ||
| @@ -285,6 +333,12 @@ void (EventLabelAddr)(Addr addr, Word id) | |||
| 285 | } | 333 | } |
| 286 | 334 | ||
| 287 | 335 | ||
| 336 | extern void EventDump(mps_lib_FILE *stream) | ||
| 337 | { | ||
| 338 | UNUSED(stream); | ||
| 339 | } | ||
| 340 | |||
| 341 | |||
| 288 | #endif /* EVENT */ | 342 | #endif /* EVENT */ |
| 289 | 343 | ||
| 290 | 344 | ||
diff --git a/mps/code/event.h b/mps/code/event.h index d4c2ce83b95..1265aa22d19 100644 --- a/mps/code/event.h +++ b/mps/code/event.h | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include "eventcom.h" | 18 | #include "eventcom.h" |
| 19 | #include "mpm.h" | 19 | #include "mpm.h" |
| 20 | #include "eventdef.h" | 20 | #include "eventdef.h" |
| 21 | #include "mpslib.h" | ||
| 21 | 22 | ||
| 22 | 23 | ||
| 23 | typedef Word EventStringId; | 24 | typedef Word EventStringId; |
| @@ -32,6 +33,7 @@ extern EventStringId EventInternString(const char *label); | |||
| 32 | extern EventStringId EventInternGenString(size_t, const char *label); | 33 | extern EventStringId EventInternGenString(size_t, const char *label); |
| 33 | extern void EventLabelAddr(Addr addr, Word id); | 34 | extern void EventLabelAddr(Addr addr, Word id); |
| 34 | extern Res EventFlush(void); | 35 | extern Res EventFlush(void); |
| 36 | extern void EventDump(mps_lib_FILE *stream); | ||
| 35 | 37 | ||
| 36 | 38 | ||
| 37 | #ifdef EVENT | 39 | #ifdef EVENT |
| @@ -78,12 +80,13 @@ extern Word EventKindControl; | |||
| 78 | BEGIN \ | 80 | BEGIN \ |
| 79 | size_t _string_len = (length); \ | 81 | size_t _string_len = (length); \ |
| 80 | size_t size; \ | 82 | size_t size; \ |
| 81 | size = offsetof(Event##name##Struct, f1.str) + _string_len; \ | 83 | size = offsetof(Event##name##Struct, f1.str) + _string_len + sizeof('\0'); \ |
| 82 | EVENT_BEGIN(name, size) \ | 84 | EVENT_BEGIN(name, size) \ |
| 83 | _event->f0 = (p0); \ | 85 | _event->f0 = (p0); \ |
| 84 | AVER(_string_len < EventStringLengthMAX); \ | 86 | AVER(_string_len <= EventStringLengthMAX); \ |
| 85 | _event->f1.len = (EventStringLen)_string_len; \ | 87 | _event->f1.len = (EventStringLen)_string_len; \ |
| 86 | mps_lib_memcpy(_event->f1.str, (string), _string_len); \ | 88 | mps_lib_memcpy(_event->f1.str, (string), _string_len); \ |
| 89 | _event->f1.str[_string_len] = '\0'; \ | ||
| 87 | EVENT_END(name, size); \ | 90 | EVENT_END(name, size); \ |
| 88 | END | 91 | END |
| 89 | 92 | ||
diff --git a/mps/code/eventcom.h b/mps/code/eventcom.h index d572c56bdc8..89b216132b1 100644 --- a/mps/code/eventcom.h +++ b/mps/code/eventcom.h | |||
| @@ -33,6 +33,12 @@ typedef unsigned __int64 EventClock; | |||
| 33 | END | 33 | END |
| 34 | 34 | ||
| 35 | #define EVENT_CLOCK_PRINT(stream, clock) fprintf(stream, "%llu", clock) | 35 | #define EVENT_CLOCK_PRINT(stream, clock) fprintf(stream, "%llu", clock) |
| 36 | #if defined(MPS_ARCH_I3) | ||
| 37 | #define EVENT_CLOCK_WRITE(stream, clock) \ | ||
| 38 | WriteF(stream, "$W$W", (WriteFW)((clock) >> 32), (WriteFW)clock, NULL) | ||
| 39 | #else /* I6 */ | ||
| 40 | WriteF(stream, "$W", (WriteFW)(clock), NULL) | ||
| 41 | #endif | ||
| 36 | 42 | ||
| 37 | /* http://clang.llvm.org/docs/LanguageExtensions.html#builtins */ | 43 | /* http://clang.llvm.org/docs/LanguageExtensions.html#builtins */ |
| 38 | #elif defined(MPS_BUILD_LL) | 44 | #elif defined(MPS_BUILD_LL) |
| @@ -72,6 +78,9 @@ __extension__ typedef unsigned long long EventClock; | |||
| 72 | (unsigned long)((clock) >> 32), \ | 78 | (unsigned long)((clock) >> 32), \ |
| 73 | (unsigned long)(clock)) | 79 | (unsigned long)(clock)) |
| 74 | 80 | ||
| 81 | #define EVENT_CLOCK_WRITE(stream, clock) \ | ||
| 82 | WriteF(stream, "$W$W", (WriteFW)((clock) >> 32), (WriteFW)clock, NULL) | ||
| 83 | |||
| 75 | #endif /* Intel, GCC or Clang */ | 84 | #endif /* Intel, GCC or Clang */ |
| 76 | 85 | ||
| 77 | /* no fast clock, use plinth, probably from the C library */ | 86 | /* no fast clock, use plinth, probably from the C library */ |
diff --git a/mps/code/mpsliban.c b/mps/code/mpsliban.c index 8b44f684a8c..d56073976e9 100644 --- a/mps/code/mpsliban.c +++ b/mps/code/mpsliban.c | |||
| @@ -25,6 +25,7 @@ | |||
| 25 | #include "mpslib.h" | 25 | #include "mpslib.h" |
| 26 | 26 | ||
| 27 | #include "mpstd.h" | 27 | #include "mpstd.h" |
| 28 | #include "event.h" | ||
| 28 | 29 | ||
| 29 | #ifdef MPS_OS_XC | 30 | #ifdef MPS_OS_XC |
| 30 | #include "osxc.h" | 31 | #include "osxc.h" |
| @@ -66,7 +67,8 @@ int mps_lib_fputs(const char *s, mps_lib_FILE *stream) | |||
| 66 | void mps_lib_assert_fail(const char *message) | 67 | void mps_lib_assert_fail(const char *message) |
| 67 | { | 68 | { |
| 68 | fflush(stdout); /* synchronize */ | 69 | fflush(stdout); /* synchronize */ |
| 69 | fprintf(stderr, "\nMPS ASSERTION FAILURE: %s\n", message); | 70 | fprintf(stderr, "\nMPS ASSERTION FAILURE: %s\n\nRECENT EVENTS:\n", message); |
| 71 | EventDump((mps_lib_FILE *)stderr); | ||
| 70 | fflush(stderr); /* make sure the message is output */ | 72 | fflush(stderr); /* make sure the message is output */ |
| 71 | abort(); | 73 | abort(); |
| 72 | } | 74 | } |
diff --git a/mps/code/trace.c b/mps/code/trace.c index c362a4809cf..d5aff875030 100644 --- a/mps/code/trace.c +++ b/mps/code/trace.c | |||
| @@ -814,6 +814,8 @@ static void traceReclaim(Trace trace) | |||
| 814 | PoolTraceEnd(pool, trace); | 814 | PoolTraceEnd(pool, trace); |
| 815 | } | 815 | } |
| 816 | 816 | ||
| 817 | NOTREACHED; | ||
| 818 | |||
| 817 | ArenaCompact(arena, trace); /* let arenavm drop chunks */ | 819 | ArenaCompact(arena, trace); /* let arenavm drop chunks */ |
| 818 | 820 | ||
| 819 | TracePostMessage(trace); /* trace end */ | 821 | TracePostMessage(trace); /* trace end */ |