Matthew Fluet mfluet@intertrust.com
Thu, 9 Aug 2001 18:19:12 -0700 (PDT)

Primarily for Henry: how do you get the disassembled instructions in
"spy"?  It seems like you're using gdb to interface with the process.  Is
there a way to get gdb to disassemble an arbitrary (not necessarily
binary) executable?

Here's the motivation.  I was looking at some output assembly, and noticed
that I'm generally generating the following an allocation:

movl tag,(%esi)             -- %esi is frontier
leal (4*1)(%esi),%eax       -- %eax now holds pointer to object
movl value0,(4+0*1)(%esi)   -- fill in slots
movl value1,(4+4*1)(%esi)
movl valueN,(4+4*N*1)(%esi)
addl (4+4*(N+1)*1),%esi     -- bump frontier

(In reality, all of the numeric expressions can be evaluated to integers;
the verbosity here is just for exposition.)

This is pretty much what you get with a simple translation of the C:
#define Object(x, np, p)					\
	do {							\
		*(word*)frontier = GC_objectHeader(np, p);	\
		x = frontier + GC_OBJECT_HEADER_SIZE;		\
	} while (0)

#define Assign(ty, o, v)						\
	do {								\
		*(ty*)(frontier + GC_OBJECT_HEADER_SIZE + (o)) = (v);	\
	} while (0)

#define AC(o, x) Assign(uchar, o, x)
#define AD(o, x) Assign(double, o, x)
#define AI(o, x) Assign(int, o, x)
#define AP(o, x) Assign(pointer, o, x)
#define AU(o, x) Assign(uint, o, x)

#define EndObject(bytes)					\
	do {							\
		frontier += GC_OBJECT_HEADER_SIZE + (bytes);	\
	} while (0)

You could also do the assignments relative to the pointer to the object:

movl tag,(%esi)
leal (4*1)(%esi),%eax
movl value0,(0*1)(%eax)
movl value1,(4*1)(%eax)
movl valueN,(4*N*1)(%eax)
addl (4+4*(N+1)*1),%esi

So far, no big deal.  But, I was browsing the IA reference manual, and
noticed that the encodings of memory operands have an _optional_
displacement field.  In theory, the second version should save a byte in
the instruction encodings, because
movl value0,(0*1)(%eax)
has no displacement.  And one byte per allocation primitive in the
program could really add up.  Alas, size reports identical sizes for
programs compiled under the different versions.  So, I was trying to track
down if as is really encoding a displacement of 0 for the second version.

In the actual assembly, I generate something like the following.  The
"*1"'s are generally extraneous, but the assembler gets them.  The
important case is the value0 case, where the memory operand does not even
have a displacement given (implicit 0 displacement):

movl tag,(%esi)
leal (4*1)(%esi),%eax
movl value0,(%eax)
movl value1,(4*1)(%eax)
addl $24,%esi

So, it's not a matter of as generating a displacement just because it's in
the input assembly.