Content: - Task 1.1: Create tiny_layout_box.h (Box for layout definitions) - Task 1.2: Audit tiny_nextptr.h (eliminate direct arithmetic) - Task 1.3: Ensure type consistency in hakmem_tiny.c - Task 1.4: Test Phantom Types in Debug build Goals: - Centralize all layout/offset logic - Enforce type safety at Box boundaries - Prepare for future Phase 2 (Headerless layout) - Maintain A/B testability Each task includes: - Detailed implementation instructions - Checklist for verification - Testing requirements - Deliverables specification 🤖 Generated with Claude Code Co-Authored-By: Gemini <gemini@example.com> Co-Authored-By: Claude <noreply@anthropic.com>
8.5 KiB
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 (新規作成)
内容:
/**
* @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 に依存させる
確認対象:
// 現在のコード例:
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 を正しく使い分ける
確認対象:
// 変換すべきパターン:
void* p = ...; // ⚠️ 型不明確
void* user = (char*)base + 1; // ❌ 直接計算 → ptr_conversion_box 使用
void* base_p = (char*)user - 1; // ❌ 直接計算 → ptr_conversion_box 使用
修正方法:
// 修正後:
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 が実際に型エラーを検出するか確認
テスト内容:
// 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)
ビルドコマンド:
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
# 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
# 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
📝 実装時の注意
✅ すべき事
- Box パターン厳守: 各 Box は単一責任を持つ
- A/B テスト機能: 環境変数で旧動作に戻せるようにする
- 詳細ログ: デバッグフラグで詳細な実行ログを出力可能に
- 型安全性: Debug build では Phantom Types で型チェック
❌ してはいけない事
- 直接的なポインタ計算:
(char*)ptr + 1は Box API 経由に - 散らばったオフセット定義:
tiny_layout_box.hに集約 - グローバル変数の氾濫: 既存のグローバルを活用
- 無関係な最適化: 本タスクに集中
📞 進捗報告形式
各タスク完了時に以下の形式で報告してください:
## 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- ポインタ変換 Boxcore/tiny_nextptr.h- Next Pointer Box (既実装の参考)
よろしくお願いします!🙏
Gemini の努力に感謝。Phase 1 の成功が、hakmem をより堅牢で標準準拠なアロケータへ進化させます!