July 23rd, 2016

Delphi is still alive

Surprised to know that Delphi is not dead but doing even mobile apps and some modern features like:
... the language has grown and supports many other modern language features, including generics and anonymous methods ...

Rust, the most loved Programming Lang of 2016

I was remembering details of the LLVM project (or more specifically an umbrella of projects), driven by this wonderful article about Graal & Truffle:

LLVM support
Most Truffle runtimes interpret source code, but there’s nothing that says you have to do that. The Sulong project is creating a Truffle interpreter for LLVM bitcode.

Sulong is still very new and code run this way has many limitations. But by running bitcode with Graal & Truffle, the framework should in theory gain support for not only C, but also C++, Objective-C, FORTRAN, Swift and potentially even Rust.

Then Rust came to be mentioned and I was surprised to know that it's heavly tailored for performance and parallel processing, which is a best fit for a experimental web browser layout engine like Servo.

The prototype seeks to create a highly parallel environment, in which many components (such as rendering, layout, HTML parsing, image decoding, etc.) are handled by fine-grained, isolated tasks. Source code for the project is written in the Rust programming language.

Not only that but Rust got the 1st place at a survey of Stack Overflow for the Most Loved Programming Language in 2016.

Rust is a general-purpose, multi-paradigm, compiled programming language sponsored by Mozilla Research. It is designed to be a "safe, concurrent, practical language", supporting pure-functional, imperative-procedural, and object-oriented styles.

The language grew out of a personal project by Mozilla employee Graydon Hoare. Mozilla began sponsoring the project in 2009 and announced it in 2010. The same year, work shifted from the initial compiler (written in OCaml) to the self-hosting compiler written in Rust. Known as rustc, it successfully compiled itself in 2011. rustc uses LLVM as its back end.
Although its development is sponsored by Mozilla, it is an open community project. The design of the language has been refined through the experiences of writing the Servo web browser layout engine and the Rust compiler.

bitcode vs. bytecode

This statement at this article about Graal & Truffe got me thinking about the differences between bitcode and bytecodes (or portable code):

Most Truffle runtimes interpret source code, but there’s nothing that says you have to do that. The Sulong project is creating a Truffle interpreter for LLVM bitcode.

So I found this definition of what are bit codes at the LLVM documentation (IR = Intermediate Representation):

What is commonly known as the LLVM bitcode file format (also, sometimes anachronistically known as bytecode) is actually two things: a bitstream container format and an encoding of LLVM IR into the container format.

The bitstream format is an abstract encoding of structured data, very similar to XML in some ways. Like XML, bitstream files contain tags, and nested structures, and you can parse the file without having to understand the tags. Unlike XML, the bitstream format is a binary encoding, and unlike XML it provides a mechanism for the file to self-describe “abbreviations”, which are effectively size optimizations for the content.

LLVM IR files may be optionally embedded into a wrapper structure, or in a native object file. Both of these mechanisms make it easy to embed extra data along with LLVM IR files

So looking further I found helpful these two bits of information at Stack Overflow:

The format is literally a bitstream, not a bytestream. See this document for more details: http://llvm.org/docs/BitCodeFormat.html

The biggest difference between JVM bytecode and and LLVM bitcode is that JVM instructions are stack-oriented, whereas LLVM bitcode is not. This means that rather than loading values into registers, JVM bytecode loads values onto a stack and computes values from there. I believe that an advantage of this is that the compiler doesn't have to allocate registers, but I'm not sure.

LLVM bitcode is closer to machine-level code, but isn't bound by a particular architecture. For instance, I think that LLVM bitcode can make use of an arbitrary number of logical registers.

And openned the path to this comment "ARC in Swift is much better than Java GC" pointing to this article at Quora: Why doesn't Apple Swift adopt the memory management method of garbage collection like in Java? Which I'll definately read in the next days!

Fast Dragons and C/C++ on JVMs through Graal & Truffle

Recently I've posted some entries citing LLVM and IR, amidst the texts I was reading one came with real good summarized definitions for both terms:

LLVM is an umbrella project for a modular and reusable compiler infrastructure written in C++. It includes a compiler frontend clang for compiling C, C++, Objective C and Objective C++ to LLVM bitcode IR. Many of the other tools such as the optimizer opt, assembler, linker, and backends then operate on the LLVM IR, to finally produce machine code. LLVM envisions that transformations and analyses can be applied during compile-time, link-time, runtime, and offline.

