spring 2014jim hogg - uw - cse - p501l-1 cse p501 – compiler construction object layout field...
TRANSCRIPT
Spring 2014 Jim Hogg - UW - CSE - P501 L-1
CSE P501 – Compiler Construction
Object layout Field access What is this? Object creation - new Method calls
Dynamic dispatch Method tables (vtables) super
Runtime Type Info
Spring 2014 Jim Hogg - UW - CSE - P501 L-2
What does this program print?
class B { // Base int x, y; void setx(int i) {x=i;} int getx() {return x;} void sety(int i) {y=i;} int gety() {return y;}}
class D extends B { // Derived int y; void sety(int i) {y = 2*i;} int gety() {return 2*y;} void supery(int i) {super.sety(i);}}
public class Main { public static void main(String[]
args) { D d = new D(); B b = d; b.setx(1); System.out.println(b.getx()); b.sety(2); System.out.println(b.gety()); d.supery(42); System.out.println(d.gety()); }}
main will print 3 values when run. What are these values?
Object Layout - Conceptual (NOT actual)
Spring 2014 Jim Hogg - UW - CSE - P501 L-3
xysetx ...getx ...sety ...gety ...
class B x
ysetx ...getx ...sety ...gety ...
class D
ysety ...gety ...supery ...
x = ?y = ?setx ...getx ...sety ...gety ...
y = ?sety ...gety ...supery ...
d b
setx - getx
Spring 2014 Jim Hogg - UW - CSE - P501 L-4
x = 1ysetx(i) {x=i;}getx ...sety ...gety ...
y = ?sety ...gety ...supery ...
d b
b.setx(1)
b.getx() => 1
x = 1ysetx ...getx() {return x;}sety ...gety ...y = ?sety ...gety ...supery ...
d b
sety - gety
Spring 2014 Jim Hogg - UW - CSE - P501 L-5
b.sety(2)
x = 1ysetx ...getx ...sety ...gety ...
y = 4sety(i) {y=2*i;}gety ...supery ...
d b
b.gety() => 8
x = 1ysetx ...getx ...sety ...gety ...
y = 4sety ...gety() {return 2*y;}supery ...
d b
supery - gety
Spring 2014 Jim Hogg - UW - CSE - P501 L-6
x = 1y = 42setx ...getx ...sety ...gety ...
y = 4sety ...gety ...supery(i) {super.sety(i);}
d b
d.supery(42)
x = 1y = 42setx ...getx ...sety ...gety ...
y = 4sety ...gety() {return 2*y;}supery ...
d b
d.gety() => 8
Object Representation in MiniJava
Conceptually, each object contains: Fields - declared in its class or in its super-classes
Redeclaration of a field hides (occludes) super-class instance; but still reachable via super.
Methods declared in its class or in its super-classes Redeclaration of a method overrides (replaces); but still reachable via
super.
When a method is called, the most-derived ("furthest down the page") method is called. (Compile-time type of variable doesn't matter)
But we don’t want to keep a copy of every method in every object. Just one, shared copy of each will be fine
Spring 2014 Jim Hogg - UW - CSE - P501 L-7
Spring 2014 Jim Hogg - UW - CSE - P501 L-8
Actual Representation
Each object contains
A slot for each field declared in its class or in its super-classes
A pointer to a runtime structure describing the class, and its method dispatch table, or "vtable"
Note that sub-classes may not even exist when base class is defined. And yet, these future sub-classes must be substitutable for objects of today's base class
Method Dispatch Tables ("vtable") One vtable per class (not per object!) One slot for each (virtual) method
slot points to beginning of method code slot matches method name + number of parameters + types of parameters
vtable offsets are fixed at compile time In full Java, every class inherits hashCode, toString, etc from
Object
Spring 2014 Jim Hogg - UW - CSE - P501 L-9
setxgetxsetygety
supery
xy
y
objects of class D vtable for class D
xy
y
toString
hashcode
inserted by compilerinserted by user
inherited from java.lang.Object
Note that field x must be stored at the same offset in objects of class B as in objects of class D (because a D is substitutable for a B}
vtables : laid out at compiletime
Spring 2014 Jim Hogg - UW - CSE - P501 L-10
xy
object of class B
vtable for class D
toString
hashcode
xy
y
objects of class D toString
hashcode B.setx
B.getx
B.sety
B.gety
D.sety
D.gety
D.supery
setx
getx
sety
gety
setx
getx
sety
gety
supery
Shared by B and D
Note that a method, called abc, say occupies the same offset in the vtable for all classes in an inheritance chain
Spring 2014 Jim Hogg - UW - CSE - P501 L-11
Method Dispatch Footnotes
Want vtable to point to parent vtable, to support instanceof and super.
Implementing multiple Interfaces is tractable
Implementing multiple inheritance, with fields and method bodies, is more complex
Spring 2014 Jim Hogg - UW - CSE - P501 L-12
Now What?
Need to explore Object layout in memory Compiling field references
Implicit and explicit use of “this” Representation of vtables Object creation: new Code for dynamic dispatch
Including implementing “super.f” Runtime type information – instanceof and
casts
Spring 2014 Jim Hogg - UW - CSE - P501 L-13
In C/C++ allocate fields sequentially, in same lexical order as they were defined, but compiler may insert padding to maintain field alignment
eg: char, int => 1-byte char, 3-byte pad, 4-byte int
In Java and C#, fields will be packed (largest-to-smallest) within each sub-class slice to minimize space, but to also maintain field alignment
eg: doubles then ints then shorts and (Unicode) chars
First word of each object points to vtable
Java objects are allocated on the heap
(C# structs are allocated on the stack, and follow value semantics)
Object Layout
Spring 2014 Jim Hogg - UW - CSE - P501 L-14
Sourceint n = obj.fld;
x86 Assuming that obj is a local variable in the current
method
mov eax, [ebp+offsetobj] ; load obj ptr
mov eax, [eax+offsetfld] ; load fld
mov [ebp+offsetn], eax ; store n
Field Access
Spring 2014 Jim Hogg - UW - CSE - P501 L-15
Local Fields
A method can refer to fields in the receiving object either explicitly as this.fld or implicitly as fld
Both compile to the same code – an implicit this. is inserted by the compiler if not present explicitly
Mechanism: a reference to the current object is an implicit, first parameter to every method
Can be in a register or on the stack
Spring 2014 Jim Hogg - UW - CSE - P501 L-16
class C { int x; void setx(C this, int i)
{ this.x = i; }}
. . .
C c = new C();setx(c, 42);
class C { int x; void setx(int i) { x = i; }}
. . .
C c = new C();c.setx(42);
You get this:You write this:
What is this ?
Spring 2014 Jim Hogg - UW - CSE - P501 L-17
x86 Conventions (C++)
ecx is traditionally used as this
Add to method callmov ecx, c ; c points to receiving object
Do this after arguments are evaluated and pushed, right before dynamic dispatch code that actually calls the method
Need to save ecx in a temporary or on the stack in methods that call other non-static methods
Following examples aren’t always careful about this
Spring 2014 Jim Hogg - UW - CSE - P501 L-18
x86 Local Field Access
Sourceint n = fld; or int n = this.fld;
x86mov eax, [ecx+offsetfld] ; load fld
mov [ebp+offsetn], eax ; store n
Spring 2014 Jim Hogg - UW - CSE - P501 L-19
x86 Method Tables (vtables)
We’ll generate vtables in assembly language program
Need to pick a naming convention for method labels to avoid collisions
For methods, classname$methodname Would need something more sophisticated for overloading
For the vtables themselves, classname$$ Examples of "name mangling"
First slot in vtable points to super-class vtable
Second slot in vtable points to default (0-argument) constructor
Makes implementation of super() simple
Example vtable Definitions
Spring 2014 Jim Hogg - UW - CSE - P501 L-20
class B { // Base int x, y; void setx(int i) {x=i;} int getx() {return x;} void sety(int i) {y=i;} int gety() {return y;}}
class D extends B { // Derived int y; void sety(int i) {y = 2*i;} int gety() {return 2*y;} void supery(int i) {super.sety(i);}}
.dataB$$: dd 0 ; no superclass dd B$B ; default ctor dd B$setx dd B$getx dd B$sety dd B$gety
D$$: dd B$$ ; parent dd D$D ; default ctor dd B$setx ; parent dd B$getx ; parent dd D$sety dd D$gety dd D$supery
vtable definitions
dd is a synonym is dword. Its operand is the value for that field, not its name. In fact, slots in vtables are anonymous - they have no name.
class definitions
Spring 2014 Jim Hogg - UW - CSE - P501 L-21
vtable Footnotes
Key point: First 4 non-ctor method entries in D’s vtable point to methods declared in B in exactly the same order
So compiler knows correct offset for a particular method regardless of whether that method is overridden
Spring 2014 Jim Hogg - UW - CSE - P501 L-22
Steps
Call storage manager (malloc or similar) to get raw bits
Store pointer to vtable in first 4 bytes of object
Call a constructor (with pointer to the new object, this, in ecx)
Result of new is pointer to constructed object
Object Creation
Spring 2014 Jim Hogg - UW - CSE - P501 L-23
Object Creation
SourceB b = new B();
x86push numBytes ; size-of-C + 4call malloc ; addr of bits returned in eaxadd esp, 4 ; pop numBytes
lea edx, B$$ ; get vtable addressmov [eax], edx ; store vtable pointer into 1st object slotmov ecx, eax ; set up this for constructorpush ecx ; save ecx (constructor might clobber it)<push constructor arguments> ; arguments (if needed)call B$B ; call constructor (no vtable lookup
needed)<pop constructor arguments> ; (if needed)pop eax ; recover pointer to objectmov [ebp+offsetb],eax ; store object reference in
variable b
Spring 2014 Jim Hogg - UW - CSE - P501 L-24
Constructor
Only special issue here is generating call to superclass constructor Same issues as super.method(…) calls
– we’ll defer for now
Spring 2014 Jim Hogg - UW - CSE - P501 L-25
Steps
Push arguments as usual
Put pointer to object in ecx (this)
Get pointer to vtable from first 4 bytes of object
Jump indirect thru vtable
Restore ecx to point to current object (if needed) Useful hack: push it in the function prolog so always in
the stack frame at a known location
Method Calls
Spring 2014 Jim Hogg - UW - CSE - P501 L-26
Method Call
Sourceobj.meth(…);
x86
<push arguments from right to left> ; (as needed)mov ecx, [ebp+offsetobj] ; get pointer to objectmov eax, [ecx] ; get pointer to vtablecall dword ptr [eax+offsetmeth] ; call indirect via vtable<pop arguments> ; (if needed)mov ecx, [ebp+offsetecxtemp] ; (restore if
needed)
Spring 2014 Jim Hogg - UW - CSE - P501 L-27
Handling super
Almost the same as a regular method call with one extra level of indirection
Sourcesuper.meth(…);
x86<push arguments from right to left> ; (if needed)mov ecx,[ebp+offsetobj] ; get pointer to objectmov eax,[ecx] ; get method tbl pointer mov eax,[eax] ; get parent’s method tbl
pointercall dword ptr [eax+offsetmeth] ; indirect call <pop arguments> ; (if needed)
Use vtable as a “runtime representation” of the class
The test for (o instanceof C) is
Is o’s vtable pointer == &C$$ ? If yes, result is true
Recursively, get the superclass’s vtable pointer (from current vtable) and check
Stop when you reach Object, or null pointer, depending on how you represent things
If no match when you reach the top of the chain, result is false
Same test is part of check for legal downcast
Spring 2014 Jim Hogg - UW - CSE - P501 L-28
Runtime Type Info
Spring 2014 Jim Hogg - UW - CSE - P501 L-29
Code Generation for Objects Representation Method calls Inheritance and overriding
Strategies for implementing code generators
Code improvement – optimization
Next