1988-07-04 15:30:12 +00:00
|
|
|
.\" Introduction
|
|
|
|
.\"
|
1994-06-24 11:31:16 +00:00
|
|
|
.\" $Id$
|
1988-07-04 15:30:12 +00:00
|
|
|
.NH
|
|
|
|
INTRODUCTION.
|
|
|
|
.PP
|
|
|
|
This document describes an EM interpreter which does extensive checking.
|
|
|
|
The interpreter exists in two versions: the normal version with full checking
|
|
|
|
and debugging facilities, and a fast stripped version that does interpretation
|
|
|
|
only.
|
|
|
|
This document assumes that the full version is used.
|
|
|
|
.LP
|
|
|
|
First the virtual EM machine embodied by the interpreter (called \fBint\fP) is
|
|
|
|
described, followed by some remarks on performance.
|
|
|
|
The second section gives some specific implementation decisions.
|
|
|
|
Section three explains the usage of the built-in debugging tool.
|
|
|
|
.LP
|
|
|
|
Appendix A gives an overview of the various warnings \fBint\fP gives,
|
|
|
|
with possible causes and solutions.
|
|
|
|
Appendix B is a simple tutorial on the use of \fBint\fP.
|
|
|
|
A separate manual page exists.
|
|
|
|
.PP
|
|
|
|
The document assumes a good understanding of what EM is and what
|
|
|
|
the assembly code looks like [1].
|
|
|
|
Notions like 'procedure descriptor', 'mini', 'shortie' etc. are not
|
|
|
|
explained.
|
|
|
|
In the sequel, any word in \fIthis font\fP refers to the name of a
|
|
|
|
variable, constant, function or whatever, used in the source code under
|
|
|
|
the same name.
|
|
|
|
.LP
|
|
|
|
To avoid confusion: \fBint\fP interprets EM machine language (e.out files),
|
|
|
|
\fInot\fP the assembly language (.e files) and \fInot\fP the compact
|
|
|
|
code (.k files).
|
|
|
|
.NH 2
|
|
|
|
The virtual EM machine.
|
|
|
|
.PP
|
|
|
|
The memory layout of the virtual EM machine represented by the interpreter
|
|
|
|
differs in details from the description in [1].
|
|
|
|
Virtual memory is split up into two separate spaces:
|
|
|
|
one space containing the instructions,
|
|
|
|
the other all the data, including stack and heap (D-space).
|
|
|
|
The procedure descriptors are preprocessed and stored in a separate array,
|
|
|
|
\fIproctab[]\fP.
|
|
|
|
Both spaces start off at address 0.
|
|
|
|
This is possible because pointers in the two different spaces are
|
|
|
|
distinguishable by context (and shadow-bytes: see 2.6).
|
|
|
|
.NH 3
|
|
|
|
Instruction Space
|
|
|
|
.PP
|
|
|
|
Figure 1 shows the I-space, together with the position of some important
|
|
|
|
EM registers.
|
|
|
|
.Dr 12
|
|
|
|
NEXT --> |________________| <-- DB \e
|
|
|
|
| | |
|
|
|
|
| | | T
|
|
|
|
| | <-- PC |
|
|
|
|
| Program | | e
|
|
|
|
| | |
|
|
|
|
| Text | | x
|
|
|
|
| | |
|
|
|
|
| | | t
|
|
|
|
0 --> |________________| <--(PB) /
|
|
|
|
.Df
|
|
|
|
\fI Fig 1. Virtual instruction space (I-space).\fP
|
|
|
|
.De
|
|
|
|
.PP
|
|
|
|
The I-space is just big enough to contain all the instructions.
|
|
|
|
The size needed for the program text (\fINTEXT\fP) is found from the
|
|
|
|
header-bytes of the loadfile.
|
|
|
|
Legal values for the program counter (\fIPC\fP) consist of all
|
|
|
|
addresses in the range from 0 through \fINTEXT\fP \- 1.
|
|
|
|
If the \fIPC\fP is made to point to an illegal address, a trap will occur.
|
|
|
|
.NH 3
|
|
|
|
The Procedure Table
|
|
|
|
.PP
|
|
|
|
The \fINProc\fP constant indicates how many procedure descriptors there
|
|
|
|
are in the proctab array.
|
|
|
|
Elements of this array contain for each procedure: the number of locals, the
|
|
|
|
entry point and the entry point of the textually following procedure. This is
|
|
|
|
used in testing the restriction that the program counter may not wander from
|
|
|
|
procedure to procedure.
|
|
|
|
.NH 3
|
|
|
|
The Data Space
|
|
|
|
.PP
|
|
|
|
Figure 2 shows the layout of the data space, which closely conforms to the EM
|
|
|
|
Manual.
|
|
|
|
.Dr 36
|
|
|
|
__________________
|
|
|
|
maxaddr(psize) --> | | <-- ML \e
|
|
|
|
| | | S
|
|
|
|
| Locals | | t
|
|
|
|
| & | | a
|
|
|
|
| RSBs | | c
|
|
|
|
| | | k
|
|
|
|
|________________| <-- SP /
|
|
|
|
. .
|
|
|
|
. .
|
|
|
|
. Unused .
|
|
|
|
. .
|
|
|
|
. .
|
|
|
|
. .
|
|
|
|
. .
|
|
|
|
. .
|
|
|
|
. Unused .
|
|
|
|
. .
|
|
|
|
. .
|
|
|
|
|________________| <-- HP
|
|
|
|
| | \e
|
|
|
|
| Heap | |
|
|
|
|
|________________| <-- HB |
|
|
|
|
| | | D
|
|
|
|
| Arguments | |
|
|
|
|
| Environ | | a
|
|
|
|
| _ _ _ _ | |
|
|
|
|
| | | t
|
|
|
|
| | |
|
|
|
|
| | | a
|
|
|
|
| Global data | |
|
|
|
|
| | |
|
|
|
|
| | |
|
|
|
|
0 --> |________________| <--(EB) /
|
|
|
|
.Df
|
|
|
|
\fI Fig 2. Virtual dataspace (D-space).\fP
|
|
|
|
.De
|
|
|
|
.PP
|
|
|
|
D-space begins at address 0, and ends at the largest address
|
|
|
|
representable by the pointer size (\fIpsize\fP) being used;
|
|
|
|
for a 2-byte pointer size this maximum address is
|
|
|
|
.DS
|
|
|
|
((2 ^ 16 \- 1) / word size * word size) \- 1
|
|
|
|
.DE
|
|
|
|
for a 4-byte pointer size it is
|
|
|
|
.DS
|
|
|
|
((2 ^ 31 \- 1) / word size * word size) \- 1
|
|
|
|
.DE
|
|
|
|
(not 2 ^ 32, to allow illegal pointers to be implemented in the future). The
|
|
|
|
funny rounding construction is required to make ML+1 expressible as the
|
|
|
|
initialisation value of LB and SP.
|
|
|
|
.PP
|
|
|
|
D-space is split into two partitions: Data and Stack (indicated by the
|
|
|
|
brackets).
|
|
|
|
The Data partition holds the global data area (GDA) and the heap.
|
|
|
|
Its initial size is given by the loadfile constant SZDATA.
|
|
|
|
Some space is added to it, because arguments and environment are
|
|
|
|
stored here also.
|
|
|
|
This total size is static while interpreting.
|
|
|
|
However, as the heap may grow during execution (e.g. caused by dynamic
|
|
|
|
allocation) this results in a variable size for the Data partition.
|
|
|
|
Initially, the size for the Data partition is the sum of the space needed
|
|
|
|
by the GDA (including the space needed for arguments and environment) and
|
|
|
|
the initial heapspace.
|
|
|
|
The lowest legal Data address is 0; the highest \fIHP\fP \- 1.
|
|
|
|
.LP
|
|
|
|
The Stack partition holds the stack.
|
|
|
|
It begins at the highest available D-space address, and grows
|
|
|
|
towards the low addresses, so the Stack partition is of variable size too.
|
|
|
|
The lowest legal Stack address is the stackpointer (\fISP\fP),
|
|
|
|
the highest is the memory limit (\fIML\fP).
|
|
|
|
.NH 2
|
|
|
|
Physical lay-out
|
|
|
|
.PP
|
|
|
|
Each partition is mapped onto a piece of physical memory with the
|
|
|
|
same name: \fItext\fP (fig. 1), \fIstack\fP and \fIdata\fP (fig. 2).
|
|
|
|
These are the storage structures which \fBint\fP uses to physically
|
|
|
|
store the contents of the virtual EM spaces.
|
|
|
|
Figure 2 thus shows the mapping of D-space onto two
|
|
|
|
different physical parts: \fIstack\fP and \fIdata\fP.
|
|
|
|
The I-space is represented by one physical part: \fItext\fP.
|
|
|
|
.LP
|
|
|
|
Each time more space is needed, the actual partition is reallocated,
|
|
|
|
with the new size being computed with the formula:
|
|
|
|
.DS
|
|
|
|
\fInew size\fP = 1.5 \(mu (\fIold size\fP + \fIextra\fP)
|
|
|
|
.DE
|
|
|
|
\fIextra\fP is the number of bytes exceeding the \fIold size\fP.
|
|
|
|
One can prove that using this method, there is a
|
|
|
|
linear relationship between allocation time and needed partition size.
|
|
|
|
.PP
|
|
|
|
A virtual D-space starting at address 0 is in correspondence with
|
|
|
|
the definition in [1], p. 3\-6.
|
|
|
|
The main reason for having D-space start at address 0, is that it induces
|
|
|
|
a one-one correspondence between the heap \- and GDA
|
|
|
|
addresses on the virtual machine (and hence the definition) on one hand,
|
|
|
|
and the offset within the \fIdata\fP partition on the other.
|
|
|
|
This implies that no extra calculation is needed to perform load and
|
|
|
|
storage operations.
|
|
|
|
.LP
|
|
|
|
Some calculation however cannot be avoided, because the stack part of
|
|
|
|
the D-space grows downwards by EM definition.
|
|
|
|
The first address of the virtual stack (\fIML\fP, the maximum address for
|
|
|
|
the given \fIpsize\fP) is mapped onto the
|
|
|
|
beginning of the \fIstack\fP partition.
|
|
|
|
When the stack grows (i.e. EM addresses get lower), the offset within the
|
|
|
|
\fIstack\fP partition gets higher.
|
|
|
|
By taking offset \fIML \- A\fP in the stack partition, one obtains the
|
|
|
|
physical address corresponding to some virtual EM (stack) address \fIA\fP.
|
|
|
|
.NH 2
|
|
|
|
Speed.
|
|
|
|
.PP
|
|
|
|
From several test results with both versions of the interpreter, the
|
|
|
|
following may be concluded.
|
|
|
|
The speed of the interpreter depends strongly on the type of
|
|
|
|
program being interpreted.
|
|
|
|
If plain CPU arithmetic is performed, the interpreter is
|
|
|
|
relatively slow (1000 \(mu the cc version).
|
|
|
|
When stack manipulation is at hand, the interpreter is
|
|
|
|
quite fast (100 \(mu the cc version).
|
|
|
|
.LP
|
|
|
|
Most programs however will not be this extreme, so an interpretation
|
|
|
|
time of somewhere between 300 and 500 times direct execution
|
|
|
|
for a normal program is to be expected.
|
|
|
|
.LP
|
|
|
|
The fast version runs in about 60% of the time of the full version, at the
|
|
|
|
expense of a considerably lower functionality.
|
|
|
|
Tallying costs about 10%.
|