util: Add function print information about a ralloc tree

In release mode print the ralloc tree header pointers.  In debug mode,
will look at the child allocations recursively checking for the canary
values.  In most cases this should work and give us extra information
about the type of the subtree (GC, Linear) and the allocation sizes.

For example, calling it at the end of spirv_to_nir() will output the
following tree with a summary at the end (lines elided to focus on the
general structure of the output)

```
0xca8d00 (472 bytes)
  0xdf2c60 (32 bytes)
  0xdf2c00 (32 bytes)
  0xdf2ba0 (32 bytes)
  0xdf2b40 (32 bytes)
  (...)
  0xcde8b0 (64 bytes)
  0xcde760 (72 bytes)
    0xd2de40 (168 bytes)
  0xcce660 (64 bytes)
  0xcce510 (72 bytes)
    0xcce5a0 (120 bytes)
  0xcce490 (64 bytes)
  (...)
  0xcbc450 (456 bytes)
    0xdf55c0 (160 bytes)
      0xdf5730 (72 bytes)
        0xdf57c0 (80 bytes)
      0xdf5530 (72 bytes)
        0xdf56a0 (80 bytes)
    (...)
    0xcbe840 (128 bytes)
      0xcc4310 (4 bytes)
    0xcbc660 (536 bytes) (gc context)
      0xde6b40 (32576 bytes) (gc slab or large block)
      0xddb160 (32704 bytes) (gc slab or large block)
      0xdc8d50 (32704 bytes) (gc slab or large block)
      (...)
      0xcde9a0 (32704 bytes) (gc slab or large block)
      0xcd6720 (32704 bytes) (gc slab or large block)
      0xcce6e0 (32768 bytes) (gc slab or large block)
  0xcbc330 (72 bytes)
    0xd680a0 (208 bytes)
  0xca9010 (78560 bytes)
  0xca8f20 (176 bytes)

==== RALLOC INFO ptr=0xca8d30 info=0xca8d00
ralloc allocations    = 4714
  - linear            = 0
  - gc                = 23
  - other             = 4691
content bytes         = 1055139
ralloc metadata bytes = 226272
linear metadata bytes = 0
====
```

There's a flag to pass so only the summary at the end is printed.

Acked-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25482>
This commit is contained in:
Caio Oliveira
2023-09-18 14:55:58 -07:00
committed by Marge Bot
parent 5b767c890f
commit 7b5b164281
2 changed files with 124 additions and 0 deletions

View File

@@ -1276,3 +1276,121 @@ linear_zalloc_child_array(linear_ctx *ctx, size_t size, unsigned count)
return linear_zalloc_child(ctx, size * count);
}
typedef struct {
FILE *f;
unsigned indent;
unsigned ralloc_count;
unsigned linear_count;
unsigned gc_count;
/* These don't include padding or metadata from suballocators. */
unsigned content_bytes;
unsigned ralloc_metadata_bytes;
unsigned linear_metadata_bytes;
unsigned gc_metadata_bytes;
bool inside_linear;
bool inside_gc;
} ralloc_print_info_state;
static void
ralloc_print_info_helper(ralloc_print_info_state *state, const ralloc_header *info)
{
FILE *f = state->f;
if (f) {
for (unsigned i = 0; i < state->indent; i++) fputc(' ', f);
fprintf(f, "%p", info);
}
/* TODO: Account for padding used in various places. */
#ifndef NDEBUG
assert(info->canary == CANARY);
if (f) fprintf(f, " (%d bytes)", info->size);
state->content_bytes += info->size;
state->ralloc_metadata_bytes += sizeof(ralloc_header);
const void *ptr = PTR_FROM_HEADER(info);
const linear_ctx *lin_ctx = ptr;
const gc_ctx *gc_ctx = ptr;
if (lin_ctx->magic == LMAGIC_CONTEXT) {
if (f) fprintf(f, " (linear context)");
assert(!state->inside_gc && !state->inside_linear);
state->inside_linear = true;
state->linear_metadata_bytes += sizeof(linear_ctx);
state->content_bytes -= sizeof(linear_ctx);
state->linear_count++;
} else if (gc_ctx->canary == GC_CONTEXT_CANARY) {
if (f) fprintf(f, " (gc context)");
assert(!state->inside_gc && !state->inside_linear);
state->inside_gc = true;
state->gc_metadata_bytes += sizeof(gc_block_header);
} else if (state->inside_linear) {
const linear_node_canary *lin_node = ptr;
if (lin_node->magic == LMAGIC_NODE) {
if (f) fprintf(f, " (linear node buffer)");
state->content_bytes -= sizeof(linear_node_canary);
state->linear_metadata_bytes += sizeof(linear_node_canary);
state->linear_count++;
}
} else if (state->inside_gc) {
if (f) fprintf(f, " (gc slab or large block)");
state->gc_count++;
}
#endif
state->ralloc_count++;
if (f) fprintf(f, "\n");
const ralloc_header *c = info->child;
state->indent += 2;
while (c != NULL) {
ralloc_print_info_helper(state, c);
c = c->next;
}
state->indent -= 2;
#ifndef NDEBUG
if (lin_ctx->magic == LMAGIC_CONTEXT) state->inside_linear = false;
else if (gc_ctx->canary == GC_CONTEXT_CANARY) state->inside_gc = false;
#endif
}
void
ralloc_print_info(FILE *f, const void *p, unsigned flags)
{
ralloc_print_info_state state = {
.f = ((flags & RALLOC_PRINT_INFO_SUMMARY_ONLY) == 1) ? NULL : f,
};
const ralloc_header *info = get_header(p);
ralloc_print_info_helper(&state, info);
fprintf(f, "==== RALLOC INFO ptr=%p info=%p\n"
"ralloc allocations = %d\n"
" - linear = %d\n"
" - gc = %d\n"
" - other = %d\n",
p, info,
state.ralloc_count,
state.linear_count,
state.gc_count,
state.ralloc_count - state.linear_count - state.gc_count);
if (state.content_bytes) {
fprintf(f,
"content bytes = %d\n"
"ralloc metadata bytes = %d\n"
"linear metadata bytes = %d\n",
state.content_bytes,
state.ralloc_metadata_bytes,
state.linear_metadata_bytes);
}
fprintf(f, "====\n");
}

View File

@@ -700,6 +700,12 @@ bool linear_strcat(linear_ctx *ctx, char **dest, const char *str);
#define linear_zalloc_array(ctx, type, count) \
((type *) linear_zalloc_child_array(ctx, sizeof(type), count))
enum {
RALLOC_PRINT_INFO_SUMMARY_ONLY = 1 << 0,
};
void ralloc_print_info(FILE *f, const void *p, unsigned flags);
#ifdef __cplusplus
} /* end of extern "C" */
#endif