Check out the new USENIX Web site. next up previous
Next: Scenario B: Removing a Up: Static Compilation vs Binary Previous: Static Compilation vs Binary


Scenario A: Adding a Method

Here we make a binary-compatible change to class Programmer by adding a new method sleep at the very beginning.

public class Programmer {
  void sleep() { ... }; // New Method!
  void eat  () { ... };
  void hack () { ... };
}

Figure 2: Scenario A: adding a method.

Now we recompile class Programmer only. The vtables for Programmer and JavaProgrammer are shown in Figure 2. The vtable layout of class Programmer has changed, and it is no longer consistent with the vtable layout of class JavaProgrammer. When these classes are loaded and Manager.main invoked, the code for Tom.eat will access the wrong entry in the vtable and end up calling method sleep. A similar problem occurs with Tom.hack. This is exactly the behavior shown by the current GCJ, which uses the standard vtable approach, and thus does not support binary compatibility.

Note that even if we had added the method sleep at the end of class Programmer, the problem still exists, because when we recompile class Programmer, method sleep will use entry 2 of the vtable. However the entry 2 of the vtable of class JavaProgrammer is already occupied by method study, and the invocation Jerry.study of Manager was compiled based on this.

The observation here is that the vtable layout may change due to changes in the class. So we really should not have made any assumptions about the vtable layouts of Programmer and JavaProgrammer in Manager. Moreover, the information available at compile time is not sufficient for building the vtables, since classes in the same hierarchy may change, yet we still need to maintain consistency between a subclass and its superclass.


next up previous
Next: Scenario B: Removing a Up: Static Compilation vs Binary Previous: Static Compilation vs Binary
Dachuan Yu 2002-05-23