295 lines
8.5 KiB
Markdown
295 lines
8.5 KiB
Markdown
|
|
# Geminiへのリファクタリング実装指示書
|
|||
|
|
|
|||
|
|
Version: 1.0 (2025-12-03)
|
|||
|
|
Status: 実装開始準備完了
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📋 背景
|
|||
|
|
|
|||
|
|
TLS_SLL_HDR_RESET の根本原因調査が完了しました。
|
|||
|
|
|
|||
|
|
**結論**:
|
|||
|
|
- **Issue A** (ヘッダー復元漏れ): ✅ **修正済み** (4つのコミット)
|
|||
|
|
- **Issue B** (アラインメント違反): ⚠️ **現在防御中**、Phase 2で根治予定
|
|||
|
|
|
|||
|
|
Gemini の最終報告書 (`docs/tls_sll_hdr_reset_final_report.md`) で、**sh8bench がmalloc返却値に +1 を加えて使用している**ことが数学的に証明されました。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎯 Phase 1 実装目標
|
|||
|
|
|
|||
|
|
**目的**: Box パターンに基づいた Tiny Allocator のロジック集約
|
|||
|
|
|
|||
|
|
**期間**: 段階的(A/B テスト可能な形で)
|
|||
|
|
|
|||
|
|
**リスク**: 低(既存の防御機構は継続)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 実装タスク(優先度順)
|
|||
|
|
|
|||
|
|
### Task 1.1: `tiny_layout_box.h` 作成 ⭐⭐⭐ (CRITICAL)
|
|||
|
|
|
|||
|
|
**目的**: クラスサイズ・ヘッダーオフセットの定義を一箇所に集約
|
|||
|
|
|
|||
|
|
**場所**: `core/box/tiny_layout_box.h` (新規作成)
|
|||
|
|
|
|||
|
|
**内容**:
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
/**
|
|||
|
|
* @file tiny_layout_box.h
|
|||
|
|
* @brief Box: Tiny Allocator Layout Definitions
|
|||
|
|
*
|
|||
|
|
* MISSION: Single source of truth for class size and header layout
|
|||
|
|
*
|
|||
|
|
* Current Design (Phase E1-CORRECT):
|
|||
|
|
* - All classes (0-7) have 1-byte header
|
|||
|
|
* - User pointer = base + 1 for classes 0-6, base + 0 for class 7
|
|||
|
|
* (Note: Class 7 is headerless in practice but marked for consistency)
|
|||
|
|
* - No external code should hardcode offsets
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
#ifndef TINY_LAYOUT_BOX_H
|
|||
|
|
#define TINY_LAYOUT_BOX_H
|
|||
|
|
|
|||
|
|
#include <stddef.h>
|
|||
|
|
|
|||
|
|
// Define all class-specific layout parameters
|
|||
|
|
// Current: Defined in g_tiny_class_sizes[8] in hakmem_tiny.c
|
|||
|
|
// TODO: Move to this file and make accessible here
|
|||
|
|
|
|||
|
|
// Example macro (to be filled in):
|
|||
|
|
// #define TINY_CLASS_SIZE(cls) g_tiny_class_sizes[cls]
|
|||
|
|
// #define TINY_HEADER_SIZE 1
|
|||
|
|
// #define TINY_USER_OFFSET(cls) ((cls) == 7 ? 0 : 1)
|
|||
|
|
|
|||
|
|
// Validation macros
|
|||
|
|
static inline int tiny_class_is_valid(int class_idx) {
|
|||
|
|
return class_idx >= 0 && class_idx < 8;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static inline size_t tiny_class_stride(int class_idx) {
|
|||
|
|
extern const size_t g_tiny_class_sizes[8];
|
|||
|
|
return tiny_class_is_valid(class_idx) ? g_tiny_class_sizes[class_idx] : 0;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endif // TINY_LAYOUT_BOX_H
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**提出物**:
|
|||
|
|
- [ ] `core/box/tiny_layout_box.h` 完成
|
|||
|
|
- [ ] `tiny_nextptr.h` がこれを `#include` するように修正
|
|||
|
|
- [ ] テスト: `tiny_class_stride()` が正しい値を返すか確認
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Task 1.2: `tiny_nextptr.h` 監査 ⭐⭐⭐ (CRITICAL)
|
|||
|
|
|
|||
|
|
**目的**: 直接的な `+1` 計算を排除し、レイアウト Box に依存させる
|
|||
|
|
|
|||
|
|
**確認対象**:
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
// 現在のコード例:
|
|||
|
|
size_t off = tiny_next_off(class_idx); // ✅ OK (Box化済み)
|
|||
|
|
*(uint8_t*)base = HEADER_MAGIC | (class_idx & HEADER_CLASS_MASK); // ⚠️ 要確認
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**チェックリスト**:
|
|||
|
|
- [ ] `tiny_next_off()`: Box 化済み (確認: `core/tiny_nextptr.h:51-62`)
|
|||
|
|
- [ ] `tiny_next_load()`: Box 化済み (確認: `core/tiny_nextptr.h:66-87`)
|
|||
|
|
- [ ] `tiny_next_store()`: Box 化済み (確認: `core/tiny_nextptr.h:95-123`)
|
|||
|
|
- [ ] ヘッダー関連マジック値: `tiny_header_box.h` に一元化されているか確認
|
|||
|
|
- [ ] 直接的な `(void*)((char*)base + 1)` 計算: 全箇所を `ptr_conversion_box.h` に置き換え
|
|||
|
|
|
|||
|
|
**提出物**:
|
|||
|
|
- [ ] 監査結果レポート(`docs/tiny_nextptr_audit.md`)
|
|||
|
|
- [ ] 修正が必要な箇所のリスト
|
|||
|
|
- [ ] 修正済みファイル群
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Task 1.3: `hakmem_tiny.c` のポインタ型一貫性 ⭐⭐ (HIGH)
|
|||
|
|
|
|||
|
|
**目的**: `hakmem_tiny.c` で `hak_base_ptr_t` / `hak_user_ptr_t` を正しく使い分ける
|
|||
|
|
|
|||
|
|
**確認対象**:
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
// 変換すべきパターン:
|
|||
|
|
void* p = ...; // ⚠️ 型不明確
|
|||
|
|
void* user = (char*)base + 1; // ❌ 直接計算 → ptr_conversion_box 使用
|
|||
|
|
void* base_p = (char*)user - 1; // ❌ 直接計算 → ptr_conversion_box 使用
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**修正方法**:
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
// 修正後:
|
|||
|
|
hak_user_ptr_t user = ptr_base_to_user(base, class_idx); // ptr_conversion_box.h
|
|||
|
|
hak_base_ptr_t base = ptr_user_to_base(user, class_idx); // ptr_conversion_box.h
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**チェックリスト**:
|
|||
|
|
- [ ] `hakmem_tiny.c` で `hak_base_ptr_t` が使用されている箇所: リスト化
|
|||
|
|
- [ ] `hakmem_tiny.c` で `hak_user_ptr_t` が使用されている箇所: リスト化
|
|||
|
|
- [ ] 型不一致の警告が出ないことを確認(コンパイルテスト)
|
|||
|
|
|
|||
|
|
**提出物**:
|
|||
|
|
- [ ] 修正箇所のリスト
|
|||
|
|
- [ ] 修正済み `hakmem_tiny.c`
|
|||
|
|
- [ ] コンパイル結果(警告なし)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### Task 1.4: Box 間の型安全性テスト ⭐⭐ (MEDIUM)
|
|||
|
|
|
|||
|
|
**目的**: `ptr_type_box.h` の Phantom Types が実際に型エラーを検出するか確認
|
|||
|
|
|
|||
|
|
**テスト内容**:
|
|||
|
|
|
|||
|
|
```c
|
|||
|
|
// Debug build で以下がコンパイルエラーになることを確認:
|
|||
|
|
hak_base_ptr_t base = HAK_BASE_FROM_RAW(ptr);
|
|||
|
|
hak_user_ptr_t user = base; // ❌ Type mismatch (Debug build)
|
|||
|
|
int cmp = hak_base_eq(base, user); // ❌ Type mismatch (Debug build)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**ビルドコマンド**:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd /mnt/workdisk/public_share/hakmem
|
|||
|
|
|
|||
|
|
# Debug build (Phantom Types enabled)
|
|||
|
|
make clean
|
|||
|
|
make shared -j8 EXTRA_CFLAGS="-g -DHAKMEM_DEBUG_VERBOSE=1"
|
|||
|
|
|
|||
|
|
# 型エラーが出ることを確認
|
|||
|
|
# 出なければ: HAKMEM_TINY_PTR_PHANTOM のデフォルト値を見直す
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**提出物**:
|
|||
|
|
- [ ] テスト結果レポート
|
|||
|
|
- [ ] コンパイル log (エラーメッセージ含む)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📊 Phase 2 準備 (参考)
|
|||
|
|
|
|||
|
|
**当面は実装不要** ですが、Phase 1 完了後に以下を検討してください:
|
|||
|
|
|
|||
|
|
### Phase 2.1: Headerless Layout Design
|
|||
|
|
|
|||
|
|
現在の `user = base + 1` 設計を `user = base + 0` に変更する場合:
|
|||
|
|
|
|||
|
|
- **メタデータ回復**: `free()` で class_idx をどうやって判定するか
|
|||
|
|
- 案A: SuperSlab Registry (現在実装済み)
|
|||
|
|
- 案B: Bitmap (パフォーマンス影響検討必要)
|
|||
|
|
- 案C: Out-of-line header (外部テーブル)
|
|||
|
|
|
|||
|
|
- **パフォーマンス影響**:
|
|||
|
|
- ヘッダー読み込みコスト削減: 利得
|
|||
|
|
- SuperSlab lookup 増加: 負荷増加
|
|||
|
|
- 総合的にどちらが利得か: ベンチマーク必要
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🧪 テスト計画
|
|||
|
|
|
|||
|
|
### Unit Tests
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Phase 1.1: tiny_layout_box
|
|||
|
|
make test -j8 FILTER="tiny_layout"
|
|||
|
|
|
|||
|
|
# Phase 1.2: tiny_nextptr
|
|||
|
|
make test -j8 FILTER="tiny_nextptr"
|
|||
|
|
|
|||
|
|
# Phase 1.3: hakmem_tiny
|
|||
|
|
make test -j8 FILTER="hakmem_tiny"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Integration Tests
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# sh8bench (既存の動作確認)
|
|||
|
|
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/sh8bench 2>&1 | \
|
|||
|
|
grep -E "TLS_SLL_HDR_RESET|Total"
|
|||
|
|
|
|||
|
|
# cfrac, larson (非推奨な挙動が出ないか)
|
|||
|
|
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/cfrac 2>&1 | grep -i error
|
|||
|
|
LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/larson 8 2>&1 | grep -i error
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📝 実装時の注意
|
|||
|
|
|
|||
|
|
### ✅ すべき事
|
|||
|
|
|
|||
|
|
1. **Box パターン厳守**: 各 Box は単一責任を持つ
|
|||
|
|
2. **A/B テスト機能**: 環境変数で旧動作に戻せるようにする
|
|||
|
|
3. **詳細ログ**: デバッグフラグで詳細な実行ログを出力可能に
|
|||
|
|
4. **型安全性**: Debug build では Phantom Types で型チェック
|
|||
|
|
|
|||
|
|
### ❌ してはいけない事
|
|||
|
|
|
|||
|
|
1. **直接的なポインタ計算**: `(char*)ptr + 1` は Box API 経由に
|
|||
|
|
2. **散らばったオフセット定義**: `tiny_layout_box.h` に集約
|
|||
|
|
3. **グローバル変数の氾濫**: 既存のグローバルを活用
|
|||
|
|
4. **無関係な最適化**: 本タスクに集中
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 📞 進捗報告形式
|
|||
|
|
|
|||
|
|
各タスク完了時に以下の形式で報告してください:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
## Task [番号] 完了レポート
|
|||
|
|
|
|||
|
|
**実装内容**:
|
|||
|
|
- 作成/修正ファイル: ...
|
|||
|
|
- 主な変更: ...
|
|||
|
|
|
|||
|
|
**テスト結果**:
|
|||
|
|
- ビルド: ✅ 成功 / ❌ 失敗
|
|||
|
|
- 既存テスト: ✅ 全て通過 / ❌ XX件失敗
|
|||
|
|
|
|||
|
|
**備考**:
|
|||
|
|
- 予期しない課題があれば記述
|
|||
|
|
- Phase 2 への提案があれば記述
|
|||
|
|
|
|||
|
|
**次のステップ**:
|
|||
|
|
- Task [次の番号] へ進む
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 🎁 完了後の評価基準
|
|||
|
|
|
|||
|
|
| 基準 | 期待値 |
|
|||
|
|
|------|--------|
|
|||
|
|
| **コード品質** | Box 理論に完全準拠、型安全性確保 |
|
|||
|
|
| **テスト** | sh8bench/cfrac/larson で回帰なし |
|
|||
|
|
| **ドキュメント** | Phase 1 実装の詳細説明あり |
|
|||
|
|
| **パフォーマンス** | ≤ 5% の低下に抑制 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 参考資料
|
|||
|
|
|
|||
|
|
- `docs/REFACTOR_PLAN_GEMINI_ENHANCED.md` - マスタープラン
|
|||
|
|
- `docs/tls_sll_hdr_reset_final_report.md` - 根本原因分析
|
|||
|
|
- `core/box/ptr_type_box.h` - Phantom Types 実装例
|
|||
|
|
- `core/box/ptr_conversion_box.h` - ポインタ変換 Box
|
|||
|
|
- `core/tiny_nextptr.h` - Next Pointer Box (既実装の参考)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
よろしくお願いします!🙏
|
|||
|
|
|
|||
|
|
Gemini の努力に感謝。Phase 1 の成功が、hakmem をより堅牢で標準準拠なアロケータへ進化させます!
|