Linked by Peter Gerdes on Mon 10th Jan 2005 17:35 UTC
Editorial As a recent ACM Queue article observes the evolution of computer language is toward later and later binding and evaluation. So while one might quibble about the virtues of Java or the CLI (also known as microsoft.net) it seems inevitable that more and more software will be written for or at least compiled to virtual machines. While this trend has many virtues, not the least of which is compatibility, current implementations have several drawbacks. However, by cleverly incorporating these features into the OS, or at least including support for them, we can overcome these limitations and in some cases even turn them into strengths.
Permalink for comment
To read all comments associated with this story, please click here.
Continued
by logicnazi on Tue 11th Jan 2005 05:07 UTC

So in the previous post I hope I clarified the reasons I think the use of virtual machines in programming offers very compelling advantages. Now many of you seemed to accept this proposition but be unconvinced that this needed to be moved into the operating system.

My first reason is that if we don't move it into the operating system the benefits of these new coding methodoligies and languages will be forever locked in the ghetto of application level programming. If we want to be able to use these fancy new languages in the OS itself or device drivers there simply isn't any way around moving things into the OS. While I realize some of you may think the idea of using things like java in the guts of an OS I would remind you that people once felt the same way about using things like C or C++. So while these may not move into the kernel itself I can certainly see these in device drivers and system calls.

In particular the safety features of virtualization are particularly attractive in device drivers. Since device drivers are often downloaded from the internet from untrusted sources but given hardward level access they are particularly in need of security features. Furthermore they are illsuited to the all or nothing type of authorization present in binary only security implementations as it is not uncommon that we would want to give a driver the ability to do things like directly interface with a system bus, but only construct messages with a certain prefix (I'm out of my element here so I apoligize if the example is incorrect but we do often want device drivers access to certain arbitraril defined subsets of a device). While we could implement these protections by hand the evolution of hardware makes it difficult to continue adding protections that protect everything one needs to access and allow new device drivers enough access to do what they need without unduly slowing down trusted system drivers which we want to bypass any security checks. A VM system allows the possibility of a general solution which lets device drivers ship with a complete specification of exactly what access they need with enforcement.

Also some people have suggested that we need not add OS support to gain many of the process pretection and optimization features to our virtual machines. While it is certainly true that we can load much of the JIT compiler into a shared library and implement a small interface for each instance this doesn't solve the thread level protection problems (which was why I mentioned threads in my article instead of just processes). In particular since threads share many context enviornments it is not sufficent to simply handle each thread as its own OS process. So unless we want to just reimplement all the thread protections and scheduling in each virtual enviornment this suggests OS level support.

This support doesn't need to be very complex. I am thinking of something as simple as entering them as threads in the scheduler but instead of waking and sleeping them normally just calling wake and sleep functions in the virtual machine code. Actually now that I think about this it may very well be possible to do in some of the cooperative thread scheduling implementations which allow the kernel to do scheduling and then just expousing data to allow a user space process to manage the threads.

Other than a few small kernel modifications like this the rest of what I mean by OS integration is basically putting support for a common multi-level binary format in the binary loader, the same way the binary loader supports shared libraries. In other words provide a common infrastructure to support the binary caching and multi-level features I suggest for JIT compilers and apparently are even implemented in some situations. So rather than each virtual system doing these things itself there would be uniform system libraries that provide functions like get ssa representation or find code associated with ssa subtree. This is needed, as I mentioned in my article, so that executables written in several virtual machines might be executed without the overhead of CORBA or the like.

Now I agree that many of these things are forward looking and somewhat speculative. It probably isn't time to start throwing virtual code in device drivers and the like. However, since I think it is inevitable that more and more of our applications will be written in high level languages with virtual execution it doesn't hurt to start thinking about it now.

Ohh and also one of the other advantages of virtual machines is reflection type services (maybe I got the term wrong but I mean things like creating functions on the fly). For instance it is nearly impossible to write good lisp as a native binary (and I don't count putting the interpreter in the binary). For the person who asked the virtual machine in question here is basically a machine which implements car, cdr and a few basic operations and has two stacks, similar to a lisp machine(tm).