void display_integer (int integer, mps_lib_FILE *stream) { /* This is naieve. Assume no more than 7 digits */ int remainder = integer; int leading = 1; int power; if (integer == 0) { /* special case needs the leading zero */ mps_lib_fputs(" 0", stream); return; } for (power = 10000000; power > 0; power = power / 10) { int exponent = (int)(log10(power)); int digit = remainder / power; remainder = remainder % power; if (digit == 0) { mps_lib_fputc(leading ? ' ' : '0', stream); } else { leading = 0; mps_lib_fputc('0' + digit, stream); }; if ((exponent == 6) || (exponent == 3)) if (digit == 0) { mps_lib_fputc(leading ? ' ' : ',', stream); } else mps_lib_fputc(',', stream); } }
void display_stat_line (char *message, int count, int size, mps_lib_FILE *stream) { mps_lib_fputs_(message, class_name_size, stream); display_padding_for_string(message, ' ', class_name_size, stream); display_integer(count, stream); mps_lib_fputc(' ', stream); display_integer(size, stream); mps_lib_fputc('\n', stream); }
void display_padding_for_string(char *string, char pad, int field, mps_lib_FILE *stream) { int i; int padding = padding_for_string(string, field); for (i = 0; i < padding; i++) mps_lib_fputc(' ', stream); }
void report_break (char* message) { mps_lib_FILE *stream = mps_lib_get_stdout(); mps_lib_fputs("Break to debugger:\n ", stream); mps_lib_fputs(message, stream); mps_lib_fputc('\n', stream); DebugBreak(); }
void report_error (char* message) { mps_lib_FILE *stream = mps_lib_get_stderr(); mps_lib_fputs("\nError:\n", stream); mps_lib_fputs(message, stream); mps_lib_fputc('\n', stream); mps_lib_abort(); }
void display_wrapper_stats () { int largest; mps_lib_FILE *stream = mps_lib_get_stdout(); char *message = "Start of heap statistics"; mps_lib_fputc('\n', stream); mps_lib_fputs(message, stream); display_padding_for_string(message, ' ', class_name_size, stream); mps_lib_fputs(" (count) (size)", stream); mps_lib_fputs("\n\n", stream); display_totals(stream); mps_lib_fputc('\n', stream); for (largest = biggest_below_value(very_big); largest >= 0; largest = biggest_below_value(largest)) { display_wrappers_of_size(largest, stream); } mps_lib_fputs("End of heap statistics\n\n", stream); }
void display_hex_address (void *address, mps_lib_FILE *stream) { unsigned int integer = (unsigned int)address; unsigned int remainder = integer; int leading = 1; unsigned int power; for (power = 0x10000000; power > 0; power = power / 0x10) { unsigned int digit = remainder / power; remainder = remainder % power; if (digit == 0) { mps_lib_fputc(leading ? ' ' : '0', stream); } else if (digit > 9) { leading = 0; mps_lib_fputc('A' + digit - 10, stream); } else { leading = 0; mps_lib_fputc('0' + digit, stream); } } }
void display_wrapper_breakpoints() { mps_lib_FILE *stream = mps_lib_get_stdout(); if (wrapper_breaks_cursor >= 0) { int i; mps_lib_fputs("Object allocation breakpoints\n\n", stream); mps_lib_fputs(" (class-name) (count)\n\n", stream); for (i = 0; i < wrapper_breaks_cursor + 1; i++) { wrapper_stats_t wrapper_record = wrapper_breaks + i; char *class_name = class_name_from_wrapper(wrapper_record->wrapper_address); mps_lib_fputs_(class_name, class_name_size, stream); display_padding_for_string(class_name, ' ', class_name_size, stream); display_integer(wrapper_record->usage_size, stream); mps_lib_fputc('\n', stream); } } else mps_lib_fputs("No active object allocation breakpoints\n\n", stream); }
Res WriteF_firstformat_v(mps_lib_FILE *stream, const char *firstformat, va_list args) { const char *format; int r; size_t i; Res res; AVER(stream != NULL); format = firstformat; for(;;) { if (format == NULL) break; while(*format != '\0') { if (*format != '$') { r = mps_lib_fputc(*format, stream); /* Could be more efficient */ if (r == mps_lib_EOF) return ResIO; } else { ++format; AVER(*format != '\0'); switch(*format) { case 'A': { /* address */ WriteFA addr = va_arg(args, WriteFA); res = WriteULongest(stream, (ULongest)addr, 16, (sizeof(WriteFA) * CHAR_BIT + 3) / 4); if (res != ResOK) return res; } break; case 'P': { /* pointer, see .writef.p */ WriteFP p = va_arg(args, WriteFP); res = WriteULongest(stream, (ULongest)p, 16, (sizeof(WriteFP) * CHAR_BIT + 3)/ 4); if (res != ResOK) return res; } break; case 'F': { /* function */ WriteFF f = va_arg(args, WriteFF); Byte *b = (Byte *)&f; /* ISO C forbits casting function pointers to integer, so decode bytes (see design.writef.f). TODO: Be smarter about endianness. */ for(i=0; i < sizeof(WriteFF); i++) { res = WriteULongest(stream, (ULongest)(b[i]), 16, (CHAR_BIT + 3) / 4); if (res != ResOK) return res; } } break; case 'S': { /* string */ WriteFS s = va_arg(args, WriteFS); r = mps_lib_fputs((const char *)s, stream); if (r == mps_lib_EOF) return ResIO; } break; case 'C': { /* character */ WriteFC c = va_arg(args, WriteFC); /* promoted */ r = mps_lib_fputc((int)c, stream); if (r == mps_lib_EOF) return ResIO; } break; case 'W': { /* word */ WriteFW w = va_arg(args, WriteFW); res = WriteULongest(stream, (ULongest)w, 16, (sizeof(WriteFW) * CHAR_BIT + 3) / 4); if (res != ResOK) return res; } break; case 'U': { /* decimal, see .writef.p */ WriteFU u = va_arg(args, WriteFU); res = WriteULongest(stream, (ULongest)u, 10, 0); if (res != ResOK) return res; } break; case '3': { /* decimal for thousandths */ WriteFU u = va_arg(args, WriteFU); res = WriteULongest(stream, (ULongest)u, 10, 3); if (res != ResOK) return res; } break; case 'B': { /* binary, see .writef.p */ WriteFB b = va_arg(args, WriteFB); res = WriteULongest(stream, (ULongest)b, 2, sizeof(WriteFB) * CHAR_BIT); if (res != ResOK) return res; } break; case '$': { /* dollar char */ r = mps_lib_fputc('$', stream); if (r == mps_lib_EOF) return ResIO; } break; case 'D': { /* double */ WriteFD d = va_arg(args, WriteFD); res = WriteDouble(stream, d); if (res != ResOK) return res; } break; default: NOTREACHED; } } ++format; } format = va_arg(args, const char *); } return ResOK; }
Res WriteF(mps_lib_FILE *stream, ...) { const char *format; int r; size_t i; Res res; va_list args; AVER(stream != NULL); va_start(args, stream); for(;;) { format = va_arg(args, const char *); if (format == NULL) break; while(*format != '\0') { if (*format != '$') { r = mps_lib_fputc(*format, stream); /* Could be more efficient */ if (r == mps_lib_EOF) return ResIO; } else { ++format; AVER(*format != '\0'); switch(*format) { case 'A': { /* address */ WriteFA addr = va_arg(args, WriteFA); res = WriteWord(stream, (Word)addr, 16, (sizeof(WriteFA) * CHAR_BIT + 3) / 4); if (res != ResOK) return res; } break; case 'P': { /* pointer, see .writef.p */ WriteFP p = va_arg(args, WriteFP); res = WriteWord(stream, (Word)p, 16, (sizeof(WriteFP) * CHAR_BIT + 3)/ 4); if (res != ResOK) return res; } break; case 'F': { /* function */ WriteFF f = va_arg(args, WriteFF); WriteFF *fp = &f; /* dodge to placate splint */ Byte *b = *((Byte **)&fp); for(i=0; i < sizeof(WriteFF); i++) { res = WriteWord(stream, (Word)(b[i]), 16, (CHAR_BIT + 3) / 4); if (res != ResOK) return res; } } break; case 'S': { /* string */ WriteFS s = va_arg(args, WriteFS); r = mps_lib_fputs((const char *)s, stream); if (r == mps_lib_EOF) return ResIO; } break; case 'C': { /* character */ WriteFC c = va_arg(args, WriteFC); /* promoted */ r = mps_lib_fputc((int)c, stream); if (r == mps_lib_EOF) return ResIO; } break; case 'W': { /* word */ WriteFW w = va_arg(args, WriteFW); res = WriteWord(stream, (Word)w, 16, (sizeof(WriteFW) * CHAR_BIT + 3) / 4); if (res != ResOK) return res; } break; case 'U': { /* decimal, see .writef.p */ WriteFU u = va_arg(args, WriteFU); res = WriteWord(stream, (Word)u, 10, 0); if (res != ResOK) return res; } break; case 'B': { /* binary, see .writef.p */ WriteFB b = va_arg(args, WriteFB); res = WriteWord(stream, (Word)b, 2, sizeof(WriteFB) * CHAR_BIT); if (res != ResOK) return res; } break; case '$': { /* dollar char */ r = mps_lib_fputc('$', stream); if (r == mps_lib_EOF) return ResIO; } break; case 'D': { /* double */ WriteFD d = va_arg(args, WriteFD); res = WriteDouble(stream, d); if (res != ResOK) return res; } break; default: NOTREACHED; } } ++format; } } va_end(args); return ResOK; }