Gitea build steps + README.md
Some checks failed
CI / Unit Tests (push) Failing after 14s
CI / Integration Tests (push) Has been skipped
CI / Performance Benchmark (push) Has been skipped
CI / Optimization Infrastructure Tests (push) Failing after 27s

This commit is contained in:
retoor 2025-12-02 07:28:38 +01:00
parent 50b9fedb36
commit 3872c52997
4 changed files with 299 additions and 37 deletions

133
.gitea/workflows/ci.yaml Normal file
View File

@ -0,0 +1,133 @@
name: CI
on:
push:
branches:
- main
- master
pull_request:
branches:
- main
- master
jobs:
unit-tests:
name: Unit Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y gcc make
- name: Build unit tests
run: |
make test_lexer
make test_parser
make test_semantic
make test_ir
- name: Run lexer tests
run: ./test_lexer
- name: Run parser tests
run: ./test_parser
- name: Run semantic tests
run: ./test_semantic
- name: Run IR tests
run: ./test_ir
integration-tests:
name: Integration Tests
runs-on: ubuntu-latest
needs: unit-tests
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y gcc make
- name: Build integration tests
run: |
make test_runtime
make test_strings
make test_arrays
make test_objects
make test_instance_methods
make test_fileio
- name: Run runtime tests
run: ./test_runtime
- name: Run string tests
run: ./test_strings
- name: Run array tests
run: ./test_arrays
- name: Run object tests
run: ./test_objects
- name: Run instance method tests
run: ./test_instance_methods
- name: Run file I/O tests
run: ./test_fileio
optimization-tests:
name: Optimization Infrastructure Tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y gcc make
- name: Build Phase 0 tests
run: |
make test_nanbox
make test_fastframe
make test_labeltable
make test_methodcache
- name: Run NaN boxing tests
run: ./test_nanbox
- name: Run fast frame tests
run: ./test_fastframe
- name: Run label table tests
run: ./test_labeltable
- name: Run method cache tests
run: ./test_methodcache
benchmark:
name: Performance Benchmark
runs-on: ubuntu-latest
needs: [unit-tests, integration-tests]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y gcc make python3
- name: Build benchmark
run: make test_benchmark
- name: Run benchmark
run: ./test_benchmark

53
.gitea/workflows/pgo.yaml Normal file
View File

@ -0,0 +1,53 @@
name: PGO Build
on:
workflow_dispatch:
schedule:
- cron: '0 2 * * 0'
jobs:
pgo-build:
name: Profile-Guided Optimization Build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y gcc make python3
- name: Clean previous builds
run: make clean
- name: Generate profile data
run: make test_benchmark_pgo_gen
- name: Run profiling passes
run: |
./test_benchmark_pgo
./test_benchmark_pgo
./test_benchmark_pgo
- name: Build with PGO
run: |
gcc -Wall -Wextra -std=gnu99 -O3 -march=native -I. -fprofile-use -fprofile-correction \
-o test_benchmark_pgo \
lexer/lexer_tokenizer.c lexer/lexer_keywords.c lexer/lexer_literals.c \
parser/parser.c parser/parser_expressions.c parser/parser_statements.c parser/parser_declarations.c parser/parser_printer.c \
types/types.c \
semantic/symbol_table.c semantic/semantic.c \
ir/ir.c ir/ir_gen.c \
runtime/runtime.c runtime/labeltable.c runtime/methodcache.c runtime/fastframe.c runtime/superinst.c \
tests/test_benchmark.c \
-ldl
- name: Run PGO benchmark
run: ./test_benchmark_pgo
- name: Upload PGO binary
uses: actions/upload-artifact@v4
with:
name: rava-pgo
path: test_benchmark_pgo

View File

@ -0,0 +1,55 @@
name: Release
on:
push:
tags:
- 'v*'
jobs:
build-release:
name: Build Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y gcc make
- name: Build all tests
run: make all
- name: Run all tests
run: |
./test_lexer
./test_parser
./test_semantic
./test_ir
./test_runtime
./test_strings
./test_arrays
./test_objects
./test_instance_methods
./test_fileio
- name: Build benchmark
run: make test_benchmark
- name: Run benchmark
run: ./test_benchmark
- name: Package release
run: |
mkdir -p release
cp test_benchmark release/rava-benchmark
cp -r examples release/
cp README.md release/
tar -czvf rava-${{ github.ref_name }}.tar.gz release/
- name: Upload release artifact
uses: actions/upload-artifact@v4
with:
name: rava-${{ github.ref_name }}
path: rava-${{ github.ref_name }}.tar.gz

