My goal is to look at how different constructs get converted into bytecode, IR, and then optimized. I am interested in contributing to rubinius but haven't found enough details to understand it.
I would post this to the mailing list but it appears to not have had traffic since 2008 and the below is too verbose for IRC. Please excuse it being filed as a github issue.
What I would like to know is how to get simple IR / optimized IR / x86 asm for a single method for example (not the whole program execution) (and to not have to force everything in the program to get JIT compiled by bypassing the profile-based JIT.
Can I do this from ruby/irb?
Here is how far I have got on my own:
I read an old slide that said to do
rbx -Xjit.enabled -Xjit.dump_code=4 some_script.rb
but -Xjit.enabled is no longer used (now you have the profile-based call count instead due to long startup time)
I ran -Xconfig.print to find -Xjit.call_til_compile.
vagrant@precise32:~/src/rubinius$ cat /tmp/a
a = 1
vagrant@precise32:~/src/rubinius$ bin/rbx -Xjit.dump_code=7 -Xjit.call_til_compile=0 /tmp/a > /tmp/log &
I specified 7 in hopes that I would get all 3 - simple IR, optimized IR, and assembly, and I did. But I got code that seems much more than those two lines.
I am this far from the aloha rubyconf12 slides:
value.to_s == "42"
cm = DeepThought.method_table.lookup(:ultimate_answer?).method
This gets me the bytecode.
I also dug/grepped far enough to find vm/llvm/jit_compiler.cpp being where the simple and optimized IR code gets dumped when selected.
You can see the AST with:
./bin/rbx compile -A script.rb
and see the bytecode with:
./bin/rbx compile -B script.rb or ./bin/rbx compile -B -e "some code"
There's no way atm to see the IR/asm just for a specific method afaik.
You can play with it in irb in such a way though:
i = 0
while i < 40_000
some_code && method_calls
i += 1
This will make it inline method calls into test and dump the IR which you should be able to locate.
The way the JIT operates is it inlines method calls and the IR it produces (the optimised version) depends on your whole program. So the asm it produces for a single method might not necessarily be the same asm if your method is run in the context of your whole program. A useful flag to enable to learn what JIT does when inlining is -Xjit.inline.debug
If you're just starting with Rubinius I suggest reading the docs http://rubini.us/doc/en (the bytecode compiler part and the memory system),
there are no JIT specific or the primitive system docs yet though), understanding the bytecode instructions and then looking at how the interpreter and the JIT compiler work together. You have to look at the code in the vm directory, eg.
are good starting points IMO. Join #rubinius on IRC if you have further questions, there are usually people able to help answer them.
Just a few additional points. IRC is actually fine for these kinds of questions, topics like this are discussed pretty often there, so don't be afraid of that. We love to help people get to know the code base and how things work.
Like @hosiawak already said, understanding how we JIT code in Rubinius is important for answering this question. Basically the JIT depends heavily on type information for jitting your code. So we use the way how your code runs to decide what to compiled and also how to compile it. Should we inline a block or method or not, do we need to add type guards or not etc.
Therefore running the code is necessary before it can be jitted. The reason you see a lot more code with your example, is because a lot of Rubinius is implemented in Ruby. For example the compiler that transforms the AST into bytecode is written in Ruby. That means that this also runs when you start your program. Other things are parts such as the loader for your code that sets up everything before you can run a script.
I suggest using the example of @hosiawak by running a certain piece of code in a loop to exercise it and see how it compiles in the context of that specific loop.
Because this issue doesn't really have any actionable for us, I'm closing it since we don't use the issues as a discussion place. Feel free to hop into IRC and don't be afraid to ask questions about this stuff, we'd love to answer them!