290 likes | 418 Views
CSE P501 – Compiler Construction. Object layout Field access What is this ? Object creation - new Method calls Dynamic dispatch Method tables ( vtables ) s uper Runtime Type Info. class B { // Base int x, y; void setx ( int i ) {x= i ; }
E N D
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 Jim Hogg - UW - CSE - P501
class B { // Base int x, y; void setx(inti) {x=i;} intgetx() {return x;} void sety(inti) {y=i;} intgety() {return y;} } class D extends B { // Derived int y; void sety(inti) {y = 2*i;} intgety() {return 2*y;} void supery(inti) {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()); } } What does this program print? main will print 3 values when run. What are these values? Jim Hogg - UW - CSE - P501
Object Layout - Conceptual (NOT actual) d b class B class D x y setx ... getx ... sety ... gety ... x y setx ... getx ... sety ... gety ... x = ? y = ? setx ... getx ... sety ... gety ... y sety ... gety ... supery ... y = ? sety ... gety ... supery ... Jim Hogg - UW - CSE - P501
setx - getx d d b b x = 1 y setx(i) {x=i;} getx ... sety ... gety ... x = 1 y setx... getx() {return x;} sety ... gety ... y = ? sety ... gety ... supery ... y = ? sety ... gety ... supery ... b.setx(1) b.getx() => 1 Jim Hogg - UW - CSE - P501
sety - gety d d b b x = 1 y setx... getx ... sety ... gety ... x = 1 y setx... getx ... sety ... gety ... y = 4 sety(i) {y=2*i;} gety ... supery ... y = 4 sety ... gety() {return 2*y;} supery ... b.sety(2) b.gety() => 8 Jim Hogg - UW - CSE - P501
supery - gety d b d b x = 1 y = 42 setx... getx ... sety ... gety ... x = 1 y = 42 setx... getx ... sety ... gety ... y = 4 sety ... gety() {return 2*y;} supery... y = 4 sety ... gety ... supery(i) {super.sety(i);} d.supery(42) d.gety() => 8 Jim Hogg - UW - CSE - P501
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 Jim Hogg - UW - CSE - P501
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 Jim Hogg - UW - CSE - P501
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 objects of class D vtable for class D hashcode inherited from java.lang.Object x y toString setx getx sety gety supery y inserted by compiler x y inserted by user y 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} Jim Hogg - UW - CSE - P501
vtables : laid out at compiletime vtable for class D Note that a method, called abc, say occupies the same offset in the vtable for all classes in an inheritance chain hashcode object of class B toString setx x y getx sety B.sety gety B.gety hashcode B.setx Shared by B and D objects of class D toString B.getx setx getx x y sety D.sety y gety D.gety D.supery supery Jim Hogg - UW - CSE - P501
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 Jim Hogg - UW - CSE - P501
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 Jim Hogg - UW - CSE - P501
Object Layout • 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 intsthen 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) Jim Hogg - UW - CSE - P501
Field Access • Source int n = obj.fld; • x86 • Assuming that obj is a local variable in the current method moveax, [ebp+offsetobj]; load objptr moveax, [eax+offsetfld] ; load fld mov [ebp+offsetn], eax; store n Jim Hogg - UW - CSE - P501
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 Jim Hogg - UW - CSE - P501
What is this ? You write this: You get this: class C { int x; void setx(inti) { x = i; } } . . . C c = new C(); c.setx(42); class C { int x; void setx(C this, inti) { this.x = i; } } . . . C c = new C(); setx(c, 42); Jim Hogg - UW - CSE - P501
x86 Conventions (C++) • ecx is traditionally used as this • Add to method call movecx, 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 Jim Hogg - UW - CSE - P501
x86 Local Field Access • Source int n = fld; or int n = this.fld; • x86 moveax, [ecx+offsetfld] ; load fld mov [ebp+offsetn], eax; store n Jim Hogg - UW - CSE - P501
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 vtablepoints to super-class vtable • Second slot in vtable points to default (0-argument) constructor • Makes implementation of super() simple Jim Hogg - UW - CSE - P501
Example vtable Definitions class definitions vtable definitions class B { // Base int x, y; void setx(inti) {x=i;} intgetx() {return x;} void sety(inti) {y=i;} intgety() {return y;} } class D extends B { // Derived int y; void sety(inti) {y = 2*i;} intgety() {return 2*y;} void supery(inti) {super.sety(i);} } .data B$$: dd 0 ; no superclass dd B$B ; default ctor ddB$setx ddB$getx ddB$sety ddB$gety D$$: dd B$$ ; parent dd D$D ; default ctor ddB$setx ; parent ddB$getx ; parent ddD$sety ddD$gety ddD$supery 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. Jim Hogg - UW - CSE - P501
vtable Footnotes • Key point: First 4 non-ctor method entries in D’s vtable point to methods declared in B inexactly the same order • So compiler knows correct offset for a particular method regardless of whether that method is overridden Jim Hogg - UW - CSE - P501
Object Creation • 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 Jim Hogg - UW - CSE - P501
Object Creation • Source B b= new B(); • x86 push numBytes ; size-of-C + 4 call malloc ; addr of bits returned in eax add esp, 4 ; pop numBytes lea edx, B$$ ; get vtable address mov [eax], edx ; store vtable pointer into 1st object slot movecx, eax ; set up this for constructor push 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 object mov [ebp+offsetb],eax ; store object reference in variable b Jim Hogg - UW - CSE - P501
Constructor • Only special issue here is generating call to superclass constructor • Same issues as super.method(…) calls – we’ll defer for now Jim Hogg - UW - CSE - P501
Method Calls • 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 Jim Hogg - UW - CSE - P501
Method Call • Source obj.meth(…); • x86 <push arguments from right to left> ; (as needed) movecx, [ebp+offsetobj] ; get pointer to object moveax, [ecx] ; get pointer to vtable call dwordptr [eax+offsetmeth] ; call indirect via vtable <pop arguments> ; (if needed) movecx, [ebp+offsetecxtemp] ; (restore if needed) Jim Hogg - UW - CSE - P501
Handling super • Almost the same as a regular method call with one extra level of indirection • Source super.meth(…); • x86 <push arguments from right to left> ; (if needed) movecx,[ebp+offsetobj] ; get pointer to object moveax,[ecx] ; get method tbl pointer moveax,[eax] ; get parent’s method tbl pointer call dwordptr [eax+offsetmeth] ; indirect call <pop arguments> ; (if needed) Jim Hogg - UW - CSE - P501
Runtime Type Info • 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 Jim Hogg - UW - CSE - P501
Next • Code Generation for Objects • Representation • Method calls • Inheritance and overriding • Strategies for implementing code generators • Code improvement – optimization Jim Hogg - UW - CSE - P501