# 機能設計書 36-v8

## 概要

本ドキュメントは、Node.js の `v8` モジュール（V8エンジン関連API）の機能設計書である。このモジュールは、V8 JavaScriptエンジンの内部機能にアクセスするためのAPIを提供し、ヒープ統計、シリアライゼーション、GCプロファイリングなどの機能を利用可能にする。

### 本機能の処理概要

v8 モジュールは、Node.js の基盤となるV8 JavaScriptエンジンの診断・デバッグ機能へのアクセスを提供する。メモリ使用状況の監視、ヒープスナップショットの取得、オブジェクトのシリアライズ/デシリアライズ、GCの監視など、パフォーマンス分析やデバッグに必要な機能を含む。

**業務上の目的・背景**：アプリケーションのメモリリーク検出、パフォーマンス分析、プロセス間でのデータ転送、スタートアップスナップショットの作成など、高度な診断・最適化のためにV8エンジンの内部機能へのアクセスが必要となる場面がある。

**機能の利用シーン**：
- メモリリークの調査（ヒープスナップショット）
- メモリ使用量のモニタリング（ヒープ統計）
- プロセス間通信でのデータシリアライズ
- GCパフォーマンスの分析
- CPUプロファイリング
- スタートアップ高速化（起動スナップショット）

**主要な処理内容**：
1. ヒープ統計の取得（`getHeapStatistics()` / `getHeapSpaceStatistics()` / `getHeapCodeStatistics()`）
2. ヒープスナップショットの作成（`writeHeapSnapshot()` / `getHeapSnapshot()`）
3. オブジェクトのシリアライズ/デシリアライズ（`serialize()` / `deserialize()`）
4. V8フラグの設定（`setFlagsFromString()`）
5. GCプロファイリング（`GCProfiler`）
6. CPUプロファイリング（`startCpuProfile()`）

**関連システム・外部連携**：
- V8 JavaScript エンジン
- Chrome DevTools（ヒープスナップショット解析）
- Node.js の `inspector` モジュール

**権限による制御**：特段の権限制御は存在しない。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 1 | V8 Tools Landing Page | 主機能 | V8エンジン関連ツール群へのナビゲーション |
| 2 | System Analyzer | 主機能 | V8ログファイルの解析・表示 |
| 3 | Profview (Tick Processor) | 主機能 | V8プロファイリングログのビジュアライズ |
| 4 | Turbolizer | 主機能 | TurboFanコンパイラグラフの可視化 |
| 5 | Turbolizer Info View | 補助機能 | Turbolizerのヘルプ情報表示 |
| 6 | Heap Statistics | 主機能 | V8ヒープメモリ使用状況の統計表示 |
| 7 | Heap Layout | 主機能 | V8ヒープレイアウトの可視化 |
| 8 | Zone Statistics | 主機能 | V8 Zoneメモリ使用量の統計表示 |
| 9 | Callstats | 主機能 | V8ランタイムコール統計のビジュアライズ |
| 10 | Parse Processor | 主機能 | V8パース・コンパイル・初回実行の分析 |

## 機能種別

診断 / プロファイリング / シリアライゼーション

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| filename | string | No | ヒープスナップショットのファイル名 | 有効なパス |
| flags | string | Yes | V8コマンドラインフラグ | 文字列であること |
| value | any | Yes | シリアライズするオブジェクト | - |
| buffer | Buffer | Yes | デシリアライズするバッファ | Buffer であること |
| options.exposeInternals | boolean | No | 内部オブジェクトを公開するか | 真偽値 |
| options.exposeNumericValues | boolean | No | 数値を公開するか | 真偽値 |

### 入力データソース

- アプリケーションコードからの呼び出し
- V8エンジンの内部状態

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| heapStatistics | object | ヒープ統計情報 |
| heapSpaceStatistics | object[] | ヒープスペース統計情報の配列 |
| heapCodeStatistics | object | ヒープコード統計情報 |
| heapSnapshot | Readable | ヒープスナップショットのストリーム |
| serializedBuffer | Buffer | シリアライズされたデータ |

