# 機能設計書 86-AOTコンパイル

## 概要

本ドキュメントは、JuliaのAOT（Ahead-Of-Time）コンパイル機能の設計を記述する。sysimage（システムイメージ）および pkgimage（パッケージイメージ）の事前コンパイルとシリアライズを行い、Julia の起動時間短縮と初回実行時のコンパイル遅延の削減を実現する。

### 本機能の処理概要

AOT コンパイルは、Julia のメソッドを実行前にネイティブコードにコンパイルし、ディスク上のイメージファイルに保存する機能である。

**業務上の目的・背景**：Julia の JIT コンパイルは初回呼び出し時にレイテンシ（TTFX: Time To First eXecution）を発生させる。特に、Base ライブラリや標準ライブラリのような頻繁に使用されるコードを毎回 JIT コンパイルすることは非効率である。AOT コンパイルにより、これらのコードを事前にコンパイルしてイメージファイルに保存することで、起動時間を大幅に短縮し、ユーザー体験を向上させる。

**機能の利用シーン**：
- Julia のビルド時に sysimage（`sys.so`/`sys.dylib`/`sys.dll`）を生成
- `using` / `import` 時に pkgimage をプリコンパイルして `.ji` ファイルに保存
- `PackageCompiler.jl` 等の外部ツールによるカスタム sysimage の生成

**主要な処理内容**：
1. `jl_create_native`: コンパイル対象メソッドの収集と LLVM Module への変換
2. LLVM 最適化パスの適用: O0-O3 レベルの最適化
3. オブジェクトファイル生成: ターゲットアーキテクチャのバイナリ出力
4. `jl_write_values` によるシリアライズ: Julia オブジェクトのバイナリ化
5. リロケーション情報の生成: デシリアライズ時のポインタ修正テーブル
6. zstd 圧縮: シリアライズデータの圧縮

**関連システム・外部連携**：コード生成（No.84）を内部で使用。JITコンパイル（No.85）と同じ codegen インフラを共有。型推論（No.79）で推論されたメタデータがシリアライズされる。

**権限による制御**：特になし。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| - | - | - | 本機能はビルドシステム内部機能であり、直接的なUI画面は存在しない |

## 機能種別

計算処理（事前コンパイル・シリアライズ処理）

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| CodeInstance リスト | jl_code_instance_t** | Yes | コンパイル対象の CodeInstance 配列 | 有効な CodeInstance であること |
| policy | int | No | コンパイルポリシー（extern/extern_sa 等） | 有効なポリシー値 |
| 最適化レベル | int | No | LLVM 最適化レベル（0-3） | 0-3 の範囲内 |

### 入力データソース

- プリコンパイル対象のメソッドリスト
- 既存の sysimage（増分コンパイルの場合）

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| jl_native_code_desc_t | struct | コンパイルされたネイティブコード情報 |
| sysimage/pkgimage | バイナリファイル | シリアライズされたイメージファイル |
| 関数変数テーブル | SmallVector | 関数ポインタのルックアップテーブル |

### 出力先

- sysimage: `usr/lib/julia/sys.so` 等
- pkgimage: `~/.julia/compiled/` 下のキャッシュディレクトリ

## 処理フロー

### 処理シーケンス

```
1. jl_create_native: ネイティブコード生成
   └─ 対象 CodeInstance を収集し LLVM Module を構築
2. LLVM 最適化パスの適用
   └─ PassBuilder による最適化パイプラインの実行
3. オブジェクトファイル生成
   └─ LLVM のコード生成器でターゲットバイナリを生成
4. シリアライズ（staticdata.c）
   └─ Step 1: serialization_order の構築（オブジェクトの列挙）
   └─ Step 2: 各オブジェクトの実際のシリアライズ
   └─ Step 3: 各セクションの結合
5. リロケーション情報の生成
   └─ relocs_list / gctags_list の生成
6. uniquing 情報の生成
   └─ 外部 DataType / MethodInstance のユニーク化テーブル
7. zstd 圧縮
   └─ シリアライズデータの圧縮
8. ファイル書き出し
   └─ .so/.dylib/.dll/.ji 形式で出力
```

### フローチャート

