Gambas Documentation
Application Repository
Code Snippets
Compilation & Installation from source code
Components
Controls pictures
Deprecated components
Developer Documentation
Development Environment Documentation
Documents
About The Best Formula In The World
Architecture details
Benchmarks
Books
By Reference Argument Passing
Compatibility between versions
Creating And Using Libraries
Database Datatype Mapping
Database Request Quoting
Date & time management
Dates and calendars
DBus and Gambas
Differences Between Shell And Exec
Differences From Visual Basic
Distributions & Operating Systems
Drag & Drop
DrawingArea Internal Behaviour
External functions datatype mapping
Frequently Asked Questions
Gambas Farm Server Protocol
Gambas Mailing List Netiquette
Gambas Markdown Syntax
Gambas Naming Conventions
Gambas Object Model
Gambas Scripting
Gambas Server Pages
Gambas Unit Testing
Gambas Wiki Markup Syntax
Getting Started With Gambas
Hall Of Fame
Housekeeping, cleaning up
Image Management In Gambas
Including Help Comments in Source Code
Installation from binary packages
Interpreter limits
Introduction
Just In Time Compiler
Just In Time Compiler (old version)
License
Localisation and Internationalization
Mailing Lists & Forums
Naming Conventions
Network Programming
ODBC Component Documentation
PCRE Pattern Syntax
Porting from Gambas 2 to Gambas 3
Previous News
Project Directory Structure
Release Notes
Reporting a problem, a bug or a crash
Rich Text Syntax
Screenshots
Text highlighting definition file syntax
The Program has stopped unexpectedly by raising signal #11
Variable Naming Convention
WebPage Syntax
Web site home page
What Is Gambas?
Window & Form Management
Window Activation & Deactivation
Window Life Cycle
XML APIs
Error Messages
Gambas Playground
How To's
Language Index
Language Overviews
Last Changes
Lexicon
README
Search the wiki
To Do
Topics
Tutorials
Wiki License
Wiki Manual

Just In Time Compiler

Since 3.12

The old just-in-time compiler didn't work anymore because of LLVM being not backward-compatible. As we have no news from the author, I decided to write a new just-in-time compiler from scratch.

By the way, I'd like to know if the LLVM developers and the GTK+ developers are the same guys...

This unfortunate experience has burned me, so I decided to design it differently. Instead of relying on a undeterministic moving beta API of all possible compilers, the new Gambas JIT compiler translates the Gambas code into C.

How it works

The process is the following:

  • When a function marked with the FAST keyword is called for the first time, the JIT compiler is called.

  • If not yet done, the JIT compiler translates all the fast methods of the current project (or component) into a big C source file.

  • Then the C compiler is called to generate a shared library from that big C source file.

  • The shared lbrary is loaded dynamically.

  • The JIT compiled function is called.

This design has many advantages:
  • You can use either gcc or clang, or tcc (see below).

  • As long as the C standard does not change, the JIT compiler will not break.

But some disadvantages too:
  • The code generation is slower (and even slower with gcc). To workaround this slowness, the compilation is done in background processes.

  • Sometimes a compiler quirk bites you (for example, using __attribute__((noreturn)) makes the gcc optimizer become mad and slow as hell).

The JIT compiler is implemented in a component that is automatically loaded when needed. It has a C part that implements the Gambas to C code translator, and a Gambas part that deals with extracting Gambas source code from executable archive files and assembling all the translations into one big file.

Syntax

The syntax did not change: place the keyword FAST at the top of a Gambas class file, for a class that you want all functions JIT-compiled instead of interpreted, or at the beginning of a function declaration, so that only that function is JIT-compiled.

JIT compiling has a cost, so try to use it only on specific methods that need a boost.

Caveats

Some language syntax is not supported at the moment:
  • The BYREF keyword.

  • Propagating variable arguments to another function call with the ... syntax.

  • Using tcc is possible, but that compiler is not very reliable and may generate incorrect code.

Performance

The biggest increases in speed will be in functions that use a lot of low-level computations and control flows (except For Each loops), such as functions that do a lot of math. However, if the function mostly calls other libraries, you won't see any great increase in speed.

You won't see any significative gain in string management.

See Benchmarks for more details.

Debugging

At the moment, some environment variables control the behavior of the JIT compiler.

Environment variable Description
GB_NO_JIT Set to 1 if you want to disable the JIT compiler entirely.
GB_JIT_DEBUG Set to 1 if you want to see the debugging message emitted by the JIT compiler.
GB_JIT_CC Set to the name of the compiler to use. By default gcc is used. But you can put clang instead, or anything else provided that it uses the same options as gcc or support for it is added in the JIT compiler Gambas part.
GB_JIT_CFLAGS Set it to the flags used for compiling the C code. The default is -O3.

See also