Compiler Designing W10L1807

Other Topics

  • Java allows classes to be loaded at the run-time, type checking happens at the compile time and bytecode is verified at the time of run.
  • Classes can be loaded using ClassLoader and also can be unloaded.
  • Initialization is Java is complex and as COOL is a subset of Java, it also has a complex initialization.
  • A class is initialized when it is first used not when it is loaded, as it will be non-deterministic to locate the error source, because classes are loaded in different sections many times.
  • Initializing a class object in Java:
1. Lock the class object for the class
       wait for the lock if another thread is using it
2. If class is being initialized then release the lock and return
3. If it has been initialized the return normally
4. Otherwise mark the object as initialization in progress and release the lock on class
5. Initialize the super class in static order, but initialize static final fields first and before initialization give every field a default value.
6. If error, then mark the class as erroneous
7. If no error, lock class and mark i as initialized and then notify thread that object is ready to use and unlock class
  • If N features are there in the systems then there are potentially N^2 interactions.

Compiler Designing W10L1806

Java Threads

  • Threads bring concurrency to Java programs, In Java each has a Program Counter and stack
  • A program can have multiple threads.
  • Scheduler: A scheduler picks one of the threads and execute one instruction in it. The picking up job is completely random.
  • Thread is class in Java having start and stop method.
  • Two threads can use the same object in the heap.
  • A synchronized method can acquire a lock on the object to be processed, and then can free it.
  • How synchronization works:
class A
     int a=0, b=9;
     void f1() {a=8;b=7;}
     void f2() {print(a,b);}

if two threads are there and one can implement f1 andd other can f2, then results would be random depending upon the function chosen and instruction executed.

Using keyword synchronized only on write operation won’t work either because only a synchronized function checks for lock.

  • The next point is that even without synchronization, a variable would hold a value given by some thread. A value is written atomically.
    • Although double violates the atomic property, because it actually stored as a two word number. So instructions are divided into two, one is for one and other for the second word. So the instructions can interleave. So doubles are declared to be volatile to avoid the situation of out of the thin air value.

Compiler Designing W10L1805

Java Coercions

  • Conversion from one type to another.
  • Widening, (example int to float) can be implicitly and narrowing, (example float to int)is to be done explicitly.
  • bool has no coercion or cast.
  • Many times coercion can result in surprising behavior. Example of PL/I here:
A = '123';
B = '123'
C = A + B    //C would have three blanks in it as a result, + will force A and B to convert in             //integers, and because C should have a length of 6, and the resulting sum would              //be placed at 
            //the last, the initial three letters will be chosen having blanks.

Compiler designing W10L1804

Java Interfaces

  • It specifiy relationship among classes without using inheritance.
interface XY {void function(int x, int y);}
class X implements XY {void function(int x, int y) {...}}

it is same as multiple inheritance in C++. class X implements A,B,C {...} but an interface need not to be at fixed offset.

Because of no fixed offsets, implementation of interfaces are different. One approach is to use a mapping function that will map method strings to method code. Hashing is used to improve the performance.

Compiler Designing W10L1803

Java Exceptions

  • Handling something unexpectable gracefully.
class Foo {
     public static void main(String[] args){
          try{X();} catch(Exception e){System.out.println("Error");} 
     public void X() throws MyException {
           throw new MyException();

Exception expressions:


gif (1)

When try block is executing, it goes all in the stack and when throw is to be executed, all the contents of the try block has to be popped.

  • An uncaught exception during object finalization(cleans object) can not be handled.

Compiler Designing W10L1802

Java Arrays

  • Having multiple aliases with updatable data with different type are unsound. Example,
//B < A
B [] b =new B();
A [] a = b;
a[0] = new A();
b[0].aMethodNotInA();                 //error, unsound!

Solution is to disallow subtyping using arrays, this solution is also adopted by COOL. The above code will be valid if B = A.

Java produces exception by checking at run-time, if an array is created then it checks for all of it’s assignment. If object type doesn’t match then error is raised. This adds an overhead of checking the array of objects and yes, primitive types are not classes.

Compiler Designing W10L1801


  • Java was designed to server in set-top devices for networking by SUNMicrosystems under the project name Oak.
  • Initial development- 1991 to 1994
  • Also internet was becoming popular at that time, so Java is adopted as networking language.
  • Java is typed, object oriented, dynamic and supports interfaces. These features were inherited from contemporary languages existed at the time of its development.

Compiler Designing W09L1705 Part II

Automatic Memory Management Conclusions

  • It prevents very serious bugs but reduces programmer’s control as now programmer don’t know the memory structure and don’t know when memory is deallocated.
  • In real-time applications it can be very inefficient as the pauses should be less frequent or very short.
  • Memory leaks are also possible. X points to an AST and IL is made out of it then this AST is no longer needed, so it’s pointer should be changed to NULL.
  • There are more advanced GCs:
    • Concurrent: program and GC can run simultaneously
    • Generational: Objects that are not usually ccoolected are stored somewhere else and GC focuses on collecting on those objects which are more likely to be freed
    • Run-time: The pause time is restricted
    • Parallel: several collectors can work simultaneously.

Compiler Designing W09L1705

Garbage Collection Algorithm IV: Reference Count

  • A dedicated field is used to store the number of pointers pointing to some object. When this value drops to zero the object can be freed.
  • Each assignment would alter reference count.
X ← Y
rc(p)++            //p is the object pointed by Y
rc(q)--            //q is the object pointed by X
if(rc(q)==0) free q;
X ← Y

Assignment cost is increased because of the overhead to manipulate reference counts

  • This method is easy to implement and there are no pauses during implementation.
  • But this is slow and cannot collect circular structures.

Compiler Designing W09L1704

Garbage Collection Algorithm III: Conservative Collection

  • This algorithm is used by languages like C/C++.
  • In C/C++ it is impossible to identify contents of an object in memory. For example, a node of a list containing data and pointer to next node, can be considered correctly or a binary tree incorrectly.
  • Solution is to consider an address a pointer if it looks like one:
    • If it is aligned and;
    • if it points to a valid data segment in the program.

In this way set of reachables is overestimated. This is a conservative approach so that’s normal.

  • Even now objects cannot be moved, because it is not known that what is considered a pointer is actually a pointer.