2003-05-04 Andrew Cagney <cagney@redhat.com>

* gdbthread.h (save_infrun_state): Drop prev_func_name parameter.
	(load_infrun_state): Ditto.
	(struct thread_info): Drop "prev_func_name" field.
	* thread.c (load_infrun_state): Update.
	(save_infrun_state): Update.
	* infrun.c (prev_func_name): Delete variable.
	(init_wait_for_inferior): Do not clear prev_func_name.
	(stop_stepping, keep_going, context_switch): Do not swap
	prev_func_name.
	(handle_inferior_event, check_sigtramp2): Use pc_in_sigtramp
	instead of PC_IN_SIGTRAMP.
This commit is contained in:
Andrew Cagney 2003-05-05 00:27:08 +00:00
parent 7ac151b7c8
commit 0ce3d317be
4 changed files with 57 additions and 22 deletions

View file

@ -1,3 +1,17 @@
2003-05-04 Andrew Cagney <cagney@redhat.com>
* gdbthread.h (save_infrun_state): Drop prev_func_name parameter.
(load_infrun_state): Ditto.
(struct thread_info): Drop "prev_func_name" field.
* thread.c (load_infrun_state): Update.
(save_infrun_state): Update.
* infrun.c (prev_func_name): Delete variable.
(init_wait_for_inferior): Do not clear prev_func_name.
(stop_stepping, keep_going, context_switch): Do not swap
prev_func_name.
(handle_inferior_event, check_sigtramp2): Use pc_in_sigtramp
instead of PC_IN_SIGTRAMP.
2003-05-04 Andrew Cagney <cagney@redhat.com> 2003-05-04 Andrew Cagney <cagney@redhat.com>
* sentinel-frame.c (sentinel_frame_prev_register): Replace * sentinel-frame.c (sentinel_frame_prev_register): Replace

View file

