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 = [
dependency('gio-2.0', version: glib_req_version),
dependency('gtk4', version: gtk_req_version),
libsysprof_capture_deps,
]

View File

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

View File

@ -20,7 +20,9 @@
#include "config.h"
#include "sysprof-document-private.h"
#include "sysprof-document-symbols-private.h"
#include "sysprof-document-traceable.h"
#include "sysprof-symbolizer-private.h"
struct _SysprofDocumentSymbols
@ -72,6 +74,10 @@ sysprof_document_symbols_worker (GTask *task,
GCancellable *cancellable)
{
Symbolize *state = task_data;
GtkBitsetIter iter;
GtkBitset *bitset;
GListModel *model;
guint i;
g_assert (source_object == NULL);
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_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_IO_ERROR,
G_IO_ERROR_NOT_SUPPORTED,

View File

@ -24,7 +24,7 @@
#include <glib/gstdio.h>
#include "sysprof-document.h"
#include "sysprof-document-private.h"
#include "sysprof-document-frame-private.h"
#include "sysprof-document-symbols-private.h"
#include "sysprof-symbolizer-private.h"
@ -37,6 +37,8 @@ struct _SysprofDocument
GMappedFile *mapped_file;
const guint8 *base;
GtkBitset *samples;
GMutex strings_mutex;
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->frames, g_array_unref);
g_clear_pointer (&self->strings, g_hash_table_unref);
g_clear_pointer (&self->samples, gtk_bitset_unref);
g_mutex_clear (&self->strings_mutex);
@ -115,10 +118,12 @@ sysprof_document_class_init (SysprofDocumentClass *klass)
static void
sysprof_document_init (SysprofDocument *self)
{
g_mutex_init (&self->strings_mutex);
self->frames = g_array_new (FALSE, FALSE, sizeof (SysprofDocumentFramePointer));
self->strings = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
(GDestroyNotify)g_ref_string_release);
g_mutex_init (&self->strings_mutex);
self->samples = gtk_bitset_new_empty ();
}
static gboolean
@ -158,6 +163,7 @@ sysprof_document_load (SysprofDocument *self,
pos = sizeof self->header;
while (pos < (len - sizeof(guint16)))
{
const SysprofCaptureFrame *tainted;
SysprofDocumentFramePointer ptr;
guint16 frame_len;
@ -170,9 +176,15 @@ sysprof_document_load (SysprofDocument *self,
ptr.offset = pos;
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;
g_array_append_val (self->frames, ptr);
}
return TRUE;
@ -490,3 +502,11 @@ sysprof_document_lookup_file_finish (SysprofDocument *self,
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;
}