Implementing a programming language on the GraalVM architecture - graalvm

What are the (architectural) differences in implementing a programming language on the GraalVM architecture – in particular between Graal, Truffle, and LLVM using Sulong?
I plan to reimplement an existing statically typed programming language on the GraalVM architecture, so that I can use it from Java without much of a hassle.
There are at moment three options:
Emit JVM bytecode
Write a Truffle interpreter
Emit LLVM bitcode, use Sulong to run it on GraalVM

Emitting JVM bytecode is the traditional option. You will have to work at the bytecode level, and you'll have to optimise your code your before emitting bytecode as the options that the JVM has for optimising it after it has been emitted are limited. To get good performance you may have to use invokedynamic.
Using Truffle is I'd say the easy option. You only have to write an AST interpreter and then code generation is all done for you. It's also the high performance option - in all languages where there is a Truffle version and a bytecode version, the Truffle version confidently outperforms the bytecode version as well as being simpler due to no bytecode generation stage.
Emitting LLVM bitcode and running on Sulong is an option, but it's not one I would recommend unless you have other constraints that lead you towards that option. Again you have to do that bitcode generation yourself, and you'll have to optimise yourself before emitting the bitcode as optimisations are limited after the bitcode is set.
Ruby is good for comparing these options - because there is a version that emits JVM bytecode (JRuby), a version using Truffle (TruffleRuby) and a version that emits LLVM bitcode (Rubinius, but it doesn't then run that bitcode on Sulong). I'd say that TruffleRuby is both faster and simpler in implementation than Rubinius or JRuby. (I work on TruffleRuby.)
I wouldn't worry about the fact that your language is statically typed. Truffle can work with static types, and it can use profiling specialisation to detect more fine-grained types again at runtime than are expressed statically.

Related

Could someone please explain the differences between Graal, GraalVM, Truffle & SubstrateVM?

I know these technologies are all related but could someone please explain what each one is used for and how they fit together?
Oversimplification:
Graal - Java bytecode compiler. Can be used just in time (as part of a JVM) or ahead of time.
SubstrateVM - other things (runtime) needed to actually run ahead-of-time compiled Java bytecode without a JVM. This powers the "native-image" command of GraalVM.
Truffle - framework for implementing languages as AST interpreters which can be just-in-time compiled using graal. Some notable languages implemented are JavaScript, Ruby, R and LLVM bitcode.
GraalVM - most of these technologies packaged together in order to support different use cases, for example: running JVM programs (i.e. anything that compiles to Java bytecode) using Graal as the JIT compiler for better peak performance, ahead-of-time compiling JVM programs for fast startup and low memory footprint, running fast dynamic languages (JS, R, Ruby) that can interoperate without overhead, and so on.

Xamarin Ahead-of-Time (AOT) compiler vs. an ordinary compiler

My understanding is that Xamarin's Ahead-of-Time (AOT) Compiler compiles Xamarin.iOS applications directly to native ARM assembly code (How Xamarin works).
What I don't get, however, is why it needs to be called "Ahead-of-Time" as opposed to just being an ordinary compiler. Is there any distinction between Xamarin's AOT compiler and a traditional compiler or is this just a marketing term?
How AOT compares to a traditional JIT compiler
Ahead-of-Time (AOT) compilation is in contrast to Just-in-Time compilation (JIT).
In a nutshell, .NET compilers do not generate platform specific assembly code, they generate .NET bytecode, instructions which are interpreted by the .NET virtual machine. This bytecode is portable, any .NET VM can run it, be it Windows Phone, Mono on Linux, or a JavaScript-based implementation. Unfortunately, because the code has to be interpreted by the VM it is slower than native code which can be executed by the processor itself. That's where JIT and AOT come in.
When a .NET application starts up, the JIT compiler analyzes the bytecode, identifies areas that could be sped up by being translated to native code, and compiles them. During execution, the compiler can also identify hot paths for compilation.
Unfortunately for .NET, Java, and any platform that would benefit from JIT, dynamic code generation is disallowed by the App Store terms of service. Since Xamarin can't perform JIT on the device and they know they're shipping to ARM devices, they can run a JIT-type compiler ahead of time (AOT) and bundle it into the binary.
How AOT compares to a machine code compiler
As mentioned above, AOT translates part of an interpreted bytecode to machine code. It doesn't eliminate the need for a virtual machine bytecode interpreter. The VM will run just as it would if, but occasionally see an instruction that says "Execute this chunk of machine code".
Is this just a marketing term?
No. The message that Xamarin was conveying in that paragraph was that their code performs faster than a simple byte code based language. For both iOS and Android, they are able to execute native code on hot code paths to improve performance. The terms AOT and JIT are technical details about how they do that.

Is AOT (ahead of time) compilation available (or planned) in mono for android?

I was wondering if there is any AOT compilation options for the mono for android platform (or anything planned?).
I am asking this because I will port a game using mono for android, and performance is really important, this is why I wanted to know if AOT compilation is available (or any other compilation option that can produce better performances)
I know that Monotouch uses AOT compilation, and that it can optionally use llvm as compiler in order to make some optimisations. So, I am wondering if the same options are available in mono for android.
Thanks in advance
AOT is not available in Mono for Android, I don't think it is on the road-map either.
As far as I understand JIT is not slower than AOT, rather the contrary, because JIT can use the information it knows about the environment it runs on to optimize code to it. An AOT compiler cannot know everything about the same environment.
This thread: Why is Java faster when using a JIT vs. compiling to machine code? has some answers that elaborates on this.
So I really doubt that you would get any performance improvements if there were an AOT compiler.

What are the advantages of LLDB over GDB in iOS development?

In Xcode 4.3, now you can enable using LLDB as the debugger for iOS targets.
What advantages does it have over using the good old GDB? GDB still works with LLVM and I cannot see any obvious differences in "everyday" debugging tasks.
The most notable advantage is that LLDB understands dot syntax in properties:
po self.property
A quote from LLVM project blog:
LLDB supports basic command line debugging scenarios on the Mac, is scriptable, and has great support for multithreaded debugging. LLDB is already much faster than GDB when debugging large programs, and has the promise to provide a much better user experience (particularly for C++ programmers). We are excited to see the new platforms, new features, and enhancements that the broader LLVM community is interested in.
Another quote from LLDB homepage:
LLDB is a next generation, high-performance debugger. It is built as a set of reusable components which highly leverage existing libraries in the larger LLVM Project, such as the Clang expression parser and LLVM disassembler.
Why a new debugger
In order to achieve our goals we decided to start with a fresh architecture that would support modern multi-threaded programs, handle debugging symbols in an efficient manner, use compiler based code knowledge and have plug-in support for functionality and extensions. Additionally we want the debugger capabilities to be available to other analysis tools, be they scripts or compiled programs, without requiring them to be GPL.

Translation of machinecode into LLVM IR (disassembly / reassembly of X86_64. X86. ARM into LLVM bitcode)

I would like to translate X86_64, x86, ARM executables into LLVM IR (disassembly).
What solution do you suggest ?
mcsema is a production-quality binary lifter. It takes x86 and x86-64 and statically "lifts" it to LLVM IR. It's actively maintained, BSD licensed, and has extensive tests and documentation.
https://github.com/trailofbits/mcsema
Consider using RevGen tool developed within the S2E project. It allows converting x86 binaries to LLVM IR. The source code could be checked out from Revgen branch of GIT repository available by url https://dslabgit.epfl.ch/git/s2e/s2e.git.
As regards to RevGen tool mentioned by #bsa2000, this latest paper "A compiler level intermediate representation based binary analysis and rewriting system" has pointed out some limitations in S2E and Revinc.
I pull them out here.
shortcoming of dynamic translation:
S2E [16] and Revnic [14] present a method for dynamically translating
x86 to LLVM using QEMU. Unlike our approach, these methods convert
blocks of code to LLVM on the fly which limits the application of LLVM
analyses to only one block at a time.
IR incomplete:
Revnic [14] and RevGen [15] recover an IR by merging the translated
blocks, but the recovered IR is incomplete and is only valid for
current execution; consequently, various whole program analyses will
provide incomplete information.
no abstract stack or promoting information
Further, the translated code retains all the assumptions of the
original bi- nary about the stack layout. They do not provide any
methods for obtaining an abstract stack or promoting memory locations
to symbols, which are essential for the application of several
source-level analyses.
I doubt there will be universal solution (think about indirect branches, etc.), LLVM IR is much "higher level" than any assembler. Though it's possible to translate on per-BB basis. You might want to check llvm-qemu and libcpu projects among others.
Just post some references on translating ARM binary to LLVM IR:
disarm - arm binary to llvm ir disassembler
https://code.google.com/p/disarm/
However, I have not tried it, thus not sure about its quality and stability. Anyone else may post additional information about this project?
There is new project, being in some early phases, The libbeauty:
https://github.com/jcdutton/libbeauty
Article about project: Libbeauty: Another Reverse-Engineering Tool, 24 December 2013, Michael Larabel - http://www.phoronix.com/scan.php?page=news_item&px=MTU1MTU
It only supports subset of x86_64 as input now. One of the project goals - is to be able to compile the generated LLVM IR back to assembly to get the binary with same functionality.

Resources