@ -44,7 +44,6 @@ struct thread_info
int num; /* Convenient handle (GDB thread id) */ int num; /* Convenient handle (GDB thread id) */
/* State from wait_for_inferior */ /* State from wait_for_inferior */
CORE_ADDR prev_pc; CORE_ADDR prev_pc;
char *prev_func_name;
struct breakpoint *step_resume_breakpoint; struct breakpoint *step_resume_breakpoint;
struct breakpoint *through_sigtramp_breakpoint; struct breakpoint *through_sigtramp_breakpoint;
CORE_ADDR step_range_start; CORE_ADDR step_range_start;
@ -117,7 +116,6 @@ extern struct thread_info *iterate_over_threads (thread_callback_func, void *);
/* infrun context switch: save the debugger state for the given thread. */ /* infrun context switch: save the debugger state for the given thread. */
extern void save_infrun_state (ptid_t ptid, extern void save_infrun_state (ptid_t ptid,
CORE_ADDR prev_pc, CORE_ADDR prev_pc,
char *prev_func_name,
int trap_expected, int trap_expected,
struct breakpoint *step_resume_breakpoint, struct breakpoint *step_resume_breakpoint,
struct breakpoint *through_sigtramp_breakpoint, struct breakpoint *through_sigtramp_breakpoint,
@ -137,7 +135,6 @@ extern void save_infrun_state (ptid_t ptid,
for the given thread. */ for the given thread. */
extern void load_infrun_state (ptid_t ptid, extern void load_infrun_state (ptid_t ptid,
CORE_ADDR *prev_pc, CORE_ADDR *prev_pc,
char **prev_func_name,
int *trap_expected, int *trap_expected,
struct breakpoint **step_resume_breakpoint, struct breakpoint **step_resume_breakpoint,
struct breakpoint **through_sigtramp_breakpoint, struct breakpoint **through_sigtramp_breakpoint,

View file

@ -786,12 +786,10 @@ proceed (CORE_ADDR addr, enum target_signal siggnal, int step)
} }
} }
/* Record the pc and sp of the program the last time it stopped. /* Record the pc of the program the last time it stopped. This is
These are just used internally by wait_for_inferior, but need just used internally by wait_for_inferior, but need to be preserved
to be preserved over calls to it and cleared when the inferior over calls to it and cleared when the inferior is started. */
is started. */
static CORE_ADDR prev_pc; static CORE_ADDR prev_pc;
static char *prev_func_name;
/* Start remote-debugging of a machine over a serial link. */ /* Start remote-debugging of a machine over a serial link. */
@ -829,7 +827,6 @@ init_wait_for_inferior (void)
{ {
/* These are meaningless until the first time through wait_for_inferior. */ /* These are meaningless until the first time through wait_for_inferior. */
prev_pc = 0; prev_pc = 0;
prev_func_name = NULL;
#ifdef HP_OS_BUG #ifdef HP_OS_BUG
trap_expected_after_continue = 0; trap_expected_after_continue = 0;
@ -1116,7 +1113,7 @@ context_switch (struct execution_control_state *ecs)
if (in_thread_list (inferior_ptid) && in_thread_list (ecs->ptid)) if (in_thread_list (inferior_ptid) && in_thread_list (ecs->ptid))
{ /* Perform infrun state context switch: */ { /* Perform infrun state context switch: */
/* Save infrun state for the old thread. */ /* Save infrun state for the old thread. */
save_infrun_state (inferior_ptid, prev_pc, prev_func_name, save_infrun_state (inferior_ptid, prev_pc,
trap_expected, step_resume_breakpoint, trap_expected, step_resume_breakpoint,
through_sigtramp_breakpoint, step_range_start, through_sigtramp_breakpoint, step_range_start,
step_range_end, &step_frame_id, step_range_end, &step_frame_id,
@ -1127,7 +1124,7 @@ context_switch (struct execution_control_state *ecs)
ecs->current_line, ecs->current_symtab, step_sp); ecs->current_line, ecs->current_symtab, step_sp);
/* Load infrun state for the new thread. */ /* Load infrun state for the new thread. */
load_infrun_state (ecs->ptid, &prev_pc, &prev_func_name, load_infrun_state (ecs->ptid, &prev_pc,
&trap_expected, &step_resume_breakpoint, &trap_expected, &step_resume_breakpoint,
&through_sigtramp_breakpoint, &step_range_start, &through_sigtramp_breakpoint, &step_range_start,
&step_range_end, &step_frame_id, &step_range_end, &step_frame_id,
@ -1140,6 +1137,39 @@ context_switch (struct execution_control_state *ecs)
inferior_ptid = ecs->ptid; inferior_ptid = ecs->ptid;
} }
/* Wrapper for PC_IN_SIGTRAMP that takes care of the need to find the
function's name.
In a classic example of "left hand VS right hand", "infrun.c" was
trying to improve GDB's performance by caching the result of calls
to calls to find_pc_partial_funtion, while at the same time
find_pc_partial_function was also trying to ramp up performance by
caching its most recent return value. The below makes the the
function find_pc_partial_function solely responsibile for
performance issues (the local cache that relied on a global
variable - arrrggg - deleted).
Using the testsuite and gcov, it was found that dropping the local
"infrun.c" cache and instead relying on find_pc_partial_function
increased the number of calls to 12000 (from 10000), but the number
of times find_pc_partial_function's cache missed (this is what
matters) was only increased by only 4 (to 3569). (A quick back of
envelope caculation suggests that the extra 2000 function calls
@1000 extra instructions per call make the 1 MIP VAX testsuite run
take two extra seconds, oops :-)
Long term, this function can be eliminated, replaced by the code:
get_frame_type(current_frame()) == SIGTRAMP_FRAME (for new
architectures this is very cheap). */
static int
pc_in_sigtramp (CORE_ADDR pc)
{
char *name;
find_pc_partial_function (pc, &name, NULL, NULL);
return PC_IN_SIGTRAMP (pc, name);
}
/* Given an execution control state that has been freshly filled in /* Given an execution control state that has been freshly filled in
by an event from the inferior, figure out what it means and take by an event from the inferior, figure out what it means and take
@ -2262,8 +2292,8 @@ process_event_stop_test:
ecs->update_step_sp = 1; ecs->update_step_sp = 1;
/* Did we just take a signal? */ /* Did we just take a signal? */
if (PC_IN_SIGTRAMP (stop_pc, ecs->stop_func_name) if (pc_in_sigtramp (stop_pc)
&& !PC_IN_SIGTRAMP (prev_pc, prev_func_name) && !pc_in_sigtramp (prev_pc)
&& INNER_THAN (read_sp (), step_sp)) && INNER_THAN (read_sp (), step_sp))
{ {
/* We've just taken a signal; go until we are back to /* We've just taken a signal; go until we are back to
@ -2373,7 +2403,7 @@ process_event_stop_test:
{ {
/* We're doing a "next". */ /* We're doing a "next". */
if (PC_IN_SIGTRAMP (stop_pc, ecs->stop_func_name) if (pc_in_sigtramp (stop_pc)
&& frame_id_inner (step_frame_id, && frame_id_inner (step_frame_id,
frame_id_build (read_sp (), 0))) frame_id_build (read_sp (), 0)))
/* We stepped out of a signal handler, and into its /* We stepped out of a signal handler, and into its
@ -2562,8 +2592,8 @@ static void
check_sigtramp2 (struct execution_control_state *ecs) check_sigtramp2 (struct execution_control_state *ecs)
{ {
if (trap_expected if (trap_expected
&& PC_IN_SIGTRAMP (stop_pc, ecs->stop_func_name) && pc_in_sigtramp (stop_pc)
&& !PC_IN_SIGTRAMP (prev_pc, prev_func_name) && !pc_in_sigtramp (prev_pc)
&& INNER_THAN (read_sp (), step_sp)) && INNER_THAN (read_sp (), step_sp))
{ {
/* What has happened here is that we have just stepped the /* What has happened here is that we have just stepped the
@ -2733,7 +2763,6 @@ stop_stepping (struct execution_control_state *ecs)
time, just like we did above if we didn't break out of the time, just like we did above if we didn't break out of the
loop. */ loop. */
prev_pc = read_pc (); prev_pc = read_pc ();
prev_func_name = ecs->stop_func_name;
} }
/* Let callers know we don't want to wait for the inferior anymore. */ /* Let callers know we don't want to wait for the inferior anymore. */
@ -2749,7 +2778,6 @@ keep_going (struct execution_control_state *ecs)
{ {
/* Save the pc before execution, to compare with pc after stop. */ /* Save the pc before execution, to compare with pc after stop. */
prev_pc = read_pc (); /* Might have been DECR_AFTER_BREAK */ prev_pc = read_pc (); /* Might have been DECR_AFTER_BREAK */
prev_func_name = ecs->stop_func_name;
if (ecs->update_step_sp) if (ecs->update_step_sp)
step_sp = read_sp (); step_sp = read_sp ();

View file

@ -292,7 +292,6 @@ gdb_list_thread_ids (struct ui_out *uiout)
void void
load_infrun_state (ptid_t ptid, load_infrun_state (ptid_t ptid,
CORE_ADDR *prev_pc, CORE_ADDR *prev_pc,
char **prev_func_name,
int *trap_expected, int *trap_expected,
struct breakpoint **step_resume_breakpoint, struct breakpoint **step_resume_breakpoint,
struct breakpoint **through_sigtramp_breakpoint, struct breakpoint **through_sigtramp_breakpoint,
@ -316,7 +315,6 @@ load_infrun_state (ptid_t ptid,
return; return;
*prev_pc = tp->prev_pc; *prev_pc = tp->prev_pc;
*prev_func_name = tp->prev_func_name;
*trap_expected = tp->trap_expected; *trap_expected = tp->trap_expected;
*step_resume_breakpoint = tp->step_resume_breakpoint; *step_resume_breakpoint = tp->step_resume_breakpoint;
*through_sigtramp_breakpoint = tp->through_sigtramp_breakpoint; *through_sigtramp_breakpoint = tp->through_sigtramp_breakpoint;
@ -340,7 +338,6 @@ load_infrun_state (ptid_t ptid,
void void
save_infrun_state (ptid_t ptid, save_infrun_state (ptid_t ptid,
CORE_ADDR prev_pc, CORE_ADDR prev_pc,
char *prev_func_name,
int trap_expected, int trap_expected,
struct breakpoint *step_resume_breakpoint, struct breakpoint *step_resume_breakpoint,
struct breakpoint *through_sigtramp_breakpoint, struct breakpoint *through_sigtramp_breakpoint,
@ -364,7 +361,6 @@ save_infrun_state (ptid_t ptid,
return; return;
tp->prev_pc = prev_pc; tp->prev_pc = prev_pc;
tp->prev_func_name = prev_func_name;
tp->trap_expected = trap_expected; tp->trap_expected = trap_expected;
tp->step_resume_breakpoint = step_resume_breakpoint; tp->step_resume_breakpoint = step_resume_breakpoint;
tp->through_sigtramp_breakpoint = through_sigtramp_breakpoint; tp->through_sigtramp_breakpoint = through_sigtramp_breakpoint;