[rfc] Frame based register cache / frame->unwind

Andrew Cagney ac131313@cygnus.com
Sun Apr 14 13:58:00 GMT 2002


Hello,

To pull together several apparently random threads.  The attached is a 
work in progress to add a frame based register cache to GDB.  It appears 
to work - NetBSD/PPC shows no regressions.

Performance is hard to quantify(1) but looks positive.  Using a native 
GDB (not typical for me :-) it appears that each frame is ~2% slower to 
create (``(gdb) up'').  Once created, the frame is ~20-25% faster 
(``(gdb) info registers'').

I'm not too worried about the apparent 2% overhead per frame create 
though.  With the patch applied, the code ends up maintaining both this 
new cache and the old ->saved_regs table.  Rewriting a target to just 
use the ->unwind_cache, should, I think, claw back the 2% and then some 
- less need to go out to the target.

There are two parts to the change and I'll describe each in turn.  The 
final patch will likely be committed as two parts.


FRAME->register_unwind(FRAME, REGNUM, ...)

This is a new per-frame method.  Given FRAME and REGNUM, it unwinds the 
register returning the value of that register as it would have been in 
the previous (calling) frame.

An implementation may be recursive.  The value of one of the previous 
frames registers may be in the next frame (available via the call 
get_saved_register(frame) == frame_register_unwind(frame->next).  The 
value of a previous frame's register isn't going to be be found in the 
previous frame :-)

The patch includes two register_unwind methods: one that handles a dummy 
frame; and one that handles ->saved_regs based frames.  The unwind 
function being selected according to the current value of the PC.


FRAME->unwind_cache;

This is used to cache the values returned by FRAME->register_unwind().

Even though the ->register_unwind() method returns the value of a 
register in the previous frame, that value is not cached in the previous 
frame.  Two reasons: the previous frame may not have been created; it is 
a cache to avoid calling ->register_unwind() and not a cache of register 
values.


The key to this all is a mind set change.  Instead of ``pulling'' 
register values from prev->next.  They are pushed/unwound from FRAME. 
When unwinding a register, you can't assume that FRAME->prev exists.


Where to from here?

Rationalize the way frames are created.  Cf other posts, something like:
   create_frame (frame_chain(fp), frame_saved_pc(fp), fp);
should ``just work'' rofl.

Change get_current_frame() to start out with an initial regcache frame 
(one that returns registers from regcache) so that even the initial 
frame can be created with:
   create_frame (...);
rof with lol.

Tie the dwarf2cfi stuff into this ...

thoughts,
Andrew



(1) ``(gdb) maint time 1'' but the numbers are really small.  Hacked it 
to give real/user/sys times but they were even smaller!
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: diffs
URL: <http://sourceware.org/pipermail/gdb/attachments/20020414/9db9db38/attachment.ksh>


More information about the Gdb mailing list