From: Tim Wiederhake <tim.wiederhake@intel.com>
To: gdb-patches@sourceware.org
Cc: markus.t.metzger@intel.com
Subject: [PATCH 04/11] btrace: Use function segment index in call iterator.
Date: Fri, 17 Feb 2017 13:27:00 -0000 [thread overview]
Message-ID: <1487337989-6367-5-git-send-email-tim.wiederhake@intel.com> (raw)
In-Reply-To: <1487337989-6367-1-git-send-email-tim.wiederhake@intel.com>
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
next prev parent reply other threads:[~2017-02-17 13:27 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-02-17 13:27 [PATCH 00/11] btrace: Turn linked list of function call segments into vector Tim Wiederhake
2017-02-17 13:27 ` [PATCH 10/11] [SQUASH] btrace: Remove bfun_s vector Tim Wiederhake
2017-02-17 13:27 ` [PATCH 07/11] [SQUASH] btrace: Adjust struct btrace_function::up Tim Wiederhake
2017-02-24 9:33 ` Metzger, Markus T
2017-02-17 13:27 ` Tim Wiederhake [this message]
2017-02-24 9:32 ` [PATCH 04/11] btrace: Use function segment index in call iterator Metzger, Markus T
2017-02-17 13:27 ` [PATCH 03/11] btrace: Add btinfo to instruction interator Tim Wiederhake
2017-02-24 9:32 ` Metzger, Markus T
2017-02-17 13:27 ` [PATCH 11/11] [SQUASH] btrace: Cleanup Tim Wiederhake
2017-02-17 13:27 ` [PATCH 05/11] btrace: Use function segment index in insn iterator Tim Wiederhake
2017-02-24 9:32 ` Metzger, Markus T
2017-02-17 13:27 ` [PATCH 01/11] btrace: Use struct btrace_thread_info fields directly Tim Wiederhake
2017-02-17 13:27 ` [PATCH 08/11] [SQUASH] btrace: Adjust struct btrace_function::{flow,segment} Tim Wiederhake
2017-02-24 9:33 ` Metzger, Markus T
2017-02-17 13:27 ` [PATCH 06/11] [SQUASH] btrace: Save function calls in a vector Tim Wiederhake
2017-02-24 9:33 ` Metzger, Markus T
2017-02-17 13:27 ` [PATCH 09/11] [SQUASH] btrace: Remove struct btrace_thread_info::{begin,end} Tim Wiederhake
2017-02-17 13:27 ` [PATCH 02/11] btrace: Change parameters to use btrace_thread_info Tim Wiederhake
2017-02-24 9:32 ` Metzger, Markus T
2017-02-24 9:32 ` [PATCH 00/11] btrace: Turn linked list of function call segments into vector Metzger, Markus T
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1487337989-6367-5-git-send-email-tim.wiederhake@intel.com \
--to=tim.wiederhake@intel.com \
--cc=gdb-patches@sourceware.org \
--cc=markus.t.metzger@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).