### 出力先

- 戻り値としてのオブジェクト・バッファ
- ファイルシステム（ヒープスナップショット）

## 処理フロー

### 処理シーケンス

```
1. ヒープ統計取得
   └─ getHeapStatistics() でV8からバッファを読み取り、オブジェクトに変換
2. ヒープスナップショット作成
   └─ writeHeapSnapshot(filename) でV8にスナップショット生成を要求
3. シリアライズ
   └─ serialize(value) でオブジェクトをV8シリアライザでバッファに変換
4. デシリアライズ
   └─ deserialize(buffer) でバッファをオブジェクトに復元
```

### フローチャート

```mermaid
flowchart TD
    A[v8.getHeapStatistics/] --> B[updateHeapStatisticsBuffer/]
    B --> C[バッファからオブジェクト構築]
    C --> D[統計オブジェクト返却]

    E[v8.writeHeapSnapshot/filename] --> F[triggerHeapSnapshot/]
    F --> G[V8スナップショット生成]
    G --> H[ファイル書き込み]
    H --> I[ファイルパス返却]

    J[v8.serialize/value] --> K[DefaultSerializer作成]
    K --> L[writeHeader/]
    L --> M[writeValue/value]
    M --> N[releaseBuffer/]
    N --> O[Buffer返却]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-01 | シリアライズ互換性 | シリアライズしたデータは同一V8バージョンでのみデシリアライズ可能 | serialize/deserialize使用時 |
| BR-02 | ヒープスナップショット形式 | Chrome DevToolsと互換性のあるJSON形式 | writeHeapSnapshot使用時 |
| BR-03 | GCProfiler状態 | start()後でないとstop()はデータを返さない | GCProfiler使用時 |

### 計算ロジック

ヒープ統計はV8の内部バッファから直接読み取り、JavaScriptオブジェクトに変換する。

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

該当なし

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

該当なし

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| ERR_INVALID_ARG_TYPE | TypeError | 引数の型が不正 | 正しい型を渡す |
| DataCloneError | Error | シリアライズ不可能なオブジェクト | シリアライズ可能なオブジェクトを渡す |

### リトライ仕様

リトライは行わない。

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

該当なし

## パフォーマンス要件

- ヒープスナップショットの生成はメモリとCPUを大量に消費するため、本番環境での使用は注意が必要
- getHeapStatistics() は軽量で頻繁な呼び出しが可能

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

- ヒープスナップショットには機密情報が含まれる可能性があるため、取り扱いに注意
- setFlagsFromString() は信頼できる入力のみ使用すること

## 備考

- `cachedDataVersionTag()` でV8のキャッシュデータバージョンを取得可能
- `promiseHooks` でPromiseのライフサイクルを監視可能
- `startupSnapshot` でスタートアップスナップショットを管理可能

---

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

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

### 推奨読解順序

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

まず、v8 モジュールの全体構造とエクスポートを理解する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | v8.js | `lib/v8.js` | module.exports（497-521行目） |

**読解のコツ**: v8モジュールは多くの機能がinternalBindingで提供されており、JavaScript側は薄いラッパーとなっている。

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

モジュールのエクスポートと主要関数を把握する。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | v8.js | `lib/v8.js` | internalBinding('v8')（111行目） |
| 2-2 | v8.js | `lib/v8.js` | module.exports（497-521行目） |

**主要処理フロー**:
1. **39-49行目**: internalBinding からシリアライザを取得
2. **51-53行目**: startupSnapshot のインポート
3. **111-159行目**: V8バインディングから各種関数・定数をインポート
4. **497-521行目**: エクスポートされるAPI

#### Step 3: ヒープ統計関連を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | v8.js | `lib/v8.js` | getHeapStatistics（230-252行目） |
| 3-2 | v8.js | `lib/v8.js` | getHeapSpaceStatistics（264-280行目） |
| 3-3 | v8.js | `lib/v8.js` | getHeapCodeStatistics（291-301行目） |

**主要処理フロー**:
- **230-252行目**: getHeapStatistics - バッファから統計オブジェクトを構築
- **264-280行目**: getHeapSpaceStatistics - 各ヒープスペースの統計を配列で返却
- **291-301行目**: getHeapCodeStatistics - コード関連の統計を返却

#### Step 4: ヒープスナップショット関連を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | v8.js | `lib/v8.js` | writeHeapSnapshot（85-91行目） |
| 4-2 | v8.js | `lib/v8.js` | getHeapSnapshot（102-107行目） |

**主要処理フロー**:
- **85-91行目**: writeHeapSnapshot - ファイルにスナップショットを書き込み
- **102-107行目**: getHeapSnapshot - Readableストリームでスナップショットを取得

#### Step 5: シリアライゼーションを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 5-1 | v8.js | `lib/v8.js` | DefaultSerializer クラス（384-419行目） |
| 5-2 | v8.js | `lib/v8.js` | DefaultDeserializer クラス（421-447行目） |
| 5-3 | v8.js | `lib/v8.js` | serialize/deserialize（454-472行目） |

**主要処理フロー**:
- **384-419行目**: DefaultSerializer - ArrayBufferView のカスタムシリアライズ
- **421-447行目**: DefaultDeserializer - カスタムデシリアライズ
- **454-460行目**: serialize - DefaultSerializerを使用してシリアライズ
- **468-472行目**: deserialize - DefaultDeserializerを使用してデシリアライズ

#### Step 6: プロファイリング機能を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 6-1 | v8.js | `lib/v8.js` | GCProfiler クラス（474-495行目） |
| 6-2 | v8.js | `lib/v8.js` | startCpuProfile（198-201行目） |
| 6-3 | v8.js | `lib/v8.js` | SyncCPUProfileHandle（173-192行目） |

**主要処理フロー**:
- **474-495行目**: GCProfiler - GC情報のプロファイリング
- **173-192行目**: SyncCPUProfileHandle - CPUプロファイルのハンドル
- **198-201行目**: startCpuProfile - CPUプロファイリング開始

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

```
v8.getHeapStatistics()
    │
    └─ updateHeapStatisticsBuffer()
           └─ V8内部バッファ更新
                  └─ heapStatisticsBuffer[index] 読み取り
                         └─ オブジェクト構築

