public inbox for dwz@sourceware.org
 help / color / mirror / Atom feed
* [committed] Add edge_freelist interface
@ 2019-01-01  0:00 Tom de Vries
  0 siblings, 0 replies; only message in thread
From: Tom de Vries @ 2019-01-01  0:00 UTC (permalink / raw)
  To: dwz, jakub

Hi,

Make sure all accesses to the edge_freelist variable are done using interface
functions.

Committed to trunk.

Thanks,
- Tom

Add edge_freelist interface

2019-12-16  Tom de Vries  <tdevries@suse.de>

	* dwz.c (verify_edge_freelist): New variable.
	(prepare_free_edge, free_edge, free_edges, edge_from_freelist):
	(first_edge_from_freelist, last_edge_from_freelist): New functions.
	(remove_import_edges, create_import_tree): Use new functions.

---
 dwz.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++++++------------
 1 file changed, 109 insertions(+), 24 deletions(-)

diff --git a/dwz.c b/dwz.c
index 9f06520..d950fb0 100644
--- a/dwz.c
+++ b/dwz.c
@@ -161,6 +161,7 @@ static int ignore_locus;
 static int dump_dies_p;
 static int dump_dups_p;
 static int verify_dups_p;
+static int verify_edge_freelist;
 #else
 #define tracing 0
 #define ignore_size 0
@@ -6483,6 +6484,98 @@ import_cu_cmp (const void *p, const void *q)
 /* Freelist for removed edges.  */
 static struct import_edge *edge_freelist;
 
+/* Prepare edge E to add to edge_freelist.  */
+static inline void FORCE_INLINE
+prepare_free_edge (struct import_edge *e UNUSED)
+{
+#if DEVEL
+  e->icu = (void *)(uintptr_t)-1;
+#endif
+}
+
+/* Add edge E to edge_freelist.  */
+static inline void FORCE_INLINE
+free_edge (struct import_edge *e)
+{
+  prepare_free_edge (e);
+  e->next = edge_freelist;
+  edge_freelist = e;
+}
+
+/* Add edge list starting at HEAD and ending at TAIL to edge_freelist.
+   Assume that prepare_free_edge has been called on all elements.  */
+static inline void FORCE_INLINE
+free_edges (struct import_edge *head, struct import_edge *tail)
+{
+#if DEVEL
+  if (verify_edge_freelist)
+    {
+      struct import_edge *e;
+      for (e = head; e; e = e->next)
+	{
+	  assert (e->icu == (void *)(uintptr_t)-1);
+	  if (e == tail)
+	    break;
+	}
+      assert (e != NULL);
+    }
+#endif
+  tail->next = edge_freelist;
+  edge_freelist = head;
+}
+
+/* Detach an edge from edge_freelist, and return it.  */
+static inline struct import_edge * FORCE_INLINE
+edge_from_freelist (void)
+{
+#if DEVEL
+  assert (edge_freelist);
+#endif
+  struct import_edge *e = edge_freelist;
+  edge_freelist = edge_freelist->next;
+#if DEVEL
+  e->next = (void *)(uintptr_t)-1;
+#endif
+  return e;
+}
+
+/* Return edge_freelist, and set it to NULL.  */
+static inline struct import_edge * FORCE_INLINE
+first_edge_from_freelist (void)
+{
+#if DEVEL
+  assert (edge_freelist);
+#endif
+  struct import_edge *e = edge_freelist;
+#if DEVEL
+  edge_freelist = NULL;
+#endif
+  return e;
+}
+
+/* Set edge_freelist to TAIL->next and return HEAD.  Assume HEAD was returned
+   by first_edge_from_freelist, and TAIL is reachable from HEAD.  */
+static inline struct import_edge * FORCE_INLINE
+last_edge_from_freelist (struct import_edge *head, struct import_edge *tail)
+{
+#if DEVEL
+  assert (!edge_freelist);
+  if (verify_edge_freelist)
+    {
+      struct import_edge *e;
+      for (e = head; e; e = e->next)
+	{
+	  if (e == tail)
+	    break;
+	}
+      assert (e != NULL);
+    }
+#endif
+  edge_freelist = tail->next;
+  tail->next = NULL;
+  return head;
+}
+
 /* Remove edges in linked list EP that refer to CUS, which
    is an array of CUCOUNT CUs/PUs.  If ADD is true, additionally
    add a new edge at the end of the linked list and return it.  */
