commit d918a8fb8cbca3b3ac6c73fc62b38d21f5b70386 Author: Joel Brobecker Date: Thu Sep 3 11:16:44 2009 -0700 Avoid quadratic behavior when computing the value of a register. * frame.c (frame_cache): New static constant. (frame_cache_add, frame_cache_find, frame_cache_invalidate): New functions. (get_frame_id): Minor reformatting. Add the frame to the frame cache. (frame_find_by_id): Search the frame cache first before walking all frames starting from te current_frame. (reinit_frame_cache): Add call to frame_cache_invalidate (); diff --git a/gdb/frame.c b/gdb/frame.c index 67e0607..c12be5e 100644 --- a/gdb/frame.c +++ b/gdb/frame.c @@ -122,6 +122,37 @@ struct frame_info enum unwind_stop_reason stop_reason; }; +/* A Frame cache used to speed up frame lookups. */ + +/* We currently only cache one frame, as this seems to be sufficient + for now. */ +static struct frame_info *frame_cache = NULL; + +/* Add the following FRAME to the frame cache. */ +static void +frame_cache_add (struct frame_info *frame) +{ + frame_cache = frame; +} + +/* Search the frame cache for an entry with the given frame ID. + If found, return that frame. Otherwise return NULL. */ +static struct frame_info * +frame_cache_find (struct frame_id id) +{ + if (frame_cache && frame_id_eq (frame_cache->this_id.value, id)) + return frame_cache; + + return NULL; +} + +/* Invalidate the frame cache by removing all entries in the cache. */ +static void +frame_cache_invalidate (void) +{ + frame_cache = NULL; +} + /* Flag to control debugging. */ int frame_debug; @@ -279,9 +310,8 @@ struct frame_id get_frame_id (struct frame_info *fi) { if (fi == NULL) - { - return null_frame_id; - } + return null_frame_id; + if (!fi->this_id.p) { if (frame_debug) @@ -300,6 +330,9 @@ get_frame_id (struct frame_info *fi) fprintf_unfiltered (gdb_stdlog, " }\n"); } } + + frame_cache_add (fi); + return fi->this_id.value; } @@ -514,6 +547,11 @@ frame_find_by_id (struct frame_id id) if (!frame_id_p (id)) return NULL; + /* Try using the frame cache first. */ + frame = frame_cache_find (id); + if (frame && frame_id_eq (frame->this_id.value, id)) + return frame; + for (frame = get_current_frame (); ; frame = prev_frame) { struct frame_id this = get_frame_id (frame); @@ -1285,6 +1323,7 @@ reinit_frame_cache (void) current_frame = NULL; /* Invalidate cache */ select_frame (NULL); + frame_cache_invalidate (); if (frame_debug) fprintf_unfiltered (gdb_stdlog, "{ reinit_frame_cache () }\n"); }