v8.writeHeapSnapshot(filename)
    │
    ├─ getValidatedPath(filename)
    ├─ getHeapSnapshotOptions(options)
    │
    └─ triggerHeapSnapshot(filename, optionArray)
           └─ V8::HeapProfiler::TakeHeapSnapshot()

v8.serialize(value)
    │
    └─ new DefaultSerializer()
           ├─ writeHeader()
           ├─ writeValue(value)
           │      └─ _writeHostObject() for ArrayBufferView
           └─ releaseBuffer()
                  └─ Buffer返却

v8.deserialize(buffer)
    │
    └─ new DefaultDeserializer(buffer)
           ├─ readHeader()
           └─ readValue()
                  └─ _readHostObject() for ArrayBufferView
```

### データフロー図

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

(なし) ────────────────▶ V8内部バッファ読み取り ───────▶ heapStatistics
                               │
filename ──────────────▶ triggerHeapSnapshot() ────────▶ snapshotファイル
                               │
value ─────────────────▶ Serializer ────────────────────▶ Buffer
                               │
Buffer ────────────────▶ Deserializer ──────────────────▶ value
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| v8.js | `lib/v8.js` | ソース | メインモジュール実装 |
| startup_snapshot.js | `lib/internal/v8/startup_snapshot.js` | ソース | 起動スナップショット管理 |
| heap_utils.js | `lib/internal/heap_utils.js` | ソース | ヒープユーティリティ |
| promise_hooks.js | `lib/internal/promise_hooks.js` | ソース | Promiseフック |
| validators.js | `lib/internal/validators.js` | ソース | 入力バリデーション |
| fs/utils.js | `lib/internal/fs/utils.js` | ソース | ファイルパス検証 |
