[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