|
From: Nicholas N. <nj...@ca...> - 2002-11-19 16:12:39
|
On Tue, 19 Nov 2002, Nicholas Nethercote wrote:
> I think it is important, ie. the fact that Valgrind virtualises all the
> registers and then loses where they were in the UCode.
Thinking about this some more, I think that one particular source of
slowdown is the fact that %esp is virtualised as %ESP.
This is because several very common instructions (push, pop, call, ret)
update %esp as a side-effect. For example:
pushl $0x0
becomes:
GETL %ESP, t4
SUBL $0x4, t4
PUTL t4, %ESP
MOVL $0x0, t6
STL t6, (t4)
INCEIPo $2
becomes:
movl 0x10(%ebp), %ecx
subl $0x4, %ecx
movl %ecx, 0x10(%ebp)
xorl %edx, %edx
movl %edx, (%ecx)
addl $2, 36(%ebp)
A lot of time is spent moving values to and from %ESP. I was wondering
about the possibility of "de-virtualising" %esp -- ie. store %ESP in %esp.
Then maybe the UCode translation could be as simple as "PUSHL 0x0".
I'm sure to have overlooked several bazillion complications here. For
example, %esp is used inside generated code, but I think that might be ok:
- for transferring %eflags to %EFLAGS -- just pushes then pops off the
top of the stack, should be fine
- for CCALLs -- saves caller-save regs, pushes args, clears args,
restores regs, should be fine?
There are sure to be other problems, though. And I have no idea how it
would affect the MemCheck instrumentation; already the code produced
contains redundant "PUTL tX, %ESP" instructions because MemCheck always
needs %ESP to be up-to-date.
I don't know, maybe it's totally impossible, but maybe it's not.
N
|