Difference between revisions of "Melting Ice Technology"
m (→The interpreter) |
m (→The interpreter) |
||
Line 27: | Line 27: | ||
This yields two requirements to the EiffelStudio runtime. It needs both to be able to execute the EiffelStudio byte code and to handle calls from frozen code into melted code and vice versa. | This yields two requirements to the EiffelStudio runtime. It needs both to be able to execute the EiffelStudio byte code and to handle calls from frozen code into melted code and vice versa. | ||
− | ====The interpreter==== | + | ====The interpreter and the byte code==== |
The EiffelStudio byte code interpreter is a stack machine. The byte code itself is not very different from .NET byte code or Java Byte Code. | The EiffelStudio byte code interpreter is a stack machine. The byte code itself is not very different from .NET byte code or Java Byte Code. | ||
Revision as of 13:56, 9 January 2007
Warning: Warning: Article under development
There are two main criteria for any good compiler. Both the compilation and the compiled program need to be fast. There is a trade off, the more time a compiler takes to make optimizations, the faster the compiled program is and the slower the compilation process becomes.
Fortunately the need for fast compilation and fast compiled programs occurs at different times during the development cycle. When the developer is incrementally writing and testing a program he needs short compilation time to be productive. At the end, when his work is thoroughly tested and ready to ship there can a slower compilation that generates a very fast delivery.
EiffelStudio exploits this by providing two basic compilation modes: workbench and finalized mode. The C code generated by the compiler looks different for workbench and finalized mode. The terms workbench code and finalized code are used to refer to the corresponding generated C code.
Workbench code has the following properties:
- It is easily testable (by debugging).
- It compiles and recompiles very fast (due to melting ice technology).
- It supports precompiles.
Finalized code has only two advantages, smallness and speed. Whereas the former contributes to the latter due too better cache efficiency. Finalized code can only be debugged at the C level. This article focuses on the workbench mode of EiffelStudio
Compiled versus interpreted
EiffelStudio was designed with the following principle in mind: When a programmer makes a small change he expects a short recompilation time, when he makes a big change he will accept some waiting time.
Traditionally, the fastest programming environments (in terms of recompilation time) were interpreted languages (like VisualBasic). Unfortunately interpreted languages are not competitive performance wise.
The designers of EiffelStudio circumnavigated the trade off by taking the best of both approaches. Thus, in workbench mode EiffelStudio is half compiler and half interpreter. The technology behind this is called melting ice.
An Eiffel System compiled in workbench mode consists of both frozen and melted code. Frozen code is code, that is translated to C code. Melted code is not yet translated to C code but to a form of byte code that has to be interpreted. This byte code is called EiffelStudio byte code (EBC).
This yields two requirements to the EiffelStudio runtime. It needs both to be able to execute the EiffelStudio byte code and to handle calls from frozen code into melted code and vice versa.
The interpreter and the byte code
The EiffelStudio byte code interpreter is a stack machine. The byte code itself is not very different from .NET byte code or Java Byte Code.
This article won't explain the byte codes. This is partially done in Byte Code. To give a general idea the Fibonacci feature and its EiffelStudio byte code are shown:
fibonacci (n: INTEGER): INTEGER require n >= 0 do if n = 0 then Result := 0 elseif n = 1 then Result := 1 else Result := fibonacci (n - 1) + fibonacci (n - 2) end end |
1: BC_START Routine Id : 186 Body Id : 185 Result Type : [INTEGER_32] Nr. args : 1 Nr. locals : 0 18: BC_NO_CLONE_ARG Routine name : fibonacci Written : 9 32: BC_PRECOND offset 23 37: BC_HOOK 1 42: BC_ASSERT <8, 16> 45: BC_ARG 1 48: BC_INT32 0 53: BC_GE 54: BC_END_PRE offset 0 59: BC_RAISE_PREC 60: BC_HOOK 2 65: BC_ARG 1 68: BC_INT32 0 73: BC_EQ 74: BC_JMP_F 16 79: BC_HOOK 3 84: BC_INT32 0 89: BC_RASSIGN 90: BC_JMP 80 |
90: BC_JMP 80 95: BC_HOOK 4 100: BC_ARG 1 103: BC_INT32 1 108: BC_EQ 109: BC_JMP_F 16 114: BC_HOOK 5 119: BC_INT32 1 124: BC_RASSIGN 125: BC_JMP 45 130: BC_HOOK 6 135: BC_ARG 1 138: BC_INT32 1 143: BC_MINUS 144: BC_CURRENT 145: BC_FEATURE fid 36 [9: HELLO_WORLD] 154: BC_ARG 1 157: BC_INT32 2 162: BC_MINUS 163: BC_CURRENT 164: BC_FEATURE fid 36 [9: HELLO_WORLD] 173: BC_PLUS 174: BC_RASSIGN 175: BC_HOOK 7 180: BC_NULL |
The byte code is not that difficult to understand. Most instructions have an effect on the interpreter stack. Instruction 124 for example pops one value from the stack and saves it to the result of the current feature.