libsysprof-analyze: index traceables for faster access

This allows us to skip past all the nodes we don't care about with
relatively low overhead once the document has been generated.
This commit is contained in:
Christian Hergert
2023-05-03 17:44:15 -07:00
parent b72eda6be2
commit 10c332d5d2
4 changed files with 52 additions and 6 deletions

View File

@ -43,6 +43,8 @@ libsysprof_analyze_public_headers = [
libsysprof_analyze_deps = [ libsysprof_analyze_deps = [
dependency('gio-2.0', version: glib_req_version), dependency('gio-2.0', version: glib_req_version),
dependency('gtk4', version: gtk_req_version),
libsysprof_capture_deps, libsysprof_capture_deps,
] ]

View File

@ -20,12 +20,15 @@
#pragma once #pragma once
#include <gtk/gtk.h>
#include "sysprof-document.h" #include "sysprof-document.h"
G_BEGIN_DECLS G_BEGIN_DECLS
gboolean _sysprof_document_is_native (SysprofDocument *self); gboolean _sysprof_document_is_native (SysprofDocument *self);
char *_sysprof_document_ref_string (SysprofDocument *self, char *_sysprof_document_ref_string (SysprofDocument *self,
const char *name); const char *name);
GtkBitset *_sysprof_document_samples (SysprofDocument *self);
G_END_DECLS G_END_DECLS

View File

@ -20,7 +20,9 @@
#include "config.h" #include "config.h"
#include "sysprof-document-private.h"
#include "sysprof-document-symbols-private.h" #include "sysprof-document-symbols-private.h"
#include "sysprof-document-traceable.h"
#include "sysprof-symbolizer-private.h" #include "sysprof-symbolizer-private.h"
struct _SysprofDocumentSymbols struct _SysprofDocumentSymbols
@ -72,6 +74,10 @@ sysprof_document_symbols_worker (GTask *task,
GCancellable *cancellable) GCancellable *cancellable)
{ {
Symbolize *state = task_data; Symbolize *state = task_data;
GtkBitsetIter iter;
GtkBitset *bitset;
GListModel *model;
guint i;
g_assert (source_object == NULL); g_assert (source_object == NULL);
g_assert (G_IS_TASK (task)); g_assert (G_IS_TASK (task));
@ -81,6 +87,21 @@ sysprof_document_symbols_worker (GTask *task,
g_assert (SYSPROF_IS_SYMBOLIZER (state->symbolizer)); g_assert (SYSPROF_IS_SYMBOLIZER (state->symbolizer));
g_assert (SYSPROF_IS_DOCUMENT_SYMBOLS (state->symbols)); g_assert (SYSPROF_IS_DOCUMENT_SYMBOLS (state->symbols));
bitset = _sysprof_document_samples (state->document);
model = G_LIST_MODEL (state->document);
if (gtk_bitset_iter_init_first (&iter, bitset, &i))
{
do
{
g_autoptr(SysprofDocumentTraceable) traceable = g_list_model_get_item (model, i);
if (!SYSPROF_IS_DOCUMENT_TRACEABLE (traceable))
continue;
}
while (gtk_bitset_iter_next (&iter, &i));
}
g_task_return_new_error (task, g_task_return_new_error (task,
G_IO_ERROR, G_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED, G_IO_ERROR_NOT_SUPPORTED,

View File

@ -24,7 +24,7 @@
#include <glib/gstdio.h> #include <glib/gstdio.h>
#include "sysprof-document.h" #include "sysprof-document-private.h"
#include "sysprof-document-frame-private.h" #include "sysprof-document-frame-private.h"
#include "sysprof-document-symbols-private.h" #include "sysprof-document-symbols-private.h"
#include "sysprof-symbolizer-private.h" #include "sysprof-symbolizer-private.h"
@ -37,6 +37,8 @@ struct _SysprofDocument
GMappedFile *mapped_file; GMappedFile *mapped_file;
const guint8 *base; const guint8 *base;
GtkBitset *samples;
GMutex strings_mutex; GMutex strings_mutex;
GHashTable *strings; GHashTable *strings;
@ -99,6 +101,7 @@ sysprof_document_finalize (GObject *object)
g_clear_pointer (&self->mapped_file, g_mapped_file_unref); g_clear_pointer (&self->mapped_file, g_mapped_file_unref);
g_clear_pointer (&self->frames, g_array_unref); g_clear_pointer (&self->frames, g_array_unref);
g_clear_pointer (&self->strings, g_hash_table_unref); g_clear_pointer (&self->strings, g_hash_table_unref);
g_clear_pointer (&self->samples, gtk_bitset_unref);
g_mutex_clear (&self->strings_mutex); g_mutex_clear (&self->strings_mutex);
@ -115,10 +118,12 @@ sysprof_document_class_init (SysprofDocumentClass *klass)
static void static void
sysprof_document_init (SysprofDocument *self) sysprof_document_init (SysprofDocument *self)
{ {
g_mutex_init (&self->strings_mutex);
self->frames = g_array_new (FALSE, FALSE, sizeof (SysprofDocumentFramePointer)); self->frames = g_array_new (FALSE, FALSE, sizeof (SysprofDocumentFramePointer));
self->strings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, self->strings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
(GDestroyNotify)g_ref_string_release); (GDestroyNotify)g_ref_string_release);
g_mutex_init (&self->strings_mutex); self->samples = gtk_bitset_new_empty ();
} }
static gboolean static gboolean
@ -158,6 +163,7 @@ sysprof_document_load (SysprofDocument *self,
pos = sizeof self->header; pos = sizeof self->header;
while (pos < (len - sizeof(guint16))) while (pos < (len - sizeof(guint16)))
{ {
const SysprofCaptureFrame *tainted;
SysprofDocumentFramePointer ptr; SysprofDocumentFramePointer ptr;
guint16 frame_len; guint16 frame_len;
@ -170,9 +176,15 @@ sysprof_document_load (SysprofDocument *self,
ptr.offset = pos; ptr.offset = pos;
ptr.length = frame_len; ptr.length = frame_len;
g_array_append_val (self->frames, ptr);
tainted = (const SysprofCaptureFrame *)(gpointer)&self->base[pos];
if (tainted->type == SYSPROF_CAPTURE_FRAME_SAMPLE ||
tainted->type == SYSPROF_CAPTURE_FRAME_ALLOCATION)
gtk_bitset_add (self->samples, self->frames->len);
pos += frame_len; pos += frame_len;
g_array_append_val (self->frames, ptr);
} }
return TRUE; return TRUE;
@ -490,3 +502,11 @@ sysprof_document_lookup_file_finish (SysprofDocument *self,
return g_task_propagate_pointer (G_TASK (result), error); return g_task_propagate_pointer (G_TASK (result), error);
} }
GtkBitset *
_sysprof_document_samples (SysprofDocument *self)
{
g_return_val_if_fail (SYSPROF_IS_DOCUMENT (self), NULL);
return self->samples;
}