mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2025-12-31 20:36:25 +00:00
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:
@ -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.
|
||||
*
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
Reference in New Issue
Block a user