Re: What is byte-code ?

Nathan Moore <nathan.moore@sdc.cox.net>
2 Apr 2005 19:30:46 -0500

          From comp.compilers

Related articles
[11 earlier articles]
Re: What is byte-code ? kers@hpl.hp.com (Chris Dollin) (2005-03-15)
Re: What is byte-code ? xous@xouslab.com (Xous - Jose R. Negreira) (2005-03-18)
Re: What is byte-code ? nathan.moore@sdc.cox.net (Nathan Moore) (2005-03-24)
Re: What is byte-code ? anton@mips.complang.tuwien.ac.at (2005-03-31)
Re: What is byte-code ? anton@mips.complang.tuwien.ac.at (2005-03-31)
Re: What is byte-code ? kers@hpl.hp.com (Chris Dollin) (2005-03-31)
Re: What is byte-code ? nathan.moore@sdc.cox.net (Nathan Moore) (2005-04-02)
Re: What is byte-code ? slimick@venango.upb.pitt.edu (John Slimick) (2005-04-11)
Re: What is byte-code ? kers@hpl.hp.com (Chris Dollin) (2005-04-11)
Re: What is byte-code ? anton@mips.complang.tuwien.ac.at (2005-04-11)
Re: What is byte-code ? nathan.moore@cox.net (Nathan Moore) (2005-04-16)
Re: What is byte-code ? gah@ugcs.caltech.edu (glen herrmannsfeldt) (2005-04-16)
Re: What is byte-code ? ralph@inputplus.co.uk (2005-05-09)
[1 later articles]
| List of all articles for this month |

From: Nathan Moore <nathan.moore@sdc.cox.net>
Newsgroups: comp.compilers
Date: 2 Apr 2005 19:30:46 -0500
Organization: Cox Communications
References: 05-03-015 05-03-026 05-03-053 05-03-088 05-03-125
Keywords: VM, interpreter
Posted-Date: 02 Apr 2005 19:30:46 EST

Chris Dollin wrote:
> Nathan Moore wrote:


>>Plus I'll bet that you take another hit on the codes
>>that use the 3 bits left from the first 8 bits as an additional portion
>>of the opcode, b/c you have to decode that as well as the first 5 bits.
>
>
> No; it's a single 256-way switch. (Earlier interpreters did work the way
> you describe. It's horrible; one massive switch is bad enough, but one
> large switch nested inside the massive switch is too much for me to keep
> track of. I never got round to seeing if using an array of function pointers
> had a sufficiently small performance penalty. Maybe the next time ...)


So what, you have several cases w/ the same code for all of the
instructions that only use the first 5 bits to determine the operation
and the other 3 of the octet as extra operands when the first 5 bits match?
With binary numbers so bits are obvious:


case 0101 0000:
case 0101 0001:
case 0101 0010:
case 0101 0011:
...
case 0101 0111:
do_some_junk();
break;


or with a gcc extention:


case 0101 0000 ... 0101 0111:
do_some_junk();
break;


That would be faster. Seems kinda dirty.


Rather than the array of f() * , if you use gcc, you could implement it
with an array of labels if you use gcc or another compiler that supports it.


void * LABEL[256] = { ADD, SUBTRACT, ... };
...
goto LABEL[instruction];


ADD:
/* add code */
/* update instruction pointer to reflect that this one has been done */
goto LABEL{instruction];
SUBTRACT:


This will save you about 2 jumps per instructoin since the jump tables
that are usually spit out by compilers are:


jump ip+(constant*case)
jump CODE_THAT_ACTUALLY_DOES_CASE_0
jump CODE_THAT_ACTUALLY_DOES_CASE_1
...


and because you won't have to jump back to the initial jump to begin the
next instruction. If you were to do this, I would suggest that you make
an automated process of building the C source file that has the
implementation of the instructions in it from one or more files that
contain the per-instruction implementations and make it so that the
method of jump table can be changed for different compilers.


>>In addition, in the instruction decode code you will have the result of
>>INSN | MASK be all high valued bits for some hosts. This means that
>>your "jump to" code (or switch/case code generated by the compiler) will
>>have to scale this value in some way before using it to find the correct
>>place to jump, which is an additional cost.
>
>
> Easy fix: in the 16-bit opcode word, put the 5:3 at the low-order end.
> You still need a mask, of course. Or - if you can - store the instructions
> as I = (A, 5:3, B), where A::B are the opcode bits and the width of B is
> such that the masked I is already suitable scaled. (You pay in the operand
> access, but since I already needed a shift, it's just a little extra shift,
> and on a beautiful machine [1], you can exploit rotates. But likely not
> at the C level.)


Took a while to figure out what you said there. My points were to get
rid of those shifts, but if you could configure the VM to take advantage
of prescaling via the shifts (or rotates) and the MASK, you have
overcome some other issues. I think that there may be some hidden
grimlins here though. I believe that most archs have at least one
rotate instruction -- even something as ugly as x86 (since forever).


>
>
>>You also have to worry about endianness and portability.
>
>
> Always.


My point here was to do something that would compile correctly on any
machine and work effeciently/quick without having to be configured
slecial for that machine. Other areas have to worry about endianness
and other protability issues, but the more areas that you can make them
non-issues, the better.


Nathan Moore



Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.