This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH 09/11] [SQUASH] btrace: Remove struct btrace_thread_info::{begin,end}.


This patch stands alone for easier review and is meant to be squashed together
for committing.  ChangeLog will be added to the squashed commit.


2017-02-17  Tim Wiederhake  <tim.wiederhake@intel.com>
---
 gdb/btrace.c        | 159 +++++++++++++++++++++++++---------------------------
 gdb/btrace.h        |   1 -
 gdb/record-btrace.c |   2 +-
 3 files changed, 77 insertions(+), 85 deletions(-)

diff --git a/gdb/btrace.c b/gdb/btrace.c
index 701daa3..cd2475d 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -402,8 +402,8 @@ ftrace_new_return (struct btrace_thread_info *btinfo,
 {
   struct btrace_function *prev, *bfun, *caller;
 
-  prev = btinfo->end;
   bfun = ftrace_new_function (btinfo, mfun, fun);
+  prev = ftrace_find_call_by_number (btinfo, bfun->number - 1);
 
   /* It is important to start at PREV's caller.  Otherwise, we might find
      PREV itself, if PREV is a recursive function.  */
@@ -500,16 +500,17 @@ ftrace_new_switch (struct btrace_thread_info *btinfo,
 static struct btrace_function *
 ftrace_new_gap (struct btrace_thread_info *btinfo, int errcode)
 {
-  struct btrace_function *prev, *bfun;
-
-  prev = btinfo->end;
+  struct btrace_function *bfun;
 
-  /* We hijack prev if it was empty.  */
-  if (prev != NULL && prev->errcode == 0
-      && VEC_empty (btrace_insn_s, prev->insn))
-    bfun = prev;
-  else
+  if (VEC_empty (btrace_fun_s, btinfo->functions))
     bfun = ftrace_new_function (btinfo, NULL, NULL);
+  else
+    {
+      /* We hijack the previous function call segment if it was empty.  */
+      bfun = VEC_last (btrace_fun_s, btinfo->functions);
+      if (bfun->errcode != 0 || !VEC_empty (btrace_insn_s, bfun->insn))
+	bfun = ftrace_new_function (btinfo, NULL, NULL);
+    }
 
   bfun->errcode = errcode;
 
@@ -531,8 +532,6 @@ ftrace_update_function (struct btrace_thread_info *btinfo, CORE_ADDR pc)
   struct btrace_insn *last;
   struct btrace_function *bfun;
 
-  bfun = btinfo->end;
-
   /* Try to determine the function we're in.  We use both types of symbols
      to avoid surprises when we sometimes get a full symbol and sometimes
      only a minimal symbol.  */
@@ -543,8 +542,13 @@ ftrace_update_function (struct btrace_thread_info *btinfo, CORE_ADDR pc)
   if (fun == NULL && mfun == NULL)
     DEBUG_FTRACE ("no symbol at %s", core_addr_to_string_nz (pc));
 
-  /* If we didn't have a function or if we had a gap before, we create one.  */
-  if (bfun == NULL || bfun->errcode != 0)
+  /* If we didn't have a function, we create one.  */
+  if (VEC_empty (btrace_fun_s, btinfo->functions))
+    return ftrace_new_function (btinfo, mfun, fun);
+
+  /* If we had a gap before, we create a function.  */
+  bfun = VEC_last (btrace_fun_s, btinfo->functions);
+  if (bfun->errcode != 0)
     return ftrace_new_function (btinfo, mfun, fun);
 
   /* Check the last instruction, if we have one.
@@ -627,7 +631,7 @@ static void
 ftrace_update_insns (struct btrace_thread_info *btinfo,
 		     const struct btrace_insn *insn)
 {
-  struct btrace_function *bfun = btinfo->end;
+  struct btrace_function *bfun = VEC_last (btrace_fun_s, btinfo->functions);
 
   VEC_safe_push (btrace_insn_s, bfun->insn, insn);
 
@@ -708,28 +712,26 @@ ftrace_fixup_level (struct btrace_thread_info *btinfo,
 static void
 ftrace_compute_global_level_offset (struct btrace_thread_info *btinfo)
 {
-  struct btrace_function *bfun, *end;
-  int level;
+  struct btrace_function *bfun;
+  int i, length, level;
 
   if (btinfo == NULL)
     return;
 
-  bfun = btinfo->begin;
-  if (bfun == NULL)
+  if (VEC_empty (btrace_fun_s, btinfo->functions))
     return;
 
-  /* The last function segment contains the current instruction, which is not
-     really part of the trace.  If it contains just this one instruction, we
-     stop when we reach it; otherwise, we let the below loop run to the end.  */
-  end = btinfo->end;
-  if (VEC_length (btrace_insn_s, end->insn) > 1)
-    end = NULL;
-
   level = INT_MAX;
-  while (bfun != end)
+  length = VEC_length (btrace_fun_s, btinfo->functions);
+  for (i = 0; VEC_iterate (btrace_fun_s, btinfo->functions, i, bfun); i++)
     {
+      /* The last function segment contains the current instruction, which is
+	 not really part of the trace.  If it contains just this one
+	 instruction, we ignore the segment.  */
+      if (bfun->number == length && VEC_length (btrace_insn_s, bfun->insn) == 1)
+	  continue;
+
       level = std::min (level, bfun->level);
-      bfun = ftrace_find_call_by_number (btinfo, bfun->number + 1);
     }
 
   DEBUG_FTRACE ("setting global level offset: %d", -level);
@@ -1033,9 +1035,13 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
 
   gdbarch = target_gdbarch ();
   btinfo = &tp->btrace;
-  level = btinfo->begin != NULL ? -btinfo->level : INT_MAX;
   blk = VEC_length (btrace_block_s, btrace->blocks);
 
+  if (VEC_empty (btrace_fun_s, btinfo->functions))
+    level = INT_MAX;
+  else
+    level = -btinfo->level;
+
   while (blk != 0)
     {
       btrace_block_s *block;
@@ -1048,6 +1054,7 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
 
       for (;;)
 	{
+	  struct btrace_function *bfun;
 	  struct btrace_insn insn;
 	  int size;
 
@@ -1055,27 +1062,23 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
 	  if (block->end < pc)
 	    {
 	      /* Indicate the gap in the trace.  */
-	      btinfo->end = ftrace_new_gap (btinfo, BDE_BTS_OVERFLOW);
-	      if (btinfo->begin == NULL)
-		btinfo->begin = btinfo->end;
+	      bfun = ftrace_new_gap (btinfo, BDE_BTS_OVERFLOW);
 
-	      VEC_safe_push (bfun_s, *gaps, btinfo->end);
+	      VEC_safe_push (bfun_s, *gaps, bfun);
 
 	      warning (_("Recorded trace may be corrupted at instruction "
-			 "%u (pc = %s)."), btinfo->end->insn_offset - 1,
+			 "%u (pc = %s)."), bfun->insn_offset - 1,
 		       core_addr_to_string_nz (pc));
 
 	      break;
 	    }
 
-	  btinfo->end = ftrace_update_function (btinfo, pc);
-	  if (btinfo->begin == NULL)
-	    btinfo->begin = btinfo->end;
+	  bfun = ftrace_update_function (btinfo, pc);
 
 	  /* Maintain the function level offset.
 	     For all but the last block, we do it here.  */
 	  if (blk != 0)
-	    level = std::min (level, btinfo->end->level);
+	    level = std::min (level, bfun->level);
 
 	  size = 0;
 	  TRY
@@ -1103,12 +1106,12 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
 	    {
 	      /* Indicate the gap in the trace.  We just added INSN so we're
 		 not at the beginning.  */
-	      btinfo->end = ftrace_new_gap (btinfo, BDE_BTS_INSN_SIZE);
+	      bfun = ftrace_new_gap (btinfo, BDE_BTS_INSN_SIZE);
 
-	      VEC_safe_push (bfun_s, *gaps, btinfo->end);
+	      VEC_safe_push (bfun_s, *gaps, bfun);
 
 	      warning (_("Recorded trace may be incomplete at instruction %u "
-			 "(pc = %s)."), btinfo->end->insn_offset - 1,
+			 "(pc = %s)."), bfun->insn_offset - 1,
 		       core_addr_to_string_nz (pc));
 
 	      break;
@@ -1123,7 +1126,7 @@ btrace_compute_ftrace_bts (struct thread_info *tp,
 	     and is not really part of the execution history, it shouldn't
 	     affect the level.  */
 	  if (blk == 0)
-	    level = std::min (level, btinfo->end->level);
+	    level = std::min (level, bfun->level);
 	}
     }
 
@@ -1174,7 +1177,7 @@ ftrace_add_pt (struct pt_insn_decoder *decoder,
 	       struct btrace_thread_info *btinfo,
 	       int *plevel, VEC (bfun_s) **gaps)
 {
-  struct btrace_function *upd;
+  struct btrace_function *bfun, *upd;
   uint64_t offset;
   int errcode;
 
@@ -1200,7 +1203,7 @@ ftrace_add_pt (struct pt_insn_decoder *decoder,
 	    break;
 
 	  /* Look for gaps in the trace - unless we're at the beginning.  */
-	  if (btinfo->begin != NULL)
+	  if (!VEC_empty (btrace_fun_s, btinfo->functions))
 	    {
 	      /* Tracing is disabled and re-enabled each time we enter the
 		 kernel.  Most times, we continue from the same instruction we
@@ -1209,45 +1212,36 @@ ftrace_add_pt (struct pt_insn_decoder *decoder,
 		 from some other instruction.  Indicate this as a trace gap.  */
 	      if (insn.enabled)
 		{
-		  btinfo->end = ftrace_new_gap (btinfo, BDE_PT_DISABLED);
+		  bfun = ftrace_new_gap (btinfo, BDE_PT_DISABLED);
 
-		  VEC_safe_push (bfun_s, *gaps, btinfo->end);
+		  VEC_safe_push (bfun_s, *gaps, bfun);
 
 		  pt_insn_get_offset (decoder, &offset);
 
 		  warning (_("Non-contiguous trace at instruction %u (offset "
 			     "= 0x%" PRIx64 ", pc = 0x%" PRIx64 ")."),
-			   btinfo->end->insn_offset - 1, offset, insn.ip);
+			   bfun->insn_offset - 1, offset, insn.ip);
 		}
 	    }
 
 	  /* Indicate trace overflows.  */
 	  if (insn.resynced)
 	    {
-	      btinfo->end = ftrace_new_gap (btinfo, BDE_PT_OVERFLOW);
-	      if (btinfo->begin == NULL)
-		btinfo->begin = btinfo->end;
+	      bfun = ftrace_new_gap (btinfo, BDE_PT_OVERFLOW);
 
-	      VEC_safe_push (bfun_s, *gaps, btinfo->end);
+	      VEC_safe_push (bfun_s, *gaps, bfun);
 
 	      pt_insn_get_offset (decoder, &offset);
 
 	      warning (_("Overflow at instruction %u (offset = 0x%" PRIx64
 			 ", pc = 0x%" PRIx64 ")."),
-		       btinfo->end->insn_offset - 1, offset, insn.ip);
+		       bfun->insn_offset - 1, offset, insn.ip);
 	    }
 
-	  upd = ftrace_update_function (btinfo, insn.ip);
-	  if (upd != btinfo->end)
-	    {
-	      btinfo->end = upd;
-
-	      if (btinfo->begin == NULL)
-		btinfo->begin = upd;
-	    }
+	  bfun = ftrace_update_function (btinfo, insn.ip);
 
 	  /* Maintain the function level offset.  */
-	  *plevel = std::min (*plevel, btinfo->end->level);
+	  *plevel = std::min (*plevel, bfun->level);
 
 	  btinsn.pc = (CORE_ADDR) insn.ip;
 	  btinsn.size = (gdb_byte) insn.size;
@@ -1261,17 +1255,15 @@ ftrace_add_pt (struct pt_insn_decoder *decoder,
 	break;
 
       /* Indicate the gap in the trace.  */
-      btinfo->end = ftrace_new_gap (btinfo, errcode);
-      if (btinfo->begin == NULL)
-	btinfo->begin = btinfo->end;
+      bfun = ftrace_new_gap (btinfo, errcode);
 
-      VEC_safe_push (bfun_s, *gaps, btinfo->end);
+      VEC_safe_push (bfun_s, *gaps, bfun);
 
       pt_insn_get_offset (decoder, &offset);
 
       warning (_("Decode error (%d) at instruction %u (offset = 0x%" PRIx64
 		 ", pc = 0x%" PRIx64 "): %s."), errcode,
-	       btinfo->end->insn_offset - 1, offset, insn.ip,
+	       bfun->insn_offset - 1, offset, insn.ip,
 	       pt_errstr (pt_errcode (errcode)));
     }
 }
@@ -1353,7 +1345,10 @@ btrace_compute_ftrace_pt (struct thread_info *tp,
     return;
 
   btinfo = &tp->btrace;
-  level = btinfo->begin != NULL ? -btinfo->level : INT_MAX;
+  if (VEC_empty (btrace_fun_s, btinfo->functions))
+    level = INT_MAX;
+  else
+    level = -btinfo->level;
 
   pt_config_init(&config);
   config.begin = btrace->data;
@@ -1391,11 +1386,14 @@ btrace_compute_ftrace_pt (struct thread_info *tp,
   CATCH (error, RETURN_MASK_ALL)
     {
       /* Indicate a gap in the trace if we quit trace processing.  */
-      if (error.reason == RETURN_QUIT && btinfo->end != NULL)
+      if (error.reason == RETURN_QUIT && !VEC_empty (btrace_fun_s,
+						     btinfo->functions))
 	{
-	  btinfo->end = ftrace_new_gap (btinfo, BDE_PT_USER_QUIT);
+	  struct btrace_function *bfun;
+
+	  bfun = ftrace_new_gap (btinfo, BDE_PT_USER_QUIT);
 
-	  VEC_safe_push (bfun_s, *gaps, btinfo->end);
+	  VEC_safe_push (bfun_s, *gaps, bfun);
 	}
 
       btrace_finalize_ftrace_pt (decoder, tp, level);
@@ -1627,8 +1625,9 @@ btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp)
   btrace_block_s *first_new_block;
 
   btinfo = &tp->btrace;
-  last_bfun = btinfo->end;
-  gdb_assert (last_bfun != NULL);
+  gdb_assert (!VEC_empty (btrace_fun_s, btinfo->functions));
+
+  last_bfun = VEC_last (btrace_fun_s, btinfo->functions);
   gdb_assert (!VEC_empty (btrace_block_s, btrace->blocks));
 
   /* If the existing trace ends with a gap, we just glue the traces
@@ -1695,7 +1694,7 @@ btrace_stitch_bts (struct btrace_data_bts *btrace, struct thread_info *tp)
      of just that one instruction.  If we remove it, we might turn the now
      empty btrace function segment into a gap.  But we don't want gaps at
      the beginning.  To avoid this, we remove the entire old trace.  */
-  if (last_bfun == btinfo->begin && VEC_empty (btrace_insn_s, last_bfun->insn))
+  if (last_bfun->number == 1 && VEC_empty (btrace_insn_s, last_bfun->insn))
     btrace_clear (tp);
 
   return 0;
@@ -1857,7 +1856,7 @@ btrace_fetch (struct thread_info *tp)
   cleanup = make_cleanup_btrace_data (&btrace);
 
   /* Let's first try to extend the trace we already have.  */
-  if (btinfo->end != NULL)
+  if (!VEC_empty (btrace_fun_s, btinfo->functions))
     {
       errcode = target_read_btrace (&btrace, tinfo, BTRACE_READ_DELTA);
       if (errcode == 0)
@@ -1933,9 +1932,6 @@ btrace_clear (struct thread_info *tp)
     }
 
   VEC_truncate (btrace_fun_s, btinfo->functions, 0);
-
-  btinfo->begin = NULL;
-  btinfo->end = NULL;
   btinfo->ngaps = 0;
 
   /* Must clear the maint data before - it depends on BTINFO->DATA.  */
@@ -2324,10 +2320,7 @@ void
 btrace_insn_begin (struct btrace_insn_iterator *it,
 		   const struct btrace_thread_info *btinfo)
 {
-  const struct btrace_function *bfun;
-
-  bfun = btinfo->begin;
-  if (bfun == NULL)
+  if (VEC_empty (btrace_fun_s, btinfo->functions))
     error (_("No trace."));
 
   it->btinfo = btinfo;
@@ -2344,10 +2337,10 @@ btrace_insn_end (struct btrace_insn_iterator *it,
   const struct btrace_function *bfun;
   unsigned int length;
 
-  bfun = btinfo->end;
-  if (bfun == NULL)
+  if (VEC_empty (btrace_fun_s, btinfo->functions))
     error (_("No trace."));
 
+  bfun = VEC_last (btrace_fun_s, btinfo->functions);
   length = VEC_length (btrace_insn_s, bfun->insn);
 
   /* The last function may either be a gap or it contains the current
@@ -2780,7 +2773,7 @@ btrace_is_empty (struct thread_info *tp)
 
   btinfo = &tp->btrace;
 
-  if (btinfo->begin == NULL)
+  if (VEC_empty (btrace_fun_s, btinfo->functions))
     return 1;
 
   btrace_insn_begin (&begin, btinfo);
diff --git a/gdb/btrace.h b/gdb/btrace.h
index 8f8a7fa..d238d4f 100644
--- a/gdb/btrace.h
+++ b/gdb/btrace.h
@@ -335,7 +335,6 @@ struct btrace_thread_info
      part of the execution history.
      Both will be NULL if there is no branch trace available.  If there is
      branch trace available, both will be non-NULL.  */
-  struct btrace_function *begin;
   struct btrace_function *end;
 
   /* Vector of decoded function call segments in execution flow order.  Note
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index 7ba3844..160424e 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -1928,7 +1928,7 @@ record_btrace_start_replaying (struct thread_info *tp)
   replay = NULL;
 
   /* We can't start replaying without trace.  */
-  if (btinfo->begin == NULL)
+  if (VEC_empty (btrace_fun_s, btinfo->functions))
     return NULL;
 
   /* GDB stores the current frame_id when stepping in order to detects steps
-- 
2.7.4


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]