My name is David Gilmore. I have been following the Slate project
for some time, and have decided that I am finally in a position to be
of some assistance. I apologize for not having been able to do more
before now. I also apologize for my delayed participation in this
thread, but I am in the field away from the internet.
I believe that the Slate Language is a very powerful idea, but
certain bottlenecks are holding it back from meeting its potential.
I have had some discussions with Brian about what needs to be done to
resolve these issues.
There are basically 3 ways to make Slate go faster:
1. Optimize Message Sends. This includes streamlining the message-
send code (which is difficult because it has to do many checks) and
method lookups from a cache (which is faster, but still involves
checks). Polymorphic inline caches is one strategy for doing this
which involves caching multiple versions of methods based on the
types of the participants.
2. Run compiled code rather than interpreted. This avoids the
overhead of bytecode decoding and offers the possibility of various
code optimizations, but is quite complex and offers little speedup
for message sends. There are several ways to do this:
a) on-demand compiler (called explicitly by the programmer and
stored to a file or image.
b) native-code just-in-time compiler (JIT). A method is compiled to
native code when it is called for the first time and then stored in a
c) threaded-code JIT: When a method is called for the first time,
the bytecodes are decoded to a jump-table which links to a series of
bytecode handlers implemented in assembly language. This is almost
as fast as unoptimized native code.
3. Eliminate Message Sends altogether. The cleanliness of the
language design allows the user to think of everything in terms of
objects participating in message sends. This is efficient for
humans, but not for computers. If the system can translate message-
sends to straight c-calls or insert the code directly into the
calling method, then dramatic speed boosts can be made in code which
is constantly calling tiny methods. These speedups are possible even
if an interpretive VM is used. The catch is that this can only be
done where the system can determine at compile time the types of the
various objects involved in the call.
Of these possibilities, I feel that the best "bang for the buck"
speedup potential for Slate is number 3. Number 1 is actually fairly
well done in the Slate VM currently. Regarding number 2, Lee's JIT
project yielded about 2x speed boost. There are a number of other
things which could be done to improve this, but it looks as if Slate
would still be slow because of exorbitant message-passing overhead.
An alternative to enhancing Lee's JIT would be to implement a
threaded-code interpreter which wouldn't have to be too complex.
So what is the best way to implementing the elimination of Message
Sends? That is the job of the optimizer code within the Slate VM.
This code needs to be understood, tested, and filled out. The
optimizer takes its input from the output of the Slate lexer and
parser in the form of syntax trees. It should then be able to walk
through the code and determine if the types of a message-send can be
known in advance either by programmer specification or type
inference. If it can, then it will replace the call with the syntax
tree of the called method. This is code-inlining.
This code is difficult to test because it can yield very complex tree-
structures. I feel that the best way to debug this code is to
resurrect the old Lisp-based VM and update it to run the current
slate libraries. LispWorks Personal is a free development
environment which is very nice and has a step-debugger and tools for
graphical presentation of tree structures. It does have a limited
heap-size so I that might become a problem. The Lisp VM code is very
nicely written and is only 7,000 lines including a slate->lisp
translator. The translated code can then be natively compiled.
Methods can be implemented in Slate or Lisp and FFI is available
I do not propose the use of the Lisp VM as a replacement of the C-
based VM, but it can be a useful test-bed for development of
components which can then be integrated into the C VM. It can also
be useful for a project which integrates Slate and Lisp code.
With the Lisp VM, the lisp language essentially becomes the
"bytecode" for system, but this is something which is visual,
tweakable, and debuggable. After success with Lisp, different
backends can be developed to produce Slate bytecodes compatible with
the current C VM, as well as LLVM bytecodes which would utilize the
LLVM engine to produce high-quality, optimized native-code. These
would not be dependent on the lisp environment.
I don't have all of the answers, but I am engaged in the process of
figuring this thing out. I hope that others will take an interest in
this and take it farther than I am able.
I am involved in several projects and I am notorious for having a
somewhat slow multi-tasking cycle so I apologize in advance for not
always being totally responsive, but I always come back to good
ideas, and I have come back to Slate repeatedly because it is
definitely a good idea, and will continue to do so.