```mermaid
flowchart TD
    A[AOTコンパイル開始] --> B[jl_create_native]
    B --> C[CodeInstance 収集]
    C --> D[LLVM Module 構築]
    D --> E[LLVM 最適化パス]
    E --> F[オブジェクトファイル生成]
    F --> G[シリアライズ: serialization_order 構築]
    G --> H[シリアライズ: jl_write_values]
    H --> I[リロケーション情報生成]
    I --> J[uniquing 情報生成]
    J --> K[zstd 圧縮]
    K --> L[ファイル出力]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-86-01 | シリアライズ順序 | オブジェクトは serialization_order に挿入された順序でシリアライズされる | 全シリアライズ |
| BR-86-02 | COMDAT | WindowsのCOFFフォーマットではCOMDATセクションが必要で、DLLExportが設定される | Windows ターゲット |
| BR-86-03 | uniquing | デシリアライズ時に既存の DataType/MethodInstance と重複チェックが行われる | デシリアライズ時 |
| BR-86-04 | バックエッジ検証 | 外部エッジはデシリアライズ時に検証され、無効化された場合は再コンパイルが必要 | pkgimage ロード時 |
| BR-86-05 | ポインタ再配置 | リロケーションテーブルに基づいてデシリアライズ時にポインタが修正される | デシリアライズ時 |

### 計算ロジック

リロケーションエンコーディング:
```
index = tag << RELOC_TAG_OFFSET + i
```
ここで `tag` は RefTags 列挙値、`i` はカテゴリ別リストのインデックス。

## データベース操作仕様

本機能はデータベースを使用しない。

### 操作別データベース影響一覧

該当なし。

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | シリアライズエラー | オブジェクトの循環参照等 | スタックベースのワークキューで回避 |
| - | LLVM コード生成エラー | 不正な LLVM IR | abort |
| - | zstd 圧縮エラー | 圧縮バッファ不足 | エラーコード返却 |

### リトライ仕様

該当なし。

## トランザクション仕様

シリアライズは全体が成功するか失敗するかのアトミック操作。部分的な sysimage は不正とみなされる。

## パフォーマンス要件

- sysimage 生成はビルド時に実行されるため、実行時パフォーマンスには直接影響しない
- デシリアライズ（起動時のロード）は高速であるべき
- zstd 圧縮によりイメージファイルサイズを削減

## セキュリティ考慮事項

- シリアライズデータの改竄は実行時に未定義動作を引き起こす
- pkgimage はファイルシステムのパーミッションで保護

## 備考

- CreateNativeCalls, CreateNativeMethods 等の LLVM STATISTIC で統計情報を収集
- `jl_get_function_id_impl` で CodeInstance と関数インデックスの対応を取得可能
- staticdata.c のコメントにシリアライズの詳細なフロー説明がある

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | aotcompile.cpp | `src/aotcompile.cpp` | jl_native_code_desc_t 構造体（72-79行目）: AOTコンパイル結果を保持 |
| 1-2 | staticdata.c | `src/staticdata.c` | 冒頭コメント（1-60行目）: シリアライズの全体フローの詳細解説 |

**読解のコツ**: staticdata.c の冒頭コメント（約60行）はシリアライズのアーキテクチャを詳細に説明しており、コードを読む前に必ず目を通すべきである。特に serialization_order、relocs_list、gctags_list、uniquing の関係を把握することが重要。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | aotcompile.cpp | `src/aotcompile.cpp` | jl_get_function_id_impl（82-93行目）: 関数ID取得 |
| 2-2 | aotcompile.cpp | `src/aotcompile.cpp` | jl_get_llvm_cis_impl（95-99行目）: CodeInstance リスト取得 |
| 2-3 | aotcompile.cpp | `src/aotcompile.cpp` | addComdat 関数（62-69行目）: Windows向けCOMDAT設定 |

**主要処理フロー**:
1. **72-79行目**: jl_native_code_desc_t に Module、関数変数テーブル、関数マップを保持
2. **82-93行目**: jl_fvar_map から CodeInstance → (func_idx, specfunc_idx) の対応を検索

#### Step 3: シリアライズの詳細を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | staticdata.c | `src/staticdata.c` | jl_queue_for_serialization: オブジェクトの収集（Step 1） |
| 3-2 | staticdata.c | `src/staticdata.c` | jl_write_values: 実際のシリアライズ（Step 2） |

### プログラム呼び出し階層図

```
ビルドシステム (Makefile / precompilation.jl)
    |
    +-- jl_create_native (aotcompile.cpp)
    |      +-- codegen (codegen.cpp)
    |      +-- LLVM 最適化パス
    |      +-- オブジェクトファイル生成
    |
    +-- シリアライズ (staticdata.c)
    |      +-- jl_queue_for_serialization (Step 1)
    |      +-- jl_write_values (Step 2)
    |      +-- セクション結合 (Step 3)
    |
    +-- zstd 圧縮
    +-- ファイル出力
```

### データフロー図

```
[入力]                       [処理]                      [出力]

CodeInstance リスト  --> jl_create_native          --> LLVM Module + メタデータ
LLVM Module         --> LLVM 最適化               --> 最適化済み Module
最適化済み Module   --> オブジェクトコード生成     --> ネイティブコード
Julia オブジェクト  --> シリアライズ               --> バイナリストリーム
バイナリストリーム  --> zstd 圧縮                  --> 圧縮データ
ネイティブ + 圧縮   --> ファイル出力               --> sysimage / pkgimage
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| aotcompile.cpp | `src/aotcompile.cpp` | ソース | AOTコンパイルのメインエントリーポイント |
| staticdata.c | `src/staticdata.c` | ソース | Julia オブジェクトのシリアライズ・デシリアライズ |
| serialize.h | `src/serialize.h` | ヘッダ | シリアライズのタグ・定数定義 |
| codegen.cpp | `src/codegen.cpp` | ソース | Julia IR → LLVM IR 変換（共有） |
| jitlayers.h | `src/jitlayers.h` | ヘッダ | LLVM モジュール型定義 |
| processor.h | `src/processor.h` | ヘッダ | ターゲットプロセッサ情報 |
