Use an std::vector for inline_states

This patch replaces VEC(inline_state) with std::vector<inline_state> and
adjusts the code that uses it.

gdb/ChangeLog:

	* common/gdb_vecs.h (unordered_remove): Add overload that takes
	an iterator.
	* inline-frame.c: Include <algorithm>.
	(struct inline_state): Add constructor.
	(inline_state_s): Remove.
	(DEF_VEC_O(inline_state_s)): Remove.
	(inline_states): Change type to std::vector.
	(find_inline_frame_state): Adjust to std::vector.
	(allocate_inline_frame_state): Remove.
	(clear_inline_frame_state): Adjust to std::vector.
	(skip_inline_frames): Adjust to std::vector.
This commit is contained in:
Simon Marchi 2018-04-09 15:40:45 -04:00 committed by Simon Marchi
parent c252925ccc
commit b24531ed17
3 changed files with 78 additions and 69 deletions

View file

@ -1,3 +1,17 @@
2018-04-09 Simon Marchi <simon.marchi@polymtl.ca>
* common/gdb_vecs.h (unordered_remove): Add overload that takes
an iterator.
* inline-frame.c: Include <algorithm>.
(struct inline_state): Add constructor.
(inline_state_s): Remove.
(DEF_VEC_O(inline_state_s)): Remove.
(inline_states): Change type to std::vector.
(find_inline_frame_state): Adjust to std::vector.
(allocate_inline_frame_state): Remove.
(clear_inline_frame_state): Adjust to std::vector.
(skip_inline_frames): Adjust to std::vector.
2018-04-09 Simon Marchi <simon.marchi@polymtl.ca>
* tracepoint.h (struct trace_state_variable): Add constructor.

View file

