As you may know, Gambas had a JIT (Just-In-Time) component based on LLVM (Low-Level-Virtual-Machine) - a library of programs for building highly optimized compilers, optimizers, and runtime environments. The old JIT-compiler no longer worked because newer versions of the LLVM are not backward compatible. Therefore, Benoît Minisini decided to write a new JIT-compiler from scratch which compiles Gambas code into C.
The new JIT-compiler is implemented using the gb.jit component in Gambas version 3.12.0. It is loaded automatically when required. It has a C part that implements the GambasToC_Code translator and a Gambas part that deals with the extraction of Gambas source code from executable archive files and the compilation of all translations in one large file.
This is how the Gambas JIT compiler works:
This construction has advantages:
with the disadvantage that code generation is slower (and with gcc even slower) than the old JIT compiler.
The syntax with FAST has not changed: Place the keyword FAST at the beginning of a Gambas class file for a class that is to provide all functions JIT-compiled instead of interpreted, or at the beginning of a function declaration so that only this function is jit-compiled.
The new keyword, UNSAFE, has been introduced, which is only used together with the keyword FAST. When a function is declared as “FAST UNSAFE”, it is jit-compiled, but all security checks are removed (null objects, out-of-array bounds, division by zero, …)! It allows you to speed up the code a little if you are sure it is declared correctly. Otherwise, you will get a memory and/or segmentation error.
These environment variables GB_NO_JIT, GB_JIT_DEBUG, GB_JIT_CC and GB_JIT_CFLAGS control the behavior of the JIT compiler in Gambas Version 3.12.0. The following applies
If you use a stable Gambas and the JIT compiler in your programs, then you are surely interested in the advantage this has for your programs. Tested program runtimes can be found at http://gambaswiki.org/wiki/doc/benchmark. The following adapted Gambas script achieved very different runtimes:
[1] #!/usr/bin/env gbs3 [2] [3] FAST ' Change it! [4] Public Sub Main() [5] Dim I As Integer [6] Dim StartTime As Float [7] [8] StartTime = Timer [9] For I = 1 To 2 ' Runs [10] Print I & ". Run: " & Test(0.2) & " basic calculations" [11] Next [12] Print "----------------------------------" [13] Print "Program runtime = "; GetTime(StartTime, Timer); " seconds" [14] End [15] [16] Private Function Test(X As Float) As Float [17] [18] Dim Mu As Float = 10.0 [19] Dim Pu, Su As Float [20] Dim I, J, N As Integer [21] Dim aPoly As New Float[100] [22] [23] N = 500000 [24] For I = 0 To N - 1 [25] For J = 0 To 99 [26] Mu = (Mu + 2.0) / 2.0 [27] aPoly[J] = Mu [28] Next [29] Su = 0.0 [30] For J = 0 To 99 [31] Su = X * Su + aPoly[J] [32] Next [33] Pu += Su [34] Next [35] Return Pu [36] End [37] [38] Private Function GetTime(StartTime As Float, EndTime As Float) As Float [39] Return Round(EndTime - StartTime, -3) [40] End
The Gambas script - stored in the file jit_p.gbs3 - is called in the console:
hans@mint-183 ~ $ gbs3 ./jit_p.gbs3 1. Run: 1250000 basic calculations 2. Run: 1250000 basic calculations ---------------------------------- Program runtime = 0,755 seconds
hans@mint-183 ~ $ gbs3 ./jit_p.gbs3 1. Run: 1250000 basic calculations 2. Run: 1250000 basic calculations ---------------------------------- Program runtime = 16,688 seconds
With the keyword FAST, which utilizes the JIT-compiler, resulted in a runtime of only 0.755 seconds, which corresponds to a runtime ratio of about 22:1 between Gambas and Gambas with JIT-compiler!
You can also use the keywords 'FAST UNSAFE' by deleting the upper line 3 completely and rewriting line 16:
[16] FAST UNSAFE Private Function Test(X As Float) As Float
Then only this function Test(..) is jit-compiled! In another test the same results were shown as expected with the runtimes.