Files
hakmem/docs/REFACTORING_INSTRUCTION_FOR_GEMINI.md

295 lines
8.5 KiB
Markdown
Raw Normal View History

# 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 をより堅牢で標準準拠なアロケータへ進化させます!