From f7882d5c5f6f9a45f16fff41b1640e41bf4a915c Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Wed, 24 May 2023 12:44:26 -0700 Subject: [PATCH] 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. --- .../sysprof-document-allocation.c | 19 +++++++++++++++++-- .../sysprof-document-sample.c | 19 +++++++++++++++++-- .../sysprof-document-traceable.c | 10 +--------- .../sysprof-document-traceable.h | 9 ++++++--- 4 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/libsysprof-analyze/sysprof-document-allocation.c b/src/libsysprof-analyze/sysprof-document-allocation.c index 0a287339..773bc7f2 100644 --- a/src/libsysprof-analyze/sysprof-document-allocation.c +++ b/src/libsysprof-analyze/sysprof-document-allocation.c @@ -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. * diff --git a/src/libsysprof-analyze/sysprof-document-sample.c b/src/libsysprof-analyze/sysprof-document-sample.c index 685668d7..73ba990c 100644 --- a/src/libsysprof-analyze/sysprof-document-sample.c +++ b/src/libsysprof-analyze/sysprof-document-sample.c @@ -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, diff --git a/src/libsysprof-analyze/sysprof-document-traceable.c b/src/libsysprof-analyze/sysprof-document-traceable.c index 8bf4f250..620bc0cc 100644 --- a/src/libsysprof-analyze/sysprof-document-traceable.c +++ b/src/libsysprof-analyze/sysprof-document-traceable.c @@ -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); } diff --git a/src/libsysprof-analyze/sysprof-document-traceable.h b/src/libsysprof-analyze/sysprof-document-traceable.h index 904ac65e..459990ba 100644 --- a/src/libsysprof-analyze/sysprof-document-traceable.h +++ b/src/libsysprof-analyze/sysprof-document-traceable.h @@ -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