libsysprof-analyze: add vfunc for getting stack addresses

This allows us to avoid the function call overhead for each of the
instruction pointers in the stack trace. Instead let the interface handle
the decoding of the whole set.
This commit is contained in:
Christian Hergert
2023-05-24 12:44:26 -07:00
parent 059aec5a1e
commit f7882d5c5f
4 changed files with 41 additions and 16 deletions

View File

@ -59,7 +59,21 @@ sysprof_document_allocation_get_stack_address (SysprofDocumentTraceable *traceab
{
const SysprofCaptureAllocation *allocation = SYSPROF_DOCUMENT_FRAME_GET (traceable, SysprofCaptureAllocation);
return SYSPROF_DOCUMENT_FRAME_UINT64 (traceable, allocation->addrs[position]);
return SYSPROF_DOCUMENT_FRAME_UINT16 (traceable, allocation->addrs[position]);
}
static guint
sysprof_document_allocation_get_stack_addresses (SysprofDocumentTraceable *traceable,
guint64 *addresses,
guint n_addresses)
{
const SysprofCaptureAllocation *allocation = SYSPROF_DOCUMENT_FRAME_GET (traceable, SysprofCaptureAllocation);
guint depth = MIN (n_addresses, SYSPROF_DOCUMENT_FRAME_UINT16 (traceable, allocation->n_addrs));
for (guint i = 0; i < depth; i++)
addresses[i] = SYSPROF_DOCUMENT_FRAME_UINT64 (traceable, allocation->addrs[i]);
return depth;
}
static void
@ -67,6 +81,7 @@ traceable_iface_init (SysprofDocumentTraceableInterface *iface)
{
iface->get_stack_depth = sysprof_document_allocation_get_stack_depth;
iface->get_stack_address = sysprof_document_allocation_get_stack_address;
iface->get_stack_addresses = sysprof_document_allocation_get_stack_addresses;
}
G_DEFINE_FINAL_TYPE_WITH_CODE (SysprofDocumentAllocation, sysprof_document_allocation, SYSPROF_TYPE_DOCUMENT_FRAME,
@ -119,7 +134,7 @@ sysprof_document_allocation_class_init (SysprofDocumentAllocationClass *klass)
/**
* SysprofDocumentAllocation:tid:
*
* The task-id or thread-id of the thread which was sampled.
* The task-id or thread-id of the thread which was traced.
*
* On Linux, this is generally set to the value of the gettid() syscall.
*

View File

@ -52,11 +52,25 @@ sysprof_document_sample_get_stack_depth (SysprofDocumentTraceable *traceable)
static guint64
sysprof_document_sample_get_stack_address (SysprofDocumentTraceable *traceable,
guint position)
guint position)
{
const SysprofCaptureSample *sample = SYSPROF_DOCUMENT_FRAME_GET (traceable, SysprofCaptureSample);
return SYSPROF_DOCUMENT_FRAME_UINT64 (traceable, sample->addrs[position]);
return SYSPROF_DOCUMENT_FRAME_UINT16 (traceable, sample->addrs[position]);
}
static guint
sysprof_document_sample_get_stack_addresses (SysprofDocumentTraceable *traceable,
guint64 *addresses,
guint n_addresses)
{
const SysprofCaptureSample *sample = SYSPROF_DOCUMENT_FRAME_GET (traceable, SysprofCaptureSample);
guint depth = MIN (n_addresses, SYSPROF_DOCUMENT_FRAME_UINT16 (traceable, sample->n_addrs));
for (guint i = 0; i < depth; i++)
addresses[i] = SYSPROF_DOCUMENT_FRAME_UINT64 (traceable, sample->addrs[i]);
return depth;
}
static void
@ -64,6 +78,7 @@ traceable_iface_init (SysprofDocumentTraceableInterface *iface)
{
iface->get_stack_depth = sysprof_document_sample_get_stack_depth;
iface->get_stack_address = sysprof_document_sample_get_stack_address;
iface->get_stack_addresses = sysprof_document_sample_get_stack_addresses;
}
G_DEFINE_FINAL_TYPE_WITH_CODE (SysprofDocumentSample, sysprof_document_sample, SYSPROF_TYPE_DOCUMENT_FRAME,

View File

@ -63,18 +63,10 @@ sysprof_document_traceable_get_stack_addresses (SysprofDocumentTraceable *self,
guint64 *addresses,
guint n_addresses)
{
guint64 (*decoder) (SysprofDocumentTraceable *, guint);
g_return_val_if_fail (SYSPROF_IS_DOCUMENT_TRACEABLE (self), 0);
if (addresses == NULL || n_addresses == 0)
return 0;
decoder = SYSPROF_DOCUMENT_TRACEABLE_GET_IFACE (self)->get_stack_address;
n_addresses = MIN (n_addresses, sysprof_document_traceable_get_stack_depth (self));
for (guint i = 0; i < n_addresses; i++)
addresses[i] = decoder (self, i);
return n_addresses;
return SYSPROF_DOCUMENT_TRACEABLE_GET_IFACE (self)->get_stack_addresses (self, addresses, n_addresses);
}

View File

@ -34,9 +34,12 @@ struct _SysprofDocumentTraceableInterface
{
GTypeInterface parent;
guint (*get_stack_depth) (SysprofDocumentTraceable *self);
guint64 (*get_stack_address) (SysprofDocumentTraceable *self,
guint position);
guint (*get_stack_depth) (SysprofDocumentTraceable *self);
guint64 (*get_stack_address) (SysprofDocumentTraceable *self,
guint position);
guint (*get_stack_addresses) (SysprofDocumentTraceable *self,
guint64 *addresses,
guint n_addresses);
};
SYSPROF_AVAILABLE_IN_ALL