@@ -6500,10 +6593,7 @@ remove_import_edges (struct import_edge **ep, struct import_cu **cus,
 	if (efirst == NULL)
 	  efirst = e;
 	else
-	  {
-	    e->next = edge_freelist;
-	    edge_freelist = e;
-	  }
+	  free_edge (e);
 	i++;
 	if (i == cucount && !add)
 	  return NULL;
@@ -6996,28 +7086,27 @@ create_import_tree (void)
 						   srccount, true)->icu = npu;
 			      pudst[j]->incoming_count -= srccount - 1;
 			    }
-			  npu->incoming = edge_freelist;
+			  npu->incoming = first_edge_from_freelist ();
 			  for (j = 0, e4 = npu->incoming; j < srccount; j++)
 			    {
 			      e4->icu = pusrc[j];
 			      if (j == srccount - 1)
 				{
-				  edge_freelist = e4->next;
-				  e4->next = NULL;
+				  npu->incoming
+				    = last_edge_from_freelist (npu->incoming,
+							       e4);
 				  ep = &e4->next;
 				}
 			      else
 				e4 = e4->next;
 			    }
-			  npu->outgoing = edge_freelist;
+			  npu->outgoing = first_edge_from_freelist ();
 			  for (j = 0, e4 = npu->outgoing; j < dstcount; j++)
 			    {
 			      e4->icu = pudst[j];
 			      if (j == dstcount - 1)
-				{
-				  edge_freelist = e4->next;
-				  e4->next = NULL;
-				}
+				npu->outgoing
+				  = last_edge_from_freelist (npu->outgoing, e4);
 			      else
 				e4 = e4->next;
 			    }
@@ -7045,8 +7134,7 @@ create_import_tree (void)
 					       pusrc + srccount, 1, false);
 			  pudst[j]->incoming_count--;
 			}
-		      *ep = edge_freelist;
-		      edge_freelist = edge_freelist->next;
+		      *ep = edge_from_freelist ();
 		      npu->incoming_count++;
 		      (*ep)->icu = pusrc[srccount];
 		      (*ep)->next = NULL;
@@ -7192,15 +7280,15 @@ create_import_tree (void)
 		  if (!ignore_size || size_dec > size_inc)
 		    {
 		      struct import_cu **ipup;
-		      for (e4 = ipu2->incoming, ep = NULL; e4; e4 = e4->next)
+		      for (e4 = ipu2->incoming, e3 = NULL; e4; e4 = e4->next)
 			{
 			  remove_import_edges (&e4->icu->outgoing, &ipu2, 1,
 					       false);
 			  e4->icu->outgoing_count--;
-			  ep = &e4->next;
+			  prepare_free_edge (e4);
+			  e3 = e4;
 			}
-		      *ep = edge_freelist;
-		      edge_freelist = ipu2->incoming;
+		      free_edges (ipu2->incoming, e3);
 		      for (e4 = ipu2->outgoing; e4; e4 = e4->next)
 			{
 			  for (ep = &e4->icu->incoming; *ep; ep = &(*ep)->next)
@@ -7299,15 +7387,13 @@ create_import_tree (void)
 			ep = &(*ep)->next;
 		      e4 = *ep;
 		      *ep = e4->next;
-		      e4->next = edge_freelist;
-		      edge_freelist = e4;
+		      free_edge (e4);
 		    }
 		  for (ep = &ipusub->outgoing; *ep; ep = &(*ep)->next)
 		    if ((*ep)->icu->idx >= ipusup->idx)
 		      break;
 		  assert (*ep == NULL || (*ep)->icu != ipusup);
-		  e4 = edge_freelist;
-		  edge_freelist = edge_freelist->next;
+		  e4 = edge_from_freelist ();
 		  e4->icu = ipusup;
 		  e4->next = *ep;
 		  *ep = e4;
@@ -7316,8 +7402,7 @@ create_import_tree (void)
 		    if ((*ep)->icu->idx >= ipusub->idx)
 		      break;
 		  assert (*ep == NULL || (*ep)->icu != ipusub);
-		  e4 = edge_freelist;
-		  edge_freelist = edge_freelist->next;
+		  e4 = edge_from_freelist ();
 		  e4->icu = ipusub;
 		  e4->next = *ep;
 		  *ep = e4;

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-12-16 13:16 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-01  0:00 [committed] Add edge_freelist interface Tom de Vries

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).