[PATCH 2/2] libdw: Reduce size of struct Dwarf_Abbrev.

Mark Wielaard mark@klomp.org
Tue Dec 26 19:38:00 GMT 2017


If we don't cache the attrcnt and use bitfields for the has_children and
code we can reduce the size of struct Dwarf Abbrev from 32 to 24 bytes on
64bit architectures and from 28 to 20 bytes on 32bit arches.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libdw/ChangeLog          |  7 +++++++
 libdw/dwarf_getabbrev.c  |  7 +++----
 libdw/dwarf_getattrcnt.c | 19 +++++++++++++++++--
 libdw/libdwP.h           | 15 +++++++--------
 4 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 3e3b7169..c284dbbd 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,10 @@
+2017-12-26  Mark Wielaard  <mark@klomp.org>
+
+	* libdwP.h (struct Dwarf_Abbrev): Pack struct. Remove attrcnt,
+	use bitfields for has_children and code.
+	* dwarf_getabbrev.c (__libdw_getabbrev): Don't count attrs.
+	* dwarf_getattrcnt.c (dwarf_getattrcnt): Count attrs.
+
 2017-12-26  Mark Wielaard  <mark@klomp.org>
 
 	* memory-access.h (__libdw_get_uleb128_unchecked): New function.
diff --git a/libdw/dwarf_getabbrev.c b/libdw/dwarf_getabbrev.c
index ef51b847..a3a68b37 100644
--- a/libdw/dwarf_getabbrev.c
+++ b/libdw/dwarf_getabbrev.c
@@ -1,5 +1,5 @@
 /* Get abbreviation at given offset.
-   Copyright (C) 2003, 2004, 2005, 2006, 2014 Red Hat, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2014, 2017 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -121,8 +121,7 @@ __libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, Dwarf_Off offset,
   abb->attrp = (unsigned char *) abbrevp;
   abb->offset = offset;
 
-  /* Skip over all the attributes and count them while doing so.  */
-  abb->attrcnt = 0;
+  /* Skip over all the attributes and check rest of the abbrev is valid.  */
   unsigned int attrname;
   unsigned int attrform;
   do
@@ -134,7 +133,7 @@ __libdw_getabbrev (Dwarf *dbg, struct Dwarf_CU *cu, Dwarf_Off offset,
 	goto invalid;
       get_uleb128 (attrform, abbrevp, end);
     }
-  while (attrname != 0 && attrform != 0 && ++abb->attrcnt);
+  while (attrname != 0 && attrform != 0);
 
   /* Return the length to the caller if she asked for it.  */
   if (lengthp != NULL)
diff --git a/libdw/dwarf_getattrcnt.c b/libdw/dwarf_getattrcnt.c
index 2bfb4ac5..a05976d4 100644
--- a/libdw/dwarf_getattrcnt.c
+++ b/libdw/dwarf_getattrcnt.c
@@ -1,5 +1,5 @@
 /* Get number of attributes of abbreviation.
-   Copyright (C) 2003, 2004 Red Hat, Inc.
+   Copyright (C) 2003, 2004, 2017 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -40,7 +40,22 @@ dwarf_getattrcnt (Dwarf_Abbrev *abbrev, size_t *attrcntp)
   if (abbrev == NULL)
     return -1;
 
-  *attrcntp = abbrev->attrcnt;
+  const unsigned char *abbrevp = abbrev->attrp;
+
+  /* Skip over all the attributes and count them while doing so.  */
+  int attrcnt = 0;
+  unsigned int attrname;
+  unsigned int attrform;
+  do
+    {
+      /* We can use unchecked since they were checked when the Dwrf_Abbrev
+	 was created.  */
+      get_uleb128_unchecked (attrname, abbrevp);
+      get_uleb128_unchecked (attrform, abbrevp);
+    }
+  while (attrname != 0 && attrform != 0 && ++attrcnt);
+
+  *attrcntp = attrcnt;
 
   return 0;
 }
diff --git a/libdw/libdwP.h b/libdw/libdwP.h
index 82b47d09..fbb8ed08 100644
--- a/libdw/libdwP.h
+++ b/libdw/libdwP.h
@@ -1,5 +1,5 @@
 /* Internal definitions for libdwarf.
-   Copyright (C) 2002-2011, 2013-2016 Red Hat, Inc.
+   Copyright (C) 2002-2011, 2013-2017 Red Hat, Inc.
    This file is part of elfutils.
    Written by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -212,13 +212,12 @@ struct Dwarf
 /* Abbreviation representation.  */
 struct Dwarf_Abbrev
 {
-  Dwarf_Off offset;
-  unsigned char *attrp;
-  unsigned int attrcnt;
-  unsigned int code;
-  unsigned int tag;
-  bool has_children;
-};
+  Dwarf_Off offset;	  /* Offset to start of abbrev into .debug_abbrev.  */
+  unsigned char *attrp;   /* Pointer to start of attribute name/form pairs. */
+  bool has_children : 1;  /* Whether or not the DIE has children. */
+  unsigned int code : 31; /* The (unique) abbrev code.  */
+  unsigned int tag;	  /* The tag of the DIE. */
+} attribute_packed;
 
 #include "dwarf_abbrev_hash.h"
 
-- 
2.14.3



More information about the Elfutils-devel mailing list