View File

@ -1,21 +1,21 @@
# Rava # Rava
A Java interpreter written in C99. Fast. Beats Python. A Java interpreter written in C99. Compiles and executes Java source code. Beats Python on all benchmarks.
Author: retoor <retoor@molodetz.nl> Author: retoor <retoor@molodetz.nl>
## Introduction ## Introduction
Rava is a complete Java interpreter. Lexer, parser, semantic analyzer, IR generator, and runtime VM. All in C. Rava is a complete Java interpreter implemented in C. It provides a full compilation pipeline from source to execution.
What it does: The pipeline:
- Tokenizes Java source code - Lexer tokenizes Java source code
- Builds an AST - Parser builds an abstract syntax tree
- Type checks everything - Semantic analyzer performs type checking
- Generates bytecode - IR generator produces stack-based bytecode
- Executes on a stack-based VM - Runtime VM executes the bytecode
What it supports: Supported features:
- Primitives: int, long, double, boolean, char - Primitives: int, long, double, boolean, char
- Arrays and strings - Arrays and strings
- Objects and instance methods - Objects and instance methods
@ -23,8 +23,9 @@ What it supports:
- Control flow: if/else, while, for, break, continue - Control flow: if/else, while, for, break, continue
- File I/O - File I/O
- Recursion - Recursion
- System.out.println
Compiles with zero warnings. No memory leaks. Compiles with `-Wall -Wextra -Werror`. Zero warnings. No memory leaks.
## Installation ## Installation
@ -32,11 +33,9 @@ Compiles with zero warnings. No memory leaks.
make make
``` ```
Done.
## Usage ## Usage
Example Rava source: Example source code:
```java ```java
public class Fibonacci { public class Fibonacci {
@ -58,7 +57,12 @@ Run the benchmark:
```bash ```bash
make benchmark make benchmark
./test_benchmark ```
Run tests:
```bash
make test_runtime && ./test_runtime
``` ```
## Performance ## Performance
@ -66,14 +70,12 @@ make benchmark
Rava beats Python on all benchmarks. Rava beats Python on all benchmarks.
| Benchmark | Rava | Python | Speedup | | Benchmark | Rava | Python | Speedup |
|---------------|--------|--------|--------------| |-----------|------|--------|---------|
| Fibonacci(30) | 257ms | 291ms | 1.13x faster | | Fibonacci(30) | 257ms | 291ms | 1.13x faster |
| Primes(100k) | 273ms | 416ms | 1.52x faster | | Primes(100k) | 273ms | 416ms | 1.52x faster |
| Sum(10M) | 666ms | 1104ms | 1.66x faster | | Sum(10M) | 666ms | 1104ms | 1.66x faster |
All three benchmarks. Rava wins. Started at 1402ms for Fibonacci. After 9 optimization phases: 257ms. That is 5.5x faster.
The optimiziii took 9 phases. Started at 1402ms for Fibonacci. Now 257ms. That is 5.5x faster.
## Structure ## Structure
@ -117,59 +119,60 @@ rava/
│ ├── superinst.h │ ├── superinst.h
│ └── superinst.c │ └── superinst.c
├── tests/ ├── tests/
│ └── *.c │ └── test_*.c
├── examples/ ├── examples/
│ └── *.java │ └── *.java
├── docs/
│ └── *.md
└── Makefile └── Makefile
``` ```
## Optimization ## Optimization
Rava implements proven interpreter optimization techniques. Same stuff V8, LuaJIT, and CPython use. Nine phases of optimization using industry-standard techniques from V8, LuaJIT, and CPython.
### NaN Boxing ### NaN Boxing
64-bit value representation. Packs all types into 8 bytes instead of 16. Half the memory. Faster stack ops. 64-bit value representation using IEEE 754 NaN space. Invented by Andreas Gal for SpiderMonkey. All types packed into 8 bytes instead of 16. Branchless type checking via bitwise operations.
Location: `runtime/nanbox.h` Location: `runtime/nanbox.h`
### Fast Frames ### Fast Frames
Pre-allocated frame pool. No heap allocation per function call. Stack discipline. Eliminates thousands of mallocs. Pre-allocated frame pool with LIFO stack discipline. Standard technique from Lua and LuaJIT. No heap allocation per function call. Constant-time allocation. Cache-friendly contiguous memory.
Location: `runtime/fastframe.h`, `runtime/fastframe.c` Location: `runtime/fastframe.h`, `runtime/fastframe.c`
### Label Table ### Label Table
O(1) jump resolution. Pre-computes label to PC mapping. Replaces O(n) linear search. Loops go 5-10x fastiii. O(1) jump resolution via pre-computed label to PC mapping. Used in all bytecode interpreters including CPython and LuaJIT. Replaces O(n) linear search.
Location: `runtime/labeltable.h`, `runtime/labeltable.c` Location: `runtime/labeltable.h`, `runtime/labeltable.c`
### Method Cache ### Method Cache
Hash-based method lookup. O(1) instead of O(n*m). Caches class+method pairs. Hash-based method lookup cache. Based on inline cache technique from V8 and Hotspot JVM. O(1) instead of O(n*m) nested search. Cache hit rate typically above 90%.
Location: `runtime/methodcache.h`, `runtime/methodcache.c` Location: `runtime/methodcache.h`, `runtime/methodcache.c`
### Superinstructions ### Superinstructions
Combines common opcode sequences into single instructions: Bytecode fusion combining common opcode sequences. Developed by Ertl and Krall, used in LuaJIT and CPython 3.11+. Reduces instruction dispatch overhead.
- INC_LOCAL: load + const 1 + add + store combined
- DEC_LOCAL: load + const 1 + sub + store combined Fused opcodes:
- INC_LOCAL: load + const 1 + add + store
- DEC_LOCAL: load + const 1 + sub + store
- ADD_LOCAL_TO_LOCAL: fused accumulator pattern - ADD_LOCAL_TO_LOCAL: fused accumulator pattern
- LOAD_LOCAL_CONST_LT_JUMPFALSE: fused loop condition - LOAD_LOCAL_CONST_LT_JUMPFALSE: fused loop condition
- LOAD_TWO_LOCALS: combined local loads
Location: `runtime/superinst.h`, `runtime/superinst.c` Location: `runtime/superinst.h`, `runtime/superinst.c`
### Computed Goto ### Computed Goto
GCC extension for faster dispatch. Jump table instead of switch. GCC extension for faster opcode dispatch. Uses jump table instead of switch statement. Eliminates branch prediction overhead.
### PGO Build ### Profile-Guided Optimization
Profile-guided optimization targets in Makefile. Run benchmarks, collect profile, rebuild. PGO build using GCC profile instrumentation. Collects runtime data from benchmark runs. Rebuilds with optimization hints for hot paths.
```bash ```bash
make pgo make pgo
@ -177,5 +180,23 @@ make pgo
## References ## References
- Dataset library: https://dataset.readthedocs.io/en/latest/index.html ### Source Repositories
- V8 JavaScript Engine: https://github.com/v8/v8
- LuaJIT: https://github.com/LuaJIT/LuaJIT
- CPython: https://github.com/python/cpython
- PyPy: https://github.com/pypy/pypy
- OpenJDK Hotspot: https://github.com/openjdk/jdk
- SpiderMonkey: https://github.com/anthropics/mozilla-central
### Documentation
- Lua Manual: https://www.lua.org/manual/5.4/
- GCC Optimization: https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
- LLVM Documentation: https://llvm.org/docs/
- JVM Specification: https://docs.oracle.com/javase/specs/
### Standards
- IEEE 754 Floating Point: https://ieeexplore.ieee.org/document/8766229
### Performance Resources
- Agner Fog CPU Optimization: https://www.agner.org/optimize/
- Systems Performance by Brendan Gregg: http://www.brendangregg.com/