libbcc: A Versatile Bitcode Execution Engine for Mobile Devices

Introduction

libbcc is an LLVM bitcode execution engine that compiles the bitcode to an in-memory executable. libbcc is versatile because:

libbcc provides:

Highlights of libbcc are:

API

Basic:

Reflection:

Debug:

Cache File Format

A cache file (denoted as *.oBCC) for libbcc consists of several sections: header, string pool, dependencies table, relocation table, exported variable list, exported function list, pragma list, function information table, and bcc context. Every section should be aligned to a word size. Here is the brief description of each sections:

For furthur information, you may read bcc_cache.h, CacheReader.cpp, and CacheWriter.cpp for details.

JIT'ed Code Calling Conventions

  1. Calls from Execution Environment or from/to within script:

    On ARM, the first 4 arguments will go into r0, r1, r2, and r3, in that order. The remaining (if any) will go through stack.

    For ext_vec_types such as float2, a set of registers will be used. In the case of float2, a register pair will be used. Specifically, if float2 is the first argument in the function prototype, float2.x will go into r0, and float2.y, r1.

    Note: stack will be aligned to the coarsest-grained argument. In the case of float2 above as an argument, parameter stack will be aligned to an 8-byte boundary (if the sizes of other arguments are no greater than 8.)

  2. Calls from/to a separate compilation unit: (E.g., calls to Execution Environment if those runtime library callees are not compiled using LLVM.)

    On ARM, we use hardfp. Note that double will be placed in a register pair.