aboutsummaryrefslogtreecommitdiff
path: root/gdb/infrun.c
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2003-05-05 00:27:08 +0000
committerAndrew Cagney <cagney@redhat.com>2003-05-05 00:27:08 +0000
commit0ce3d317be781807abc8bf2643cd7e03e8dcbac5 (patch)
treea6bacf9d5a2a2ba91c69a8003210dcb0aa325538 /gdb/infrun.c
parent7ac151b7c8b6725044d1ca406531fd408ddd6ed7 (diff)
downloadgdb-0ce3d317be781807abc8bf2643cd7e03e8dcbac5.zip
gdb-0ce3d317be781807abc8bf2643cd7e03e8dcbac5.tar.gz
gdb-0ce3d317be781807abc8bf2643cd7e03e8dcbac5.tar.bz2
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.
Diffstat (limited to 'gdb/infrun.c')
-rw-r--r--gdb/infrun.c58
1 files changed, 43 insertions, 15 deletions
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 9503b10..9a0c99f 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -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.
- These are just used internally by wait_for_inferior, but need
- to be preserved over calls to it and cleared when the inferior
- is started. */
+/* Record the pc of the program the last time it stopped. This is
+ just used internally by wait_for_inferior, but need to be preserved
+ over calls to it and cleared when the inferior is started. */
static CORE_ADDR prev_pc;
-static char *prev_func_name;
/* 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. */
prev_pc = 0;
- prev_func_name = NULL;
#ifdef HP_OS_BUG
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))
{ /* Perform infrun state context switch: */
/* 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,
through_sigtramp_breakpoint, step_range_start,
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);
/* 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,
&through_sigtramp_breakpoint, &step_range_start,
&step_range_end, &step_frame_id,
@@ -1140,6 +1137,39 @@ context_switch (struct execution_control_state *ecs)
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
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;
/* Did we just take a signal? */
- if (PC_IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
- && !PC_IN_SIGTRAMP (prev_pc, prev_func_name)
+ if (pc_in_sigtramp (stop_pc)
+ && !pc_in_sigtramp (prev_pc)
&& INNER_THAN (read_sp (), step_sp))
{
/* 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". */
- if (PC_IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
+ if (pc_in_sigtramp (stop_pc)
&& frame_id_inner (step_frame_id,
frame_id_build (read_sp (), 0)))
/* We stepped out of a signal handler, and into its
@@ -2562,8 +2592,8 @@ static void
check_sigtramp2 (struct execution_control_state *ecs)
{
if (trap_expected
- && PC_IN_SIGTRAMP (stop_pc, ecs->stop_func_name)
- && !PC_IN_SIGTRAMP (prev_pc, prev_func_name)
+ && pc_in_sigtramp (stop_pc)
+ && !pc_in_sigtramp (prev_pc)
&& INNER_THAN (read_sp (), step_sp))
{
/* 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
loop. */
prev_pc = read_pc ();
- prev_func_name = ecs->stop_func_name;
}
/* 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. */
prev_pc = read_pc (); /* Might have been DECR_AFTER_BREAK */
- prev_func_name = ecs->stop_func_name;
if (ecs->update_step_sp)
step_sp = read_sp ();