Section Notes
Layout of Objects
Goal of an object data
structure in memory:
Objects are stored in memory
as two tables:
Class Foo { int x; getX()
{ … } print() { … } } |
Class Bar extends
Foo { int y; // override print() print() { … } // new method draw() draw() { … } } |
Things to note about the
object’s dispatch table:
Because
the offset of the method pointers are the same for the subclasses as the super classes,
the code that we generate for the method call can stay the same.
Code Generation for Short Circuit Evaluation
(from
notes for cs536 in Univ.
How would we write cgen for Boolean
expressions that are used in control flow?
One way:
1.
Generate code
for evaluation of Boolean expression, and store to the top of the stack.
2.
Pop off top of
stack, and see what the value is, and jump either to the true/false label.
Problems
with this approach?
Introduce a new method: condGen(trueLabel, falseLabel)
How does this work? Consider
an if-then-else statement:
Old
Method: < evaluate condition,
leaving the value on the stack> pop
value into T0 if
T0 == false goto falseLabel < code for “then”
branch > goto endLabel falseLabel: < code for “else”
branch > endLabel: |
New
Method: < evaluate condition –
if true, jump to trueLabel, else jump to falseLabel > trueLabel: < code for “then”
branch > goto endLabel falseLabel: < code for “else”
branch > endLabel: |
Let’s see how we would write
the condGen for ‘&&’ operator:
We are given the trueLabel1
and falseLabel1 from the arguments to condGen. These are the labels outside the block of code we are generating that
we want to jump to if the result is true, or false
respectively.
Start with two new labels,
trueLabel2, falseLabel2, representing where inner calls to condGen
should go when they are evaluated:
trueLabel2:
jmp end
falseLabel2:
end:
Now we need to add in code
for evaluating e1 by recursively calling condGen on e1.
Note that if e1 evaluates to false, then we can simply jump out of the block of
code we are generating to falseLabel1. If e1 evaluates to true, then we need to
evaluate e2. If e2 evaluates to false, then again we jump to falseLabel1 on the
outside. If e2 evaluates to true, then we can jump to trueLabel1, because both
e1 and e2 are true. Finally, we note that the rest of the code generated will
never be reached, and we can eliminate it:
< code generated by e1.condGen(trueLabel2,
falseLabel1) >
trueLabel2:
< code generated by e2.condGen(trueLabel1,
falseLabel1) >
jmp end
falseLabel2:
end: