From 0ce3d317be781807abc8bf2643cd7e03e8dcbac5 Mon Sep 17 00:00:00 2001 From: Andrew Cagney Date: Mon, 5 May 2003 00:27:08 +0000 Subject: [PATCH] 2003-05-04 Andrew Cagney * 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. --- gdb/ChangeLog | 14 ++++++++++++ gdb/gdbthread.h | 3 --- gdb/infrun.c | 58 ++++++++++++++++++++++++++++++++++++------------- gdb/thread.c | 4 ---- 4 files changed, 57 insertions(+), 22 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 9de8f01673..60157253af 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,17 @@ +2003-05-04 Andrew Cagney + + * 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 * sentinel-frame.c (sentinel_frame_prev_register): Replace diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h index f336d91f48..09dea26ca8 100644 --- a/gdb/gdbthread.h +++ b/gdb/gdbthread.h @@ -44,7 +44,6 @@ struct thread_info int num; /* Convenient handle (GDB thread id) */ /* State from wait_for_inferior */ CORE_ADDR prev_pc; - char *prev_func_name; struct breakpoint *step_resume_breakpoint; struct breakpoint *through_sigtramp_breakpoint; 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. */ extern void save_infrun_state (ptid_t ptid, CORE_ADDR prev_pc, - char *prev_func_name, int trap_expected, struct breakpoint *step_resume_breakpoint, struct breakpoint *through_sigtramp_breakpoint, @@ -137,7 +135,6 @@ extern void save_infrun_state (ptid_t ptid, for the given thread. */ extern void load_infrun_state (ptid_t ptid, CORE_ADDR *prev_pc, - char **prev_func_name, int *trap_expected, struct breakpoint **step_resume_breakpoint, struct breakpoint **through_sigtramp_breakpoint, diff --git a/gdb/infrun.c b/gdb/infrun.c index 9503b106fa..9a0c99f90b 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 (); diff --git a/gdb/thread.c b/gdb/thread.c index 53a2d4f49f..315f33b1c4 100644 --- a/gdb/thread.c +++ b/gdb/thread.c @@ -292,7 +292,6 @@ gdb_list_thread_ids (struct ui_out *uiout) void load_infrun_state (ptid_t ptid, CORE_ADDR *prev_pc, - char **prev_func_name, int *trap_expected, struct breakpoint **step_resume_breakpoint, struct breakpoint **through_sigtramp_breakpoint, @@ -316,7 +315,6 @@ load_infrun_state (ptid_t ptid, return; *prev_pc = tp->prev_pc; - *prev_func_name = tp->prev_func_name; *trap_expected = tp->trap_expected; *step_resume_breakpoint = tp->step_resume_breakpoint; *through_sigtramp_breakpoint = tp->through_sigtramp_breakpoint; @@ -340,7 +338,6 @@ load_infrun_state (ptid_t ptid, void save_infrun_state (ptid_t ptid, CORE_ADDR prev_pc, - char *prev_func_name, int trap_expected, struct breakpoint *step_resume_breakpoint, struct breakpoint *through_sigtramp_breakpoint, @@ -364,7 +361,6 @@ save_infrun_state (ptid_t ptid, return; tp->prev_pc = prev_pc; - tp->prev_func_name = prev_func_name; tp->trap_expected = trap_expected; tp->step_resume_breakpoint = step_resume_breakpoint; tp->through_sigtramp_breakpoint = through_sigtramp_breakpoint; -- 2.34.1