@ -47,6 +47,22 @@ extern void dirnames_to_char_ptr_vec_append
extern std::vector<gdb::unique_xmalloc_ptr<char>>
dirnames_to_char_ptr_vec (const char *dirnames);
/* Remove the element pointed by iterator IT from VEC, not preserving the order
of the remaining elements. Return the removed element. */
template <typename T>
T
unordered_remove (std::vector<T> &vec, typename std::vector<T>::iterator it)
{
gdb_assert (it >= vec.begin () && it < vec.end ());
T removed = std::move (*it);
*it = std::move (vec.back ());
vec.pop_back ();
return removed;
}
/* Remove the element at position IX from VEC, not preserving the order of the
remaining elements. Return the removed element. */
@ -56,11 +72,7 @@ unordered_remove (std::vector<T> &vec, typename std::vector<T>::size_type ix)
{
gdb_assert (ix < vec.size ());
T removed = std::move (vec[ix]);
vec[ix] = std::move (vec.back ());
vec.pop_back ();
return removed;
return unordered_remove (vec, vec.begin () + ix);
}
/* Remove the element at position IX from VEC, preserving the order the

View file

@ -27,6 +27,7 @@
#include "symtab.h"
#include "vec.h"
#include "frame.h"
#include <algorithm>
/* We need to save a few variables for every thread stopped at the
virtual call site of an inlined function. If there was always a
@ -34,6 +35,12 @@
keep our own list. */
struct inline_state
{
inline_state (ptid_t ptid_, int skipped_frames_, CORE_ADDR saved_pc_,
symbol *skipped_symbol_)
: ptid (ptid_), skipped_frames (skipped_frames_), saved_pc (saved_pc_),
skipped_symbol (skipped_symbol_)
{}
/* The thread this data relates to. It should be a currently
stopped thread; we assume thread IDs never change while the
thread is stopped. */
@ -55,10 +62,7 @@ struct inline_state
struct symbol *skipped_symbol;
};
typedef struct inline_state inline_state_s;
DEF_VEC_O(inline_state_s);
static VEC(inline_state_s) *inline_states;
static std::vector<inline_state> inline_states;
/* Locate saved inlined frame state for PTID, if it exists
and is valid. */
@ -66,43 +70,29 @@ static VEC(inline_state_s) *inline_states;
static struct inline_state *
find_inline_frame_state (ptid_t ptid)
{
struct inline_state *state;
int ix;
auto state_it = std::find_if (inline_states.begin (), inline_states.end (),
[&ptid] (const inline_state &state)
{
return ptid == state.ptid;
});
for (ix = 0; VEC_iterate (inline_state_s, inline_states, ix, state); ix++)
if (state_it == inline_states.end ())
return nullptr;
inline_state &state = *state_it;
struct regcache *regcache = get_thread_regcache (ptid);
CORE_ADDR current_pc = regcache_read_pc (regcache);
if (current_pc != state.saved_pc)
{
if (ptid_equal (state->ptid, ptid))
{
struct regcache *regcache = get_thread_regcache (ptid);
CORE_ADDR current_pc = regcache_read_pc (regcache);
/* PC has changed - this context is invalid. Use the
default behavior. */
if (current_pc != state->saved_pc)
{
/* PC has changed - this context is invalid. Use the
default behavior. */
VEC_unordered_remove (inline_state_s, inline_states, ix);
return NULL;
}
else
return state;
}
unordered_remove (inline_states, state_it);
return nullptr;
}
return NULL;
}
/* Allocate saved inlined frame state for PTID. */
static struct inline_state *
allocate_inline_frame_state (ptid_t ptid)
{
struct inline_state *state;
state = VEC_safe_push (inline_state_s, inline_states, NULL);
memset (state, 0, sizeof (*state));
state->ptid = ptid;
return state;
return &state;
}
/* Forget about any hidden inlined functions in PTID, which is new or
@ -112,36 +102,34 @@ allocate_inline_frame_state (ptid_t ptid)
void
clear_inline_frame_state (ptid_t ptid)
{
struct inline_state *state;
int ix;
if (ptid_equal (ptid, minus_one_ptid))
if (ptid == minus_one_ptid)
{
VEC_free (inline_state_s, inline_states);
inline_states.clear ();
return;
}
if (ptid_is_pid (ptid))
if (ptid.is_pid ())
{
VEC (inline_state_s) *new_states = NULL;
int pid = ptid_get_pid (ptid);
int pid = ptid.pid ();
auto it = std::remove_if (inline_states.begin (), inline_states.end (),
[pid] (const inline_state &state)
{
return pid == state.ptid.pid ();
});
inline_states.erase (it, inline_states.end ());
for (ix = 0;
VEC_iterate (inline_state_s, inline_states, ix, state);
ix++)
if (pid != ptid_get_pid (state->ptid))
VEC_safe_push (inline_state_s, new_states, state);
VEC_free (inline_state_s, inline_states);
inline_states = new_states;
return;
}
for (ix = 0; VEC_iterate (inline_state_s, inline_states, ix, state); ix++)
if (ptid_equal (state->ptid, ptid))
{
VEC_unordered_remove (inline_state_s, inline_states, ix);
return;
}
auto it = std::find_if (inline_states.begin (), inline_states.end (),
[&ptid] (const inline_state &state)
{
return ptid == state.ptid;
});
if (it != inline_states.end ())
unordered_remove (inline_states, it);
}
static void
@ -303,16 +291,14 @@ block_starting_point_at (CORE_ADDR pc, const struct block *block)
void
skip_inline_frames (ptid_t ptid)
{
CORE_ADDR this_pc;
const struct block *frame_block, *cur_block;
struct symbol *last_sym = NULL;
int skip_count = 0;
struct inline_state *state;
/* This function is called right after reinitializing the frame
cache. We try not to do more unwinding than absolutely
necessary, for performance. */
this_pc = get_frame_pc (get_current_frame ());
CORE_ADDR this_pc = get_frame_pc (get_current_frame ());
frame_block = block_for_pc (this_pc);
if (frame_block != NULL)
@ -341,10 +327,7 @@ skip_inline_frames (ptid_t ptid)
}
gdb_assert (find_inline_frame_state (ptid) == NULL);
state = allocate_inline_frame_state (ptid);
state->skipped_frames = skip_count;
state->saved_pc = this_pc;
state->skipped_symbol = last_sym;
inline_states.emplace_back (ptid, skip_count, this_pc, last_sym);
if (skip_count != 0)
reinit_frame_cache ();