On Fri, Apr 9, 2010 at 4:53 AM, Fredrik Öhrström <[email protected]> wrote: > It might be fun, but I do not think that it is a good idea to implement > an interpreter in this way, > or more precisely, to implement any interpreter of bytecodes, using Java.
I never said anything about a bytecode interpreter :) > For languages like Ruby where the executable format is the source, I > assume that your interpreter works on the source text by > parsing/interpreting each source code line after each other. Since each > interpreter step requires so much computation you will not gain any > measurable performance by putting the interpreter loop inside the > MethodHandle. In JRuby, we actually interpret Ruby code by walking the AST. It's a series of interpret calls chained form one to the next. So if we can represent Ruby code as a tree of executable objects of one kind... > On the other hand, if you interpret bytecodes, then each interpreter > step is very small. At first it might look like a good idea to try to > shave a few instructions from each interpreter step. > > But the whole point of achieving good performance on the JVM is that you > translate the bytecodes of the other language into JVM bytecodes and > then allow the JVM technology to do its magic. > > When you implement an interpreter with JVM bytecodes (or MethodHandles) > then you immediately shut the door hard in the face of the JVM. It is > simply impossible for the JVM to optimize >through< your interpreter > loop into your application. The JVM will try to optimize your > interpreter loop, but it is still only the interpreter loop. No > variables will be optimized away from your code, no objects allocations > will disappear, no inlining will happen! I think you misunderstand what I mean. I don't want to implement an interpreter using MethodHandles...I want to represent the actual Ruby code by recomposing the AST's structure in an identical structure of MethodHandles. In otherwords, a piece of code like this: if a.foo() # condition b + c # then else bar() # else end which would be an AST something like If ..Call "foo" # condition ....LocalVar "a" ..Call "+" # then ....LocalVar "b" ....LocalVar "c" ..Call "bar" # else would get recomposed into handles something like this: GuardWithTest ..InvokeDynamic "foo" # condition ....VariableLookup "a" ..InvokeDynamic "+" # then ....VariableLookup "b" ....VariableLookup "c" ..InvokeDynamic "bar # else And because direct method handles get composed together, it would essentially become the native code version of the Ruby AST, without any compile phase (or rather, the compile phase is the recomposition as DMHs). The reason a loop handle is needed is because there's "while" constructs in Ruby I need to represent somehow...*not* because I want to construct a bytecode loop: while a.foo # condition b.bar # body end needs to become Loop ..InvokeDynamic "foo" # condition ....VariableLookup "a" ..InvokeDynamic "bar" # body ....VariableLookup "b" There's no way to represent this using handles without a loop construct. Think about this more like if I were using LLVM and calling its various methods for representing variable/memory access, flow control, basic blocks, and so on. That's what I want: a toolkit for composing the spirit of my code in a recognizable form which then optimizes and assembles that spirit into native code (or bytecode). - Charlie _______________________________________________ mlvm-dev mailing list [email protected] http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
