All source listed below is under MIT license if no LICENSE file stating different is available.

Rava

A Java interpreter written in C99. Fast. Beats Python.

Author: retoor retoor@molodetz.nl

Introduction

Rava is a complete Java interpreter. Lexer, parser, semantic analyzer, IR generator, and runtime VM. All in C.

What it does:

  • Tokenizes Java source code
  • Builds an AST
  • Type checks everything
  • Generates bytecode
  • Executes on a stack-based VM

What it supports:

  • Primitives: int, long, double, boolean, char
  • Arrays and strings
  • Objects and instance methods
  • Inheritance
  • Control flow: if/else, while, for, break, continue
  • File I/O
  • Recursion

Compiles with zero warnings. No memory leaks.

Installation

make

Done.

Usage

Example Rava source:

public class Fibonacci {
    public static int fib(int n) {
        if (n <= 1) {
            return n;
        }
        return fib(n - 1) + fib(n - 2);
    }

    public static int main() {
        System.out.println(fib(30));
        return 0;
    }
}

Run the benchmark:

make benchmark
./test_benchmark

Performance

Rava beats Python on all benchmarks.

Benchmark Rava Python Speedup
Fibonacci(30) 257ms 291ms 1.13x faster
Primes(100k) 273ms 416ms 1.52x faster
Sum(10M) 666ms 1104ms 1.66x faster

All three benchmarks. Rava wins.

The optimiziii took 9 phases. Started at 1402ms for Fibonacci. Now 257ms. That is 5.5x faster.

Structure

rava/
├── lexer/
│   ├── lexer.h
│   ├── lexer_tokenizer.c
│   ├── lexer_keywords.c
│   └── lexer_literals.c
├── parser/
│   ├── parser.h
│   ├── parser.c
│   ├── parser_expressions.c
│   ├── parser_statements.c
│   ├── parser_declarations.c
│   └── parser_printer.c
├── types/
│   ├── types.h
│   └── types.c
├── semantic/
│   ├── semantic.h
│   ├── semantic.c
│   ├── symbol_table.h
│   └── symbol_table.c
├── ir/
│   ├── ir.h
│   ├── ir.c
│   ├── ir_gen.h
│   └── ir_gen.c
├── runtime/
│   ├── runtime.h
│   ├── runtime.c
│   ├── nanbox.h
│   ├── fastframe.h
│   ├── fastframe.c
│   ├── labeltable.h
│   ├── labeltable.c
│   ├── methodcache.h
│   ├── methodcache.c
│   ├── superinst.h
│   └── superinst.c
├── tests/
│   └── *.c
├── examples/
│   └── *.java
├── docs/
│   └── *.md
└── Makefile

Optimization

Rava implements proven interpreter optimization techniques. Same stuff V8, LuaJIT, and CPython use.

NaN Boxing

64-bit value representation. Packs all types into 8 bytes instead of 16. Half the memory. Faster stack ops.

Location: runtime/nanbox.h

Fast Frames

Pre-allocated frame pool. No heap allocation per function call. Stack discipline. Eliminates thousands of mallocs.

Location: runtime/fastframe.h, runtime/fastframe.c

Label Table

O(1) jump resolution. Pre-computes label to PC mapping. Replaces O(n) linear search. Loops go 5-10x fastiii.

Location: runtime/labeltable.h, runtime/labeltable.c

Method Cache

Hash-based method lookup. O(1) instead of O(n*m). Caches class+method pairs.

Location: runtime/methodcache.h, runtime/methodcache.c

Superinstructions

Combines common opcode sequences into single instructions:

  • INC_LOCAL: load + const 1 + add + store combined
  • DEC_LOCAL: load + const 1 + sub + store combined
  • ADD_LOCAL_TO_LOCAL: fused accumulator pattern
  • LOAD_LOCAL_CONST_LT_JUMPFALSE: fused loop condition

Location: runtime/superinst.h, runtime/superinst.c

Computed Goto

GCC extension for faster dispatch. Jump table instead of switch.

PGO Build

Profile-guided optimization targets in Makefile. Run benchmarks, collect profile, rebuild.

make pgo

References

examples
ir
lexer
parser
runtime
semantic
tests
types
Makefile
README.md