Module: Mesa
Branch: main
Commit: 7b5b1642815dc7e74a7f90d89a7d46fde4ace19a
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=7b5b1642815dc7e74a7f90d89a7d46fde4ace19a

Author: Caio Oliveira <[email protected]>
Date:   Mon Sep 18 14:55:58 2023 -0700

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 <[email protected]>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25482>

---

 src/util/ralloc.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/util/ralloc.h |   6 +++
 2 files changed, 124 insertions(+)

diff --git a/src/util/ralloc.c b/src/util/ralloc.c
index 1625744c043..4dfc6f27b3d 100644
--- a/src/util/ralloc.c
+++ b/src/util/ralloc.c
@@ -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");
+}
+
diff --git a/src/util/ralloc.h b/src/util/ralloc.h
index a20d8e35103..58d851f1823 100644
--- a/src/util/ralloc.h
+++ b/src/util/ralloc.h
@@ -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

Reply via email to