Re: GUI systems Jonathan S. Shapiro (shap@eros-os.org)
Tue, 27 Jun 2000 19:58:29 -0400

Hey, guys, a debate about everybody's favorite OO language is really NOT helpful. I'm not going to consider Objective C, Scheme, C++, ML, Java, or any number of other really cool languages.

This is not motivated by language bigotry. From a research perspective ML would be an interesting choice to explore -- particularly the subset that compiles to C.

Here are some of the issues that seem relevant:

  1. The runtime system must not allocate storage dynamically except in response to a specific program statement that requests an object allocation. Ever. No exceptions. None. Really, none. No, not for that reason either. This rules out every current OO or high-level language I know about.

Why: Unless the total storage allocation that occurs as a side effect of runtime requirements is statically boundable it is not possible to avoid GC in the kernel. If things get bad enough you get prone to deadlock. The hash-memoization mechanism used by Objective C (which, by the way, first appeared in MacLisp and was later reimplemented by yours truly for Franz Lisp) requires such a dynamic allocation.

2. Runtime overhead is the enemy. Abstraction at the level of syntax is a useful thing to have. At the level of code generation it is completely unacceptable to pay anything for it. Macrokernels may be a different story, but microkernels really want to be implemented in a high-level assembler.

Why: Ultimately, kernel performance sets a bound on the performance of the entire system. It is therefore necessary to be able to understand exactly how code is generated. High-level abstraction tends to lead to indirection and virtual dispatch overheads that are not appropriate in a kernel.

3. Destructors plus exceptions do not mix. The combination requires that catch-blocks be generated by the compiler. Once such catch blocks must be generated it's damn near impossible to understand what the hell is going on in the code at the instruction level. See issue (2).

4. Garbage collection in a kernel is the work of the devil.

I'm actually a fan of GC, and given who is on the list I'ld be very surprised if any of you are as well-read on them as I am. Perhaps Mark Miller is more up to date. I don't say this to brag, but only to point out that I'm very aware of the design tradeoffs and implementation strategies involved, and that I'm generally in favor of GC for application-level code.

While collectors have about the same costs as managed allocators, that cost is amortized differently, and it's very hard to beat a managed allocator in a program that doesn't do dynamic allocation at all. Current high-performance incremental collectors rely on techniques that are not easily implemented in a kernel.

The real problem is runtimes. Languages hat presume collection tend to build this presumption into their runtimes and libraries. While it is possible in principle to build a Scheme program that creates no garbage, one's success in practice depends heavily on the particular implementations of the library and the compiler. This is a bad dependency for a kernel to have.

5. There is very little object structure in the EROS kernel. Actually, that's wrong. There are lots of objects, but there is essentially no inheritance. What inheritance there is in the kernel is pure single inheritance, and doesn't call for virtual functions at all. There is one exception, and that was a mistake -- interfaces would have been a better model.

While the current kernel makes heavy use of inlining, this has proven to be a fairly serious impediment to comprehensibility.

6. Much of the point of getting out of C++ is to be able to use Linux drivers without modification. Objective C, however pleasant, would suffer the same runtime-level issues.

Look, I'm all for OO languages. Hell, I wrote a book on how to use one effectively. Objective C and Java certainly have a great deal of appeal, and if I could get a Java to native compiler I'ld very happily write all domain code in Java.

But not in the kernel. In the kernel, the rubber has to meet the road in a very precise way, and all of the current OO languages introduce overheads and unpredictabilities that make them non-starters for kernel implementations.

Meanwhile, does anybody know of a good Java to native code compiler?