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 04/11] btrace: Use function segment index in call iterator.


2017-02-17  Tim Wiederhake  <tim.wiederhake@intel.com>

gdb/ChangeLog

	* btrace.c (btrace_ends_with_single_insn): New function.
	(btrace_call_get, btrace_call_number, btrace_call_begin,
	btrace_call_end, btrace_call_next, btrace_call_prev,
	btrace_find_call_by_number): Use
	index into call segment vector instead of pointer.
	(btrace_call_cmp): Simplify.
	* btrace.h (struct btrace_call_iterator): Replace function call segment
	pointer with index into vector.
	* record-btrace.c (record_btrace_call_history): Use index instead of
	pointer.


---
 gdb/btrace.c        | 188 +++++++++++++++++++++-------------------------------
 gdb/btrace.h        |   6 +-
 gdb/record-btrace.c |   2 +-
 3 files changed, 78 insertions(+), 118 deletions(-)

diff --git a/gdb/btrace.c b/gdb/btrace.c
index 5f0eb7a..31590ce 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -2515,12 +2515,30 @@ btrace_find_insn_by_number (struct btrace_insn_iterator *it,
   return 1;
 }
 
+/* Returns a non-zero value if the recording ends with a function call segment
+   that contains only a single (i.e. the current) instruction.  */
+
+static int
+btrace_ends_with_single_insn (const struct btrace_thread_info* btinfo)
+{
+  const btrace_function *bfun;
+
+  if (VEC_empty (btrace_fun_p, btinfo->functions))
+    return 0;
+
+  bfun = VEC_last (btrace_fun_p, btinfo->functions);
+  return ftrace_call_num_insn (bfun) == 1;
+}
+
 /* See btrace.h.  */
 
 const struct btrace_function *
 btrace_call_get (const struct btrace_call_iterator *it)
 {
-  return it->function;
+  if (it->call_index >= VEC_length (btrace_fun_p, it->btinfo->functions))
+    return NULL;
+
+  return VEC_index (btrace_fun_p, it->btinfo->functions, it->call_index);
 }
 
 /* See btrace.h.  */
@@ -2528,28 +2546,12 @@ btrace_call_get (const struct btrace_call_iterator *it)
 unsigned int
 btrace_call_number (const struct btrace_call_iterator *it)
 {
-  const struct btrace_thread_info *btinfo;
-  const struct btrace_function *bfun;
-  unsigned int insns;
-
-  btinfo = it->btinfo;
-  bfun = it->function;
-  if (bfun != NULL)
-    return bfun->number;
-
-  /* For the end iterator, i.e. bfun == NULL, we return one more than the
-     number of the last function.  */
-  bfun = btinfo->end;
-  insns = VEC_length (btrace_insn_s, bfun->insn);
+  const unsigned int length = VEC_length (btrace_fun_p, it->btinfo->functions);
 
-  /* If the function contains only a single instruction (i.e. the current
-     instruction), it will be skipped and its number is already the number
-     we seek.  */
-  if (insns == 1)
-    return bfun->number;
+  if ((it->call_index == length) && btrace_ends_with_single_insn (it->btinfo))
+    return length;
 
-  /* Otherwise, return one more than the number of the last function.  */
-  return bfun->number + 1;
+  return it->call_index + 1;
 }
 
 /* See btrace.h.  */
@@ -2558,14 +2560,15 @@ void
 btrace_call_begin (struct btrace_call_iterator *it,
 		   const struct btrace_thread_info *btinfo)
 {
-  const struct btrace_function *bfun;
-
-  bfun = btinfo->begin;
-  if (bfun == NULL)
+  if (VEC_empty (btrace_fun_p, btinfo->functions))
     error (_("No trace."));
 
   it->btinfo = btinfo;
-  it->function = bfun;
+  it->call_index = 0;
+
+  if ((VEC_length (btrace_fun_p, it->btinfo->functions) == 1)
+      && (btrace_ends_with_single_insn (btinfo)))
+    it->call_index = 1;
 }
 
 /* See btrace.h.  */
@@ -2574,14 +2577,11 @@ void
 btrace_call_end (struct btrace_call_iterator *it,
 		 const struct btrace_thread_info *btinfo)
 {
-  const struct btrace_function *bfun;
-
-  bfun = btinfo->end;
-  if (bfun == NULL)
+  if (VEC_empty (btrace_fun_p, btinfo->functions))
     error (_("No trace."));
 
   it->btinfo = btinfo;
-  it->function = NULL;
+  it->call_index = VEC_length (btrace_fun_p, it->btinfo->functions);
 }
 
 /* See btrace.h.  */