LLVM IR is a language that resembles assembler, but which provides type-safety and has virtual registers that are in Static Single Assignment (SSA) form.

Here is some pieces of human readeable generated LLVM IR:

@.str = private unnamed_addr constant [14 x i8]
    c"Hello World \0A\00", align 1
@str = internal constant [13 x i8] c"Hello World \00"

define i32 @main() nounwind uwtable {
%puts = tail call i32 @puts(i8* getelementptr inbounds
  ([13 x i8]* @str, i64 0, i64 0))
ret i32 0

One could recognize some traces of the classic C hello world below that was used to generate the IR above:

#include <stdio.h>
int main() {
    printf("Hello World \n");

All this from the Sulong project intro page:

Sulong (Graal LLVM) is an interpreter for LLVM IR written in Java using the Truffle language implementation framework and Graal as a just-in-time (JIT) compiler.

With Sulong you can execute C/C++, Fortran, and other programs written in a LLVM language on the JVM. To execute a program by Sulong, you have to compile the program to LLVM IR by a LLVM front end such as Clang. By using Truffle and Java the interpreter implementation is simple and is thus a great platform for experimentation. On the other hand, dynamic optimizations and JIT compilation with Graal still provides native execution speed (improving performance is work in progress). Through Truffle's language interoperability capabilities, you will soon be able to call functions from/to other languages on Truffle such as Ruby, JavaScript, or R.

Design the Language and receive the best 'dna' traits at its birth

I've posted a few entries based on this article about Graal & Truffle, here are some highlights of this article:

Truffle is a framework for writing interpreters with annotations and small bits of extra code in them which, when Truffle is paired with its sister project Graal, allow those interpreters to be converted into JIT compiling VMs … automatically. The resulting runtimes have peak performance competitive with the best hand-tuned language-specific compilers on the market. For example, the TruffleJS engine which implements JavaScript is competitive with V8 in benchmarks. The RubyTruffle engine is faster than all other Ruby implementations by far. The TruffleC engine is roughly competitive with GCC.

This project could advance an order of grandess the quick experimentation|variability and consequent evolution of new programming languages|platforms. The modern state of the art characteristics of successful programming languages are given without effort to those willing to work with this toolset, which is already showing the remarkable results cited in the excerpt above.

Graal is designed from the start as a multi-language compiler, but its set of optimization techniques is especially well suited to compiling programs with high levels of abstraction and dynamism. It runs Java as fast as the existing JVM compilers do, but when applied to Scala programs it runs them about 20% faster. Ruby programs get 400% faster than the best alternative runtime (i.e. not MRI)."

Some notable languages already experimented with are:

  • Smalltalk;

  • LLVM bitcode, allowing C/C++/Objective-C/Swift programs to run on it;

  • Python 3 (yes, 3);

  • R;

  • Lua (Lua can get 'for free' a state of the art VM... awesome);

Mike Hearn also reminds us that:

To give a feel for how easy it is to write these engines, TruffleJS is only about 80,000 lines of code compared to about 1.7 million for V8.

80k to 1.7mi? That is a gap... and we can thank Oracle Labs for that, and they say:

Graal is a new just-in-time compiler for the JVM, written in Java and focused on performance and language interoperability. Graal offers performance advantages to Java code, thanks to new techniques of method inlining, eliding object allocations and speculative execution - and makes possible high-performance scripting language engines.

Fast scripting languages, this is addressing one of the most common flaws of languages of this nature, one that has become the most popular in the past years.

Portable low level code are not only for VMs

This article presents some good arguments towards assembly level programming using LLVM Intermediate Representation (IR) code. He shows how LLVM front ends all generate IR code from many distinct languages, then general optimization can take place at the IR code which then can be used to generate the real assembly targeting some processor architecture.

He argues in favour of using the expert assembly knownlegde one might have in order to help to enhance the optmization or the {IR to assembly} steps instead of keep repeating this work manually, which is a strong and good argument and he closes saying:

I think it's amazing that once written pseudo-assembly code can be retargetted to any architecture. For me IR has all the advantages of assembly without any of its problems: fast, expressive, retargettable and maintainable.