mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
libsysprof-analyze: add summary augmentation capabilities
This allows us to have augmentation at the summary level so that things like the weighted callgraph or memprof callgraph can add their respective summary data up the chain of function calls.
This commit is contained in:
@ -176,7 +176,7 @@ sysprof_callgraph_frame_get_symbol (SysprofCallgraphFrame *self)
|
||||
if (self->callgraph == NULL)
|
||||
return NULL;
|
||||
|
||||
return self->node->symbol;
|
||||
return self->node->summary->symbol;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -197,3 +197,23 @@ sysprof_callgraph_frame_get_augment (SysprofCallgraphFrame *self)
|
||||
|
||||
return sysprof_callgraph_get_augment (self->callgraph, self->node);
|
||||
}
|
||||
|
||||
/**
|
||||
* sysprof_callgraph_frame_get_summary_augment: (skip)
|
||||
* @self: a #SysprofCallgraphFrame
|
||||
*
|
||||
* Gets the augmentation that was attached to the summary for
|
||||
* the callgraph node's symbol.
|
||||
*
|
||||
* Returns: (nullable) (transfer none): the augmentation data
|
||||
*/
|
||||
gpointer
|
||||
sysprof_callgraph_frame_get_summary_augment (SysprofCallgraphFrame *self)
|
||||
{
|
||||
g_return_val_if_fail (SYSPROF_IS_CALLGRAPH_FRAME (self), NULL);
|
||||
|
||||
if (self->callgraph == NULL)
|
||||
return NULL;
|
||||
|
||||
return sysprof_callgraph_get_summary_augment (self->callgraph, self->node);
|
||||
}
|
||||
|
||||
@ -25,16 +25,26 @@
|
||||
#include "sysprof-callgraph.h"
|
||||
#include "sysprof-document.h"
|
||||
|
||||
#include "eggbitset.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
typedef struct _SysprofCallgraphSummary
|
||||
{
|
||||
SysprofSymbol *symbol;
|
||||
EggBitset *traceables;
|
||||
GPtrArray *callers;
|
||||
gpointer augment;
|
||||
} SysprofCallgraphSummary;
|
||||
|
||||
struct _SysprofCallgraphNode
|
||||
{
|
||||
SysprofCallgraphNode *parent;
|
||||
SysprofCallgraphNode *prev;
|
||||
SysprofCallgraphNode *next;
|
||||
SysprofCallgraphNode *children;
|
||||
SysprofSymbol *symbol;
|
||||
gpointer augment;
|
||||
SysprofCallgraphNode *parent;
|
||||
SysprofCallgraphNode *prev;
|
||||
SysprofCallgraphNode *next;
|
||||
SysprofCallgraphNode *children;
|
||||
SysprofCallgraphSummary *summary;
|
||||
gpointer augment;
|
||||
};
|
||||
|
||||
void _sysprof_callgraph_new_async (SysprofDocument *document,
|
||||
|
||||
@ -38,8 +38,6 @@ struct _SysprofCallgraph
|
||||
SysprofDocument *document;
|
||||
GListModel *traceables;
|
||||
|
||||
SysprofSymbol *everything;
|
||||
|
||||
GHashTable *symbol_to_summary;
|
||||
|
||||
gsize augment_size;
|
||||
@ -50,13 +48,6 @@ struct _SysprofCallgraph
|
||||
SysprofCallgraphNode root;
|
||||
};
|
||||
|
||||
typedef struct _SysprofCallgraphSummary
|
||||
{
|
||||
gpointer augment;
|
||||
EggBitset *traceables;
|
||||
GPtrArray *callers;
|
||||
} SysprofCallgraphSummary;
|
||||
|
||||
static GType
|
||||
sysprof_callgraph_get_item_type (GListModel *model)
|
||||
{
|
||||
@ -92,6 +83,8 @@ list_model_iface_init (GListModelInterface *iface)
|
||||
G_DEFINE_FINAL_TYPE_WITH_CODE (SysprofCallgraph, sysprof_callgraph, G_TYPE_OBJECT,
|
||||
G_IMPLEMENT_INTERFACE (G_TYPE_LIST_MODEL, list_model_iface_init))
|
||||
|
||||
static SysprofSymbol *everything;
|
||||
|
||||
static void
|
||||
sysprof_callgraph_summary_free_all (SysprofCallgraphSummary *summary)
|
||||
{
|
||||
@ -122,6 +115,7 @@ sysprof_callgraph_get_summary (SysprofCallgraph *self,
|
||||
summary->augment = NULL;
|
||||
summary->traceables = egg_bitset_new_empty ();
|
||||
summary->callers = g_ptr_array_new ();
|
||||
summary->symbol = symbol;
|
||||
|
||||
g_hash_table_insert (self->symbol_to_summary, symbol, summary);
|
||||
}
|
||||
@ -173,7 +167,6 @@ sysprof_callgraph_finalize (GObject *object)
|
||||
|
||||
g_clear_object (&self->document);
|
||||
g_clear_object (&self->traceables);
|
||||
g_clear_object (&self->everything);
|
||||
|
||||
sysprof_callgraph_node_free (&self->root, FALSE);
|
||||
|
||||
@ -187,13 +180,13 @@ sysprof_callgraph_class_init (SysprofCallgraphClass *klass)
|
||||
|
||||
object_class->dispose = sysprof_callgraph_dispose;
|
||||
object_class->finalize = sysprof_callgraph_finalize;
|
||||
|
||||
everything = _sysprof_symbol_new (g_ref_string_new_intern ("[Everything]"), NULL, NULL, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
sysprof_callgraph_init (SysprofCallgraph *self)
|
||||
{
|
||||
self->everything = _sysprof_symbol_new (g_ref_string_new_intern ("[Everything]"), NULL, NULL, 0, 0);
|
||||
self->root.symbol = self->everything;
|
||||
}
|
||||
|
||||
static void
|
||||
@ -208,15 +201,13 @@ sysprof_callgraph_populate_callers (SysprofCallgraph *self,
|
||||
iter != NULL && iter->parent != NULL;
|
||||
iter = iter->parent)
|
||||
{
|
||||
SysprofCallgraphSummary *summary;
|
||||
SysprofSymbol *parent_symbol = iter->parent->summary->symbol;
|
||||
guint pos;
|
||||
|
||||
summary = g_hash_table_lookup (self->symbol_to_summary, iter->symbol);
|
||||
egg_bitset_add (iter->summary->traceables, list_model_index);
|
||||
|
||||
egg_bitset_add (summary->traceables, list_model_index);
|
||||
|
||||
if (!g_ptr_array_find (summary->callers, iter->parent->symbol, &pos))
|
||||
g_ptr_array_add (summary->callers, iter->parent->symbol);
|
||||
if (!g_ptr_array_find (iter->summary->callers, parent_symbol, &pos))
|
||||
g_ptr_array_add (iter->summary->callers, parent_symbol);
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,7 +221,7 @@ sysprof_callgraph_add_trace (SysprofCallgraph *self,
|
||||
|
||||
g_assert (SYSPROF_IS_CALLGRAPH (self));
|
||||
g_assert (n_symbols >= 2);
|
||||
g_assert (symbols[n_symbols-1] == self->everything);
|
||||
g_assert (symbols[n_symbols-1] == everything);
|
||||
|
||||
parent = &self->root;
|
||||
|
||||
@ -255,10 +246,11 @@ sysprof_callgraph_add_trace (SysprofCallgraph *self,
|
||||
iter = iter->next)
|
||||
{
|
||||
g_assert (iter != NULL);
|
||||
g_assert (iter->symbol != NULL);
|
||||
g_assert (iter->summary != NULL);
|
||||
g_assert (iter->summary->symbol != NULL);
|
||||
g_assert (symbol != NULL);
|
||||
|
||||
if (_sysprof_symbol_equal (iter->symbol, symbol))
|
||||
if (_sysprof_symbol_equal (iter->summary->symbol, symbol))
|
||||
{
|
||||
node = iter;
|
||||
goto next_symbol;
|
||||
@ -267,7 +259,7 @@ sysprof_callgraph_add_trace (SysprofCallgraph *self,
|
||||
|
||||
/* Otherwise create a new node */
|
||||
node = g_new0 (SysprofCallgraphNode, 1);
|
||||
node->symbol = symbol;
|
||||
node->summary = sysprof_callgraph_get_summary (self, symbol);
|
||||
node->parent = parent;
|
||||
node->next = parent->children;
|
||||
if (parent->children)
|
||||
@ -322,7 +314,7 @@ sysprof_callgraph_add_traceable (SysprofCallgraph *self,
|
||||
if (final_context == SYSPROF_ADDRESS_CONTEXT_KERNEL)
|
||||
symbols[n_symbols++] = _sysprof_document_kernel_symbol (self->document);
|
||||
symbols[n_symbols++] = _sysprof_document_process_symbol (self->document, pid);
|
||||
symbols[n_symbols++] = self->everything;
|
||||
symbols[n_symbols++] = everything;
|
||||
|
||||
node = sysprof_callgraph_add_trace (self, symbols, n_symbols, list_model_index);
|
||||
|
||||
@ -391,6 +383,7 @@ _sysprof_callgraph_new_async (SysprofDocument *document,
|
||||
self->augment_func_data = augment_func_data;
|
||||
self->augment_func_data_destroy = augment_func_data_destroy;
|
||||
self->symbol_to_summary = g_hash_table_new_full (NULL, NULL, NULL, summary_free);
|
||||
self->root.summary = sysprof_callgraph_get_summary (self, everything);
|
||||
|
||||
task = g_task_new (NULL, cancellable, callback, user_data);
|
||||
g_task_set_source_tag (task, _sysprof_callgraph_new_async);
|
||||
@ -407,20 +400,34 @@ _sysprof_callgraph_new_finish (GAsyncResult *result,
|
||||
return g_task_propagate_pointer (G_TASK (result), error);
|
||||
}
|
||||
|
||||
gpointer
|
||||
sysprof_callgraph_get_augment (SysprofCallgraph *callgraph,
|
||||
SysprofCallgraphNode *node)
|
||||
static inline gpointer
|
||||
get_augmentation (SysprofCallgraph *self,
|
||||
gpointer *augment_location)
|
||||
{
|
||||
if (callgraph->augment_size == 0)
|
||||
if (self->augment_size == 0)
|
||||
return NULL;
|
||||
|
||||
if (callgraph->augment_size <= GLIB_SIZEOF_VOID_P)
|
||||
return &node->augment;
|
||||
if (self->augment_size <= GLIB_SIZEOF_VOID_P)
|
||||
return augment_location;
|
||||
|
||||
if (node->augment == NULL)
|
||||
node->augment = g_malloc0 (callgraph->augment_size);
|
||||
if (*augment_location == NULL)
|
||||
*augment_location = g_malloc0 (self->augment_size);
|
||||
|
||||
return node->augment;
|
||||
return *augment_location;
|
||||
}
|
||||
|
||||
gpointer
|
||||
sysprof_callgraph_get_augment (SysprofCallgraph *self,
|
||||
SysprofCallgraphNode *node)
|
||||
{
|
||||
return get_augmentation (self, &node->augment);
|
||||
}
|
||||
|
||||
gpointer
|
||||
sysprof_callgraph_get_summary_augment (SysprofCallgraph *self,
|
||||
SysprofCallgraphNode *node)
|
||||
{
|
||||
return get_augmentation (self, &node->summary->augment);
|
||||
}
|
||||
|
||||
SysprofCallgraphNode *
|
||||
|
||||
@ -66,6 +66,9 @@ SYSPROF_AVAILABLE_IN_ALL
|
||||
gpointer sysprof_callgraph_get_augment (SysprofCallgraph *self,
|
||||
SysprofCallgraphNode *node);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
gpointer sysprof_callgraph_get_summary_augment (SysprofCallgraph *self,
|
||||
SysprofCallgraphNode *node);
|
||||
SYSPROF_AVAILABLE_IN_ALL
|
||||
SysprofCallgraphNode *sysprof_callgraph_node_parent (SysprofCallgraphNode *node);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
Reference in New Issue
Block a user