From 97c93ea9657d7556aecbb53b2352cc7639f5cf5c Mon Sep 17 00:00:00 2001 From: Christian Hergert Date: Tue, 25 Apr 2023 17:09:04 -0700 Subject: [PATCH] libsysprof-analyze: track frame length That way we don't have to decode this too in the subclasses. --- .../sysprof-document-frame-private.h | 7 ++-- .../sysprof-document-frame.c | 2 ++ src/libsysprof-analyze/sysprof-document.c | 33 +++++++++++++------ 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/src/libsysprof-analyze/sysprof-document-frame-private.h b/src/libsysprof-analyze/sysprof-document-frame-private.h index aadd6319..918acb9d 100644 --- a/src/libsysprof-analyze/sysprof-document-frame-private.h +++ b/src/libsysprof-analyze/sysprof-document-frame-private.h @@ -28,10 +28,12 @@ G_BEGIN_DECLS struct _SysprofDocumentFrame { - GObject parent_instance; + GObject parent; GMappedFile *mapped_file; const SysprofCaptureFrame *frame; - guint needs_swap : 1; + guint32 frame_len : 16; + guint32 needs_swap : 1; + guint32 padding : 15; }; struct _SysprofDocumentFrameClass @@ -41,6 +43,7 @@ struct _SysprofDocumentFrameClass SysprofDocumentFrame *_sysprof_document_frame_new (GMappedFile *mapped, const SysprofCaptureFrame *frame, + guint16 frame_len, gboolean needs_swap); #define SYSPROF_DOCUMENT_FRAME_GET(obj, type) \ diff --git a/src/libsysprof-analyze/sysprof-document-frame.c b/src/libsysprof-analyze/sysprof-document-frame.c index fdd773ee..3bd4ddcb 100644 --- a/src/libsysprof-analyze/sysprof-document-frame.c +++ b/src/libsysprof-analyze/sysprof-document-frame.c @@ -114,6 +114,7 @@ sysprof_document_frame_init (SysprofDocumentFrame *self) SysprofDocumentFrame * _sysprof_document_frame_new (GMappedFile *mapped_file, const SysprofCaptureFrame *frame, + guint16 frame_len, gboolean needs_swap) { SysprofDocumentFrame *self; @@ -122,6 +123,7 @@ _sysprof_document_frame_new (GMappedFile *mapped_file, self->mapped_file = g_mapped_file_ref (mapped_file); self->frame = frame; + self->frame_len = frame_len; self->needs_swap = !!needs_swap; return self; diff --git a/src/libsysprof-analyze/sysprof-document.c b/src/libsysprof-analyze/sysprof-document.c index 43d5d468..9b9ed75b 100644 --- a/src/libsysprof-analyze/sysprof-document.c +++ b/src/libsysprof-analyze/sysprof-document.c @@ -30,12 +30,19 @@ struct _SysprofDocument { GObject parent_instance; - GPtrArray *frames; + GArray *frames; GMappedFile *mapped_file; + const guint8 *base; SysprofCaptureFileHeader header; guint needs_swap : 1; }; +typedef struct _SysprofDocumentFramePointer +{ + guint64 offset : 48; + guint64 length : 16; +} SysprofDocumentFramePointer; + static GType sysprof_document_get_item_type (GListModel *model) { @@ -50,15 +57,19 @@ sysprof_document_get_n_items (GListModel *model) static gpointer sysprof_document_get_item (GListModel *model, - guint position) + guint position) { SysprofDocument *self = SYSPROF_DOCUMENT (model); + SysprofDocumentFramePointer *ptr; if (position >= self->frames->len) return NULL; + ptr = &g_array_index (self->frames, SysprofDocumentFramePointer, position); + return _sysprof_document_frame_new (self->mapped_file, - g_ptr_array_index (self->frames, position), + (gconstpointer)&self->base[ptr->offset], + ptr->length, self->needs_swap); } @@ -79,7 +90,7 @@ sysprof_document_finalize (GObject *object) SysprofDocument *self = (SysprofDocument *)object; g_clear_pointer (&self->mapped_file, g_mapped_file_unref); - g_clear_pointer (&self->frames, g_ptr_array_unref); + g_clear_pointer (&self->frames, g_array_unref); G_OBJECT_CLASS (sysprof_document_parent_class)->finalize (object); } @@ -94,7 +105,7 @@ sysprof_document_class_init (SysprofDocumentClass *klass) static void sysprof_document_init (SysprofDocument *self) { - self->frames = g_ptr_array_new (); + self->frames = g_array_new (FALSE, FALSE, sizeof (SysprofDocumentFramePointer)); } static gboolean @@ -102,7 +113,6 @@ sysprof_document_load (SysprofDocument *self, int capture_fd, GError **error) { - const guint8 *data; goffset pos; gsize len; @@ -112,14 +122,14 @@ sysprof_document_load (SysprofDocument *self, if (!(self->mapped_file = g_mapped_file_new_from_fd (capture_fd, FALSE, error))) return FALSE; - data = (const guint8 *)g_mapped_file_get_contents (self->mapped_file); + self->base = (const guint8 *)g_mapped_file_get_contents (self->mapped_file); len = g_mapped_file_get_length (self->mapped_file); if (len < sizeof self->header) return FALSE; /* Keep a copy of our header */ - memcpy (&self->header, data, sizeof self->header); + memcpy (&self->header, self->base, sizeof self->header); #if G_BYTE_ORDER == G_LITTLE_ENDIAN self->needs_swap = !self->header.little_endian; #else @@ -135,16 +145,19 @@ sysprof_document_load (SysprofDocument *self, pos = sizeof self->header; while (pos < (len - sizeof(guint16))) { + SysprofDocumentFramePointer ptr; guint16 frame_len; - memcpy (&frame_len, &data[pos], sizeof frame_len); + memcpy (&frame_len, &self->base[pos], sizeof frame_len); if (self->needs_swap) frame_len = GUINT16_SWAP_LE_BE (frame_len); if (frame_len < sizeof (SysprofCaptureFrame)) break; - g_ptr_array_add (self->frames, (gpointer)&data[pos]); + ptr.offset = pos; + ptr.length = frame_len; + g_array_append_val (self->frames, ptr); pos += frame_len; }