@@ -2589,35 +2589,29 @@ btrace_call_end (struct btrace_call_iterator *it,
 unsigned int
 btrace_call_next (struct btrace_call_iterator *it, unsigned int stride)
 {
-  const struct btrace_function *bfun;
-  unsigned int steps;
+  const unsigned int length = VEC_length (btrace_fun_p, it->btinfo->functions);
 
-  bfun = it->function;
-  steps = 0;
-  while (bfun != NULL)
+  if (it->call_index + stride < length - 1)
     {
-      const struct btrace_function *next;
-      unsigned int insns;
-
-      next = bfun->flow.next;
-      if (next == NULL)
-	{
-	  /* Ignore the last function if it only contains a single
-	     (i.e. the current) instruction.  */
-	  insns = VEC_length (btrace_insn_s, bfun->insn);
-	  if (insns == 1)
-	    steps -= 1;
-	}
-
-      if (stride == steps)
-	break;
-
-      bfun = next;
-      steps += 1;
+      it->call_index += stride;
+    }
+  else if (it->call_index + stride == length - 1)
+    {
+      if (btrace_ends_with_single_insn (it->btinfo))
+	it->call_index = length;
+      else
+	it->call_index += stride;
+    }
+  else
+    {
+      if (btrace_ends_with_single_insn (it->btinfo))
+	stride = length - it->call_index - 1;
+      else
+	stride = length - it->call_index;
+      it->call_index = length;
     }
 
-  it->function = bfun;
-  return steps;
+  return stride;
 }
 
 /* See btrace.h.  */
@@ -2625,48 +2619,30 @@ btrace_call_next (struct btrace_call_iterator *it, unsigned int stride)
 unsigned int
 btrace_call_prev (struct btrace_call_iterator *it, unsigned int stride)
 {
-  const struct btrace_thread_info *btinfo;
-  const struct btrace_function *bfun;
-  unsigned int steps;
+  const unsigned int length = VEC_length (btrace_fun_p, it->btinfo->functions);
+  int steps;
+
+  if (length == 0 || stride == 0)
+    return 0;
 
-  bfun = it->function;
   steps = 0;
 
-  if (bfun == NULL)
+  if (it->call_index >= length)
     {
-      unsigned int insns;
-
-      btinfo = it->btinfo;
-      bfun = btinfo->end;
-      if (bfun == NULL)
-	return 0;
-
-      /* Ignore the last function if it only contains a single
-	 (i.e. the current) instruction.  */
-      insns = VEC_length (btrace_insn_s, bfun->insn);
-      if (insns == 1)
-	bfun = bfun->flow.prev;
-
-      if (bfun == NULL)
-	return 0;
+      if (btrace_ends_with_single_insn (it->btinfo))
+	it->call_index = length - 2;
+      else
+	it->call_index = length - 1;
 
-      steps += 1;
+      steps = 1;
+      stride -= 1;
     }
 
-  while (steps < stride)
-    {
-      const struct btrace_function *prev;
+  if (it->call_index < stride)
+    stride = it->call_index;
 
-      prev = bfun->flow.prev;
-      if (prev == NULL)
-	break;
-
-      bfun = prev;
-      steps += 1;
-    }
-
-  it->function = bfun;
-  return steps;
+  it->call_index -= stride;
+  return steps + stride;
 }
 
 /* See btrace.h.  */
@@ -2675,12 +2651,8 @@ int
 btrace_call_cmp (const struct btrace_call_iterator *lhs,
 		 const struct btrace_call_iterator *rhs)
 {
-  unsigned int lnum, rnum;
-
-  lnum = btrace_call_number (lhs);
-  rnum = btrace_call_number (rhs);
-
-  return (int) (lnum - rnum);
+  gdb_assert (lhs->btinfo == rhs->btinfo);
+  return (int) (lhs->call_index - rhs->call_index);
 }
 
 /* See btrace.h.  */
@@ -2690,26 +2662,14 @@ btrace_find_call_by_number (struct btrace_call_iterator *it,
 			    const struct btrace_thread_info *btinfo,
 			    unsigned int number)
 {
-  const struct btrace_function *bfun;
+  const unsigned int length = VEC_length (btrace_fun_p, btinfo->functions);
 
-  for (bfun = btinfo->end; bfun != NULL; bfun = bfun->flow.prev)
-    {
-      unsigned int bnum;
-
-      bnum = bfun->number;
-      if (number == bnum)
-	{
-	  it->btinfo = btinfo;
-	  it->function = bfun;
-	  return 1;
-	}
-
-      /* Functions are ordered and numbered consecutively.  We could bail out
-	 earlier.  On the other hand, it is very unlikely that we search for
-	 a nonexistent function.  */
-  }
+  if ((number == 0) || (number > length))
+    return 0;
 
-  return 0;
+  it->btinfo = btinfo;
+  it->call_index = number - 1;
+  return 1;
 }
 
 /* See btrace.h.  */
diff --git a/gdb/btrace.h b/gdb/btrace.h
index f912b04..c49b114 100644
--- a/gdb/btrace.h
+++ b/gdb/btrace.h
@@ -210,9 +210,9 @@ struct btrace_call_iterator
   /* The branch trace information for this thread.  Will never be NULL.  */
   const struct btrace_thread_info *btinfo;
 
-  /* The branch trace function segment.
-     This will be NULL for the iterator pointing to the end of the trace.  */
-  const struct btrace_function *function;
+  /* The index of the function call segment in struct btrace_thread_info's
+     FUNCTIONS vector.  Note that index + 1 == number.  */
+  unsigned int call_index;
 };
 
 /* Branch trace iteration state for "record instruction-history".  */
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index f7683f2..ba83be0 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -1110,8 +1110,8 @@ record_btrace_call_history (struct target_ops *self, int size, int int_flags)
       replay = btinfo->replay;
       if (replay != NULL)
 	{
-	  begin.function = replay->function;
 	  begin.btinfo = btinfo;
+	  begin.call_index = replay->function->number - 1;
 	}
       else
 	btrace_call_end (&begin, btinfo);
-- 
2.7.4


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