btrace: Replace struct btrace_function::segment.
This used to hold a pair of pointers to the previous and next function segment that belong to this function call. Replace with a pair of indices into the vector of function segments.
This commit is contained in:
parent
eb8f2b9c44
commit
4aeb0dfcc4
5 changed files with 57 additions and 37 deletions
|
@ -1,3 +1,19 @@
|
||||||
|
2017-05-30 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||||
|
|
||||||
|
* btrace.c (ftrace_fixup_caller, ftrace_new_return, ftrace_connect_bfun,
|
||||||
|
ftrace_bridge_gap): Replace references to btrace_thread_info::segment
|
||||||
|
with btrace_thread_info::next_segment and
|
||||||
|
btrace_thread_info::prev_segment.
|
||||||
|
* btrace.h: Remove struct btrace_func_link.
|
||||||
|
(struct btrace_function): Replace pair of function segment pointers
|
||||||
|
with pair of indices.
|
||||||
|
* python/py-record-btrace.c (btpy_call_prev_sibling,
|
||||||
|
btpy_call_next_sibling): Replace references to
|
||||||
|
btrace_thread_info::segment with btrace_thread_info::next_segment and
|
||||||
|
btrace_thread_info::prev_segment.
|
||||||
|
* record-btrace.c (record_btrace_frame_this_id): Use
|
||||||
|
btrace_find_call_by_number.
|
||||||
|
|
||||||
2017-05-30 Tim Wiederhake <tim.wiederhake@intel.com>
|
2017-05-30 Tim Wiederhake <tim.wiederhake@intel.com>
|
||||||
|
|
||||||
* btrace.c (ftrace_new_function, ftrace_fixup_level,
|
* btrace.c (ftrace_new_function, ftrace_fixup_level,
|
||||||
|
|
48
gdb/btrace.c
48
gdb/btrace.c
|
@ -271,20 +271,29 @@ ftrace_update_caller (struct btrace_function *bfun,
|
||||||
/* Fix up the caller for all segments of a function. */
|
/* Fix up the caller for all segments of a function. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ftrace_fixup_caller (struct btrace_function *bfun,
|
ftrace_fixup_caller (struct btrace_thread_info *btinfo,
|
||||||
|
struct btrace_function *bfun,
|
||||||
struct btrace_function *caller,
|
struct btrace_function *caller,
|
||||||
enum btrace_function_flag flags)
|
enum btrace_function_flag flags)
|
||||||
{
|
{
|
||||||
struct btrace_function *prev, *next;
|
unsigned int prev, next;
|
||||||
|
|
||||||
|
prev = bfun->prev;
|
||||||
|
next = bfun->next;
|
||||||
ftrace_update_caller (bfun, caller, flags);
|
ftrace_update_caller (bfun, caller, flags);
|
||||||
|
|
||||||
/* Update all function segments belonging to the same function. */
|
/* Update all function segments belonging to the same function. */
|
||||||
for (prev = bfun->segment.prev; prev != NULL; prev = prev->segment.prev)
|
for (; prev != 0; prev = bfun->prev)
|
||||||
ftrace_update_caller (prev, caller, flags);
|
{
|
||||||
|
bfun = ftrace_find_call_by_number (btinfo, prev);
|
||||||
|
ftrace_update_caller (bfun, caller, flags);
|
||||||
|
}
|
||||||
|
|
||||||
for (next = bfun->segment.next; next != NULL; next = next->segment.next)
|
for (; next != 0; next = bfun->next)
|
||||||
ftrace_update_caller (next, caller, flags);
|
{
|
||||||
|
bfun = ftrace_find_call_by_number (btinfo, next);
|
||||||
|
ftrace_update_caller (bfun, caller, flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add a new function segment for a call at the end of the trace.
|
/* Add a new function segment for a call at the end of the trace.
|
||||||
|
@ -414,10 +423,10 @@ ftrace_new_return (struct btrace_thread_info *btinfo,
|
||||||
{
|
{
|
||||||
/* The caller of PREV is the preceding btrace function segment in this
|
/* The caller of PREV is the preceding btrace function segment in this
|
||||||
function instance. */
|
function instance. */
|
||||||
gdb_assert (caller->segment.next == NULL);
|
gdb_assert (caller->next == 0);
|
||||||
|
|
||||||
caller->segment.next = bfun;
|
caller->next = bfun->number;
|
||||||
bfun->segment.prev = caller;
|
bfun->prev = caller->number;
|
||||||
|
|
||||||
/* Maintain the function level. */
|
/* Maintain the function level. */
|
||||||
bfun->level = caller->level;
|
bfun->level = caller->level;
|
||||||
|
@ -449,7 +458,7 @@ ftrace_new_return (struct btrace_thread_info *btinfo,
|
||||||
bfun->level = prev->level - 1;
|
bfun->level = prev->level - 1;
|
||||||
|
|
||||||
/* Fix up the call stack for PREV. */
|
/* Fix up the call stack for PREV. */
|
||||||
ftrace_fixup_caller (prev, bfun, BFUN_UP_LINKS_TO_RET);
|
ftrace_fixup_caller (btinfo, prev, bfun, BFUN_UP_LINKS_TO_RET);
|
||||||
|
|
||||||
ftrace_debug (bfun, "new return - no caller");
|
ftrace_debug (bfun, "new return - no caller");
|
||||||
}
|
}
|
||||||
|
@ -752,11 +761,11 @@ ftrace_connect_bfun (struct btrace_thread_info *btinfo,
|
||||||
ftrace_debug (next, "..next");
|
ftrace_debug (next, "..next");
|
||||||
|
|
||||||
/* The function segments are not yet connected. */
|
/* The function segments are not yet connected. */
|
||||||
gdb_assert (prev->segment.next == NULL);
|
gdb_assert (prev->next == 0);
|
||||||
gdb_assert (next->segment.prev == NULL);
|
gdb_assert (next->prev == 0);
|
||||||
|
|
||||||
prev->segment.next = next;
|
prev->next = next->number;
|
||||||
next->segment.prev = prev;
|
next->prev = prev->number;
|
||||||
|
|
||||||
/* We may have moved NEXT to a different function level. */
|
/* We may have moved NEXT to a different function level. */
|
||||||
ftrace_fixup_level (btinfo, next, prev->level - next->level);
|
ftrace_fixup_level (btinfo, next, prev->level - next->level);
|
||||||
|
@ -770,7 +779,7 @@ ftrace_connect_bfun (struct btrace_thread_info *btinfo,
|
||||||
if (next != NULL)
|
if (next != NULL)
|
||||||
{
|
{
|
||||||
DEBUG_FTRACE ("using next's callers");
|
DEBUG_FTRACE ("using next's callers");
|
||||||
ftrace_fixup_caller (prev, next, flags);
|
ftrace_fixup_caller (btinfo, prev, next, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (next->up == 0)
|
else if (next->up == 0)
|
||||||
|
@ -781,7 +790,7 @@ ftrace_connect_bfun (struct btrace_thread_info *btinfo,
|
||||||
if (prev != NULL)
|
if (prev != NULL)
|
||||||
{
|
{
|
||||||
DEBUG_FTRACE ("using prev's callers");
|
DEBUG_FTRACE ("using prev's callers");
|
||||||
ftrace_fixup_caller (next, prev, flags);
|
ftrace_fixup_caller (btinfo, next, prev, flags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -809,7 +818,7 @@ ftrace_connect_bfun (struct btrace_thread_info *btinfo,
|
||||||
DEBUG_FTRACE ("adding prev's tail calls to next");
|
DEBUG_FTRACE ("adding prev's tail calls to next");
|
||||||
|
|
||||||
prev = ftrace_find_call_by_number (btinfo, prev->up);
|
prev = ftrace_find_call_by_number (btinfo, prev->up);
|
||||||
ftrace_fixup_caller (next, prev, prev_flags);
|
ftrace_fixup_caller (btinfo, next, prev, prev_flags);
|
||||||
|
|
||||||
for (; prev != NULL; prev = ftrace_find_call_by_number (btinfo,
|
for (; prev != NULL; prev = ftrace_find_call_by_number (btinfo,
|
||||||
prev->up))
|
prev->up))
|
||||||
|
@ -821,7 +830,7 @@ ftrace_connect_bfun (struct btrace_thread_info *btinfo,
|
||||||
ftrace_debug (prev, "..top");
|
ftrace_debug (prev, "..top");
|
||||||
ftrace_debug (caller, "..up");
|
ftrace_debug (caller, "..up");
|
||||||
|
|
||||||
ftrace_fixup_caller (prev, caller, next_flags);
|
ftrace_fixup_caller (btinfo, prev, caller, next_flags);
|
||||||
|
|
||||||
/* If we skipped any tail calls, this may move CALLER to a
|
/* If we skipped any tail calls, this may move CALLER to a
|
||||||
different function level.
|
different function level.
|
||||||
|
@ -944,14 +953,13 @@ ftrace_bridge_gap (struct btrace_thread_info *btinfo,
|
||||||
static void
|
static void
|
||||||
btrace_bridge_gaps (struct thread_info *tp, VEC (bfun_s) **gaps)
|
btrace_bridge_gaps (struct thread_info *tp, VEC (bfun_s) **gaps)
|
||||||
{
|
{
|
||||||
struct btrace_thread_info *btinfo;
|
struct btrace_thread_info *btinfo = &tp->btrace;
|
||||||
VEC (bfun_s) *remaining;
|
VEC (bfun_s) *remaining;
|
||||||
struct cleanup *old_chain;
|
struct cleanup *old_chain;
|
||||||
int min_matches;
|
int min_matches;
|
||||||
|
|
||||||
DEBUG ("bridge gaps");
|
DEBUG ("bridge gaps");
|
||||||
|
|
||||||
btinfo = &tp->btrace;
|
|
||||||
remaining = NULL;
|
remaining = NULL;
|
||||||
old_chain = make_cleanup (VEC_cleanup (bfun_s), &remaining);
|
old_chain = make_cleanup (VEC_cleanup (bfun_s), &remaining);
|
||||||
|
|
||||||
|
|
17
gdb/btrace.h
17
gdb/btrace.h
|
@ -85,13 +85,6 @@ struct btrace_insn
|
||||||
typedef struct btrace_insn btrace_insn_s;
|
typedef struct btrace_insn btrace_insn_s;
|
||||||
DEF_VEC_O (btrace_insn_s);
|
DEF_VEC_O (btrace_insn_s);
|
||||||
|
|
||||||
/* A doubly-linked list of branch trace function segments. */
|
|
||||||
struct btrace_func_link
|
|
||||||
{
|
|
||||||
struct btrace_function *prev;
|
|
||||||
struct btrace_function *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Flags for btrace function segments. */
|
/* Flags for btrace function segments. */
|
||||||
enum btrace_function_flag
|
enum btrace_function_flag
|
||||||
{
|
{
|
||||||
|
@ -146,10 +139,12 @@ struct btrace_function
|
||||||
struct minimal_symbol *msym;
|
struct minimal_symbol *msym;
|
||||||
struct symbol *sym;
|
struct symbol *sym;
|
||||||
|
|
||||||
/* The previous and next segment belonging to the same function.
|
/* The function segment numbers of the previous and next segment belonging to
|
||||||
If a function calls another function, the former will have at least
|
the same function. If a function calls another function, the former will
|
||||||
two segments: one before the call and another after the return. */
|
have at least two segments: one before the call and another after the
|
||||||
struct btrace_func_link segment;
|
return. Will be zero if there is no such function segment. */
|
||||||
|
unsigned int prev;
|
||||||
|
unsigned int next;
|
||||||
|
|
||||||
/* The function segment number of the directly preceding function segment in
|
/* The function segment number of the directly preceding function segment in
|
||||||
a (fake) call stack. Will be zero if there is no such function segment in
|
a (fake) call stack. Will be zero if there is no such function segment in
|
||||||
|
|
|
@ -416,11 +416,11 @@ recpy_bt_func_prev (PyObject *self, void *closure)
|
||||||
if (func == NULL)
|
if (func == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (func->segment.prev == NULL)
|
if (func->prev == 0)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
|
||||||
return recpy_func_new (((recpy_element_object *) self)->ptid,
|
return recpy_func_new (((recpy_element_object *) self)->ptid,
|
||||||
RECORD_METHOD_BTRACE, func->segment.prev->number);
|
RECORD_METHOD_BTRACE, func->prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of RecordFunctionSegment.next [RecordFunctionSegment] for
|
/* Implementation of RecordFunctionSegment.next [RecordFunctionSegment] for
|
||||||
|
@ -434,11 +434,11 @@ recpy_bt_func_next (PyObject *self, void *closure)
|
||||||
if (func == NULL)
|
if (func == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (func->segment.next == NULL)
|
if (func->next == 0)
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
|
|
||||||
return recpy_func_new (((recpy_element_object *) self)->ptid,
|
return recpy_func_new (((recpy_element_object *) self)->ptid,
|
||||||
RECORD_METHOD_BTRACE, func->segment.next->number);
|
RECORD_METHOD_BTRACE, func->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Implementation of BtraceList.__len__ (self) -> int. */
|
/* Implementation of BtraceList.__len__ (self) -> int. */
|
||||||
|
|
|
@ -1584,6 +1584,7 @@ record_btrace_frame_this_id (struct frame_info *this_frame, void **this_cache,
|
||||||
{
|
{
|
||||||
const struct btrace_frame_cache *cache;
|
const struct btrace_frame_cache *cache;
|
||||||
const struct btrace_function *bfun;
|
const struct btrace_function *bfun;
|
||||||
|
struct btrace_call_iterator it;
|
||||||
CORE_ADDR code, special;
|
CORE_ADDR code, special;
|
||||||
|
|
||||||
cache = (const struct btrace_frame_cache *) *this_cache;
|
cache = (const struct btrace_frame_cache *) *this_cache;
|
||||||
|
@ -1591,8 +1592,8 @@ record_btrace_frame_this_id (struct frame_info *this_frame, void **this_cache,
|
||||||
bfun = cache->bfun;
|
bfun = cache->bfun;
|
||||||
gdb_assert (bfun != NULL);
|
gdb_assert (bfun != NULL);
|
||||||
|
|
||||||
while (bfun->segment.prev != NULL)
|
while (btrace_find_call_by_number (&it, &cache->tp->btrace, bfun->prev) != 0)
|
||||||
bfun = bfun->segment.prev;
|
bfun = btrace_call_get (&it);
|
||||||
|
|
||||||
code = get_frame_func (this_frame);
|
code = get_frame_func (this_frame);
|
||||||
special = bfun->number;
|
special = bfun->number;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue