From: Rocky Bernstein Date: 2008-04-16T17:19:48+09:00 Subject: Re: [ruby-core:16395] RFC: VM Instruction Manipulation gem(s)? ------=_Part_10286_319111.1208333987268 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline Chiyuan wrote about the current thinking of an instruction manipulator. However if you are considering changing VM bytecodes, I have a suggestion for one that would allow debugging without having to compile in trace instructions for every different line number represented in the code. It would be great if there were an additional kind of "trace" instruction and some kind of API to set and remove these. The way it would work follows. You specify the position of an opcode in an instruction sequence. The opcode gets overwritten with this new trace opcode, let's call it rtrace. The original instruction before overwriting with the rtrace instruction gets copied someplace. In addition, there is some free space at the end of the instruction sequence, of about 8 words. More on that magic number 8 below. The implementation of this rtrace instruction is almost like the implementation of the trace instruction which calls a trace hook. However on return from the trace-hook call, the original instruction that didn't get executed because of overwriting with an rtrace instruction would be copied to this free area at the end of the instruction sequence. It would be followed by a JUMP instruction to the location of the PC value had that original instruction been executed. Finally the implementation of the new trace instruction would change the PC to point to this temporary area which starts after the finish of the normal instruction sequence. So about 8 words are needed, because the longest instruction is 6 words and 2 words are needed for the JUMP instruction. (I may be a little bit off in terms of details, but I hope you get the idea.) I would be happy to provide a sample implementation as a patch if this would help or make things clearer. I thought about out what it would take to do the above *without* changing the VM or extending the instruction sequence by 8 words, but instead by adding this completely inside a trace hook. If the trap replacement instruction is not to be cleared after it is hit (i.e. a gdb "temporary breakpoint"), then the original opcode can be put back and the PC adjusted. However if this trap is to be more permanent, then you also have to trap at the following instruction to put back in the trap again for a future time. And since there is branching, it might involve a temporary trap at two locations of which only one will get hit, so that second location would have to be cleared as well. And there is one other problem in trying to do this completely in a trace hook. The current trace instruction is two words long, but there are some instructions like "leave" which are only one word long. Since we can't always assume we can read after the last instruction of an instruction sequence which can be "leave" instruction, replacing this instruction in this kind of situation would have to be disallowed. On Wed, Apr 16, 2008 at 12:41 AM, SASADA Koichi wrote: > Hi, > > > Rocky Bernstein wrote: > > > Is anyone aware of or working on a package/gem for facilitation VM > > instruction manipulation? Things like replace, insert or delete a > > sequence > > of VM instructions. I understand rubinius may have something like this. > > I > > ask because a colleague is considering writing one. > > > > (I've posted a query on ruby-talk but so there's been silence which I > > guess > > means there's been nothing.) > > > > I don't know about it. > > But VM bytecodes are not stable, because I want to remove/modify some > instructions which are not used frequently such as "definemethod". > > And I'm not sure which API is suitable. If you have any idea, please > teach me or see your implementation. > > Regards, > -- > // SASADA Koichi at atdot dot net > > ------=_Part_10286_319111.1208333987268 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline Chiyuan wrote about the current thinking of an instruction manipulator. However if you are considering changing VM bytecodes, I have a suggestion for one that would allow debugging without having to compile in trace instructions for every different line number represented in the code.

It would be great if there were an additional kind of "trace" instruction and some kind of API to set and remove these.

The way it would work follows. You specify the position of an opcode in an instruction sequence. The opcode gets overwritten with this new trace opcode, let's call it rtrace.  The original instruction before overwriting with the rtrace instruction gets copied someplace. In addition, there is some free space at the end of the instruction sequence, of about 8 words. More on that magic number 8 below.

The implementation of this rtrace instruction is almost like the implementation of the trace instruction which calls a trace hook. However on return from the trace-hook call, the original instruction that didn't get executed because of overwriting with an rtrace instruction would be copied to this free area at the end of the instruction sequence. It would be followed by a JUMP instruction to the location of the PC value had that original instruction been executed. Finally the implementation of the new trace instruction would change the PC to point to this temporary area which starts after the finish of the normal instruction sequence.  So about 8 words are needed, because the longest instruction is 6 words and 2 words are needed for the JUMP instruction. (I may be a little bit off in terms of details, but I hope you get the idea.)

I would be happy to provide a sample implementation as a patch if this would help or make things clearer.

I thought about out what it would take to do the above without changing the VM or extending the instruction sequence by 8 words, but instead by adding this completely inside a trace hook. If the trap replacement instruction is not to be cleared after it is hit (i.e. a gdb "temporary breakpoint"), then the original opcode can be put back and the PC adjusted. However if this trap is to be more permanent, then you also have to trap at the following instruction to put back in the trap again for a future time. And since there is branching, it might involve a temporary trap at two locations of which only one will get hit, so that second location would have to be cleared as well.

And there is one other problem in trying to do this completely in a trace hook. The current trace instruction is two words long, but there are some instructions like "leave" which are only one word long. Since we can't always assume we can read after the last instruction of an instruction sequence which can be "leave" instruction, replacing this instruction in this kind of situation would have to be disallowed.

On Wed, Apr 16, 2008 at 12:41 AM, SASADA Koichi <ko1@atdot.net> wrote:
Hi,


Rocky Bernstein wrote:
Is anyone aware of or working on a package/gem for facilitation VM
instruction manipulation? Things like replace, insert or delete a sequence
of VM instructions. I understand rubinius may have something like this. I
ask because a colleague is considering writing one.

(I've posted a query on ruby-talk but so there's been silence which I guess
means there's been nothing.)

I don't know about it.

But VM bytecodes are not stable, because I want to remove/modify some instructions which are not used frequently such as "definemethod".

And I'm not sure which API is suitable.  If you have any idea, please teach me or see your implementation.

Regards,
--
// SASADA Koichi at atdot dot net


------=_Part_10286_319111.1208333987268--