From 2f09f3cba8953b821743f394b6c632599b0aa61a Mon Sep 17 00:00:00 2001 From: "Moe Charm (CI)" Date: Wed, 3 Dec 2025 11:41:34 +0900 Subject: [PATCH] Add Phase 2 Headerless implementation instruction for Gemini MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Phase 2 Goal: Eliminate inline headers for C standard alignment compliance Tasks (7 total): - Task 2.1: Add A/B toggle flag (HAKMEM_TINY_HEADERLESS) - Task 2.2: Update ptr_conversion_box.h for Headerless mode - Task 2.3: Modify HAK_RET_ALLOC macro (skip header write) - Task 2.4: Update Free path (class_idx from SuperSlab Registry) - Task 2.5: Update tiny_nextptr.h for Headerless - Task 2.6: Update TLS SLL (skip header validation) - Task 2.7: Integration testing Expected Results: - malloc(15) returns 16B-aligned address (not odd) - TLS_SLL_HDR_RESET eliminated in sh8bench - Zero overhead in Release build - A/B toggle for gradual rollout Design: - Before: user = base + 1 (odd address) - After: user = base + 0 (aligned!) - Free path: class_idx from SuperSlab Registry (no header) 🤖 Generated with Claude Code Co-Authored-By: Gemini Co-Authored-By: Claude --- ...HASE2_HEADERLESS_INSTRUCTION_FOR_GEMINI.md | 518 ++++++++++++++++++ 1 file changed, 518 insertions(+) create mode 100644 docs/PHASE2_HEADERLESS_INSTRUCTION_FOR_GEMINI.md diff --git a/docs/PHASE2_HEADERLESS_INSTRUCTION_FOR_GEMINI.md b/docs/PHASE2_HEADERLESS_INSTRUCTION_FOR_GEMINI.md new file mode 100644 index 00000000..f9d99781 --- /dev/null +++ b/docs/PHASE2_HEADERLESS_INSTRUCTION_FOR_GEMINI.md @@ -0,0 +1,518 @@ +# Phase 2: Headerless化 実装指示書 + +Version: 1.0 (2025-12-03) +Status: Phase 1 完了、Phase 2 開始準備完了 + +--- + +## 🎯 目標 + +**Headerless Tiny Allocator** を実装し、C標準のアラインメント保証を達成する。 + +### ゴール + +```c +// 現在(Phase 1) +malloc(15) → 0x...0001 (奇数アドレス = base + 1) + +// Phase 2 完了後 +malloc(15) → 0x...0000 (16B aligned = base + 0) +``` + +### 成功基準 + +1. ✅ Release ビルドで `user_ptr = base` (ゼロオーバーヘッド) +2. ✅ 全クラス (0-7) で 16B アラインメント保証 +3. ✅ sh8bench で TLS_SLL_HDR_RESET が発生しない +4. ✅ cfrac, larson で回帰なし +5. ✅ パフォーマンス低下 ≤ 5% + +--- + +## 📋 設計概要 + +### Before (Phase 1: Inline Header) + +``` +Block Layout (Class 1, 16B stride): +┌─────────┬────────────────────────────┐ +│Header 1B│ User Payload 15B │ +└─────────┴────────────────────────────┘ +↑ base ↑ user = base + 1 (奇数!) +``` + +### After (Phase 2: Headerless) + +``` +Block Layout (Class 1, 16B stride): +┌──────────────────────────────────────┐ +│ User Payload 16B │ +└──────────────────────────────────────┘ +↑ base = user (16B aligned!) + +Free時のみ: +┌──────────────────────────────────────┐ +│ Next Ptr (8B) │ Unused (8B) │ +└──────────────────────────────────────┘ +↑ base (freelist linkage) +``` + +### class_idx の取得方法 + +**Allocated 時**: Headerなし → class_idx は SuperSlab Registry から取得 + +```c +// Free時の処理 +void hak_free(void* user_ptr) { + // Step 1: user = base (Headerless) + void* base = user_ptr; + + // Step 2: SuperSlab Registry から class_idx を取得 + SuperSlab* ss = hak_super_lookup((uintptr_t)base); + int class_idx = ss->class_idx; // ← ここが重要 + + // Step 3: 通常のfree処理 + // ... +} +``` + +--- + +## 📝 実装タスク(優先度順) + +### Task 2.1: A/B切替フラグ追加 ⭐⭐⭐ (CRITICAL) + +**目的**: Headerless 化を段階的に導入可能にする + +**場所**: `core/box/tiny_layout_box.h` + +**実装内容**: + +```c +// core/box/tiny_layout_box.h に追加 + +// A/B Toggle: Headerless mode +// ENV: HAKMEM_TINY_HEADERLESS=1 で有効化 +// Default: 0 (Phase 1互換) +#ifndef HAKMEM_TINY_HEADERLESS + #define HAKMEM_TINY_HEADERLESS 0 +#endif + +// User offset: Headerless時は0, Header時は1 +static inline size_t tiny_user_offset(int class_idx) { +#if HAKMEM_TINY_HEADERLESS + (void)class_idx; + return 0; // Headerless: user = base +#else + // Phase 1互換: Class 0-6 = 1, Class 7 = 0 + return (0x7Eu >> class_idx) & 1u; +#endif +} + +// Header size: Headerless時は0 +static inline size_t tiny_header_size(int class_idx) { +#if HAKMEM_TINY_HEADERLESS + (void)class_idx; + return 0; +#else + return (0x7Eu >> class_idx) & 1u; +#endif +} +``` + +**提出物**: +- [ ] `tiny_layout_box.h` に A/B フラグ追加 +- [ ] ビルド確認: `make shared EXTRA_CFLAGS="-DHAKMEM_TINY_HEADERLESS=1"` +- [ ] ビルド確認: `make shared` (デフォルト = Phase 1互換) + +--- + +### Task 2.2: ptr_conversion_box.h Headerless対応 ⭐⭐⭐ (CRITICAL) + +**目的**: ポインタ変換を Headerless モードに対応 + +**場所**: `core/box/ptr_conversion_box.h` + +**実装内容**: + +```c +// core/box/ptr_conversion_box.h 修正 + +#include "tiny_layout_box.h" + +// BASE → USER 変換 +static inline void* ptr_base_to_user(void* base_ptr, uint8_t class_idx) { + if (base_ptr == NULL) return NULL; + +#if HAKMEM_TINY_HEADERLESS + // Headerless: user = base (identity) + (void)class_idx; + return base_ptr; +#else + // Phase 1: user = base + offset + size_t offset = tiny_user_offset(class_idx); + return (void*)((uint8_t*)base_ptr + offset); +#endif +} + +// USER → BASE 変換 +static inline void* ptr_user_to_base(void* user_ptr, uint8_t class_idx) { + if (user_ptr == NULL) return NULL; + +#if HAKMEM_TINY_HEADERLESS + // Headerless: base = user (identity) + (void)class_idx; + return user_ptr; +#else + // Phase 1: base = user - offset + size_t offset = tiny_user_offset(class_idx); + return (void*)((uint8_t*)user_ptr - offset); +#endif +} +``` + +**提出物**: +- [ ] `ptr_conversion_box.h` 修正完了 +- [ ] Headerless ビルドでテスト +- [ ] Phase 1 互換ビルドでテスト(回帰なし) + +--- + +### Task 2.3: HAK_RET_ALLOC マクロ修正 ⭐⭐⭐ (CRITICAL) + +**目的**: Allocation パスを Headerless 対応に + +**場所**: `core/hakmem_tiny_config_box.inc` + +**実装内容**: + +```c +// core/hakmem_tiny_config_box.inc 修正 + +#if HAKMEM_TINY_HEADERLESS + +// Headerless: ヘッダー書き込み不要、user = base +#define HAK_RET_ALLOC(base, cls) do { \ + /* No header write needed */ \ + return (base); \ +} while(0) + +#else + +// Phase 1: ヘッダー書き込み + user = base + offset +#define HAK_RET_ALLOC(base, cls) do { \ + tiny_header_write((base), (cls)); \ + return ptr_base_to_user((base), (cls)); \ +} while(0) + +#endif +``` + +**提出物**: +- [ ] `HAK_RET_ALLOC` マクロ修正完了 +- [ ] Headerless: ヘッダー書き込みがスキップされることを確認 +- [ ] Phase 1: 既存動作と同一であることを確認 + +--- + +### Task 2.4: Free パス修正 ⭐⭐⭐ (CRITICAL) + +**目的**: Free 時の class_idx 取得を SuperSlab Registry 経由に + +**場所**: `core/hakmem_tiny_free.inc` または関連ファイル + +**確認すべき既存コード**: + +```c +// 現在のコード(推定) +void hak_tiny_free(void* user_ptr) { + // Step 1: user → base 変換 + void* base = ptr_user_to_base(user_ptr, ???); // ← class_idx が必要! + + // 現在: ヘッダーから class_idx を読み取り + int class_idx = *(uint8_t*)base & 0x0F; + + // ... +} +``` + +**Headerless 対応**: + +```c +void hak_tiny_free(void* user_ptr) { +#if HAKMEM_TINY_HEADERLESS + // Headerless: user = base + void* base = user_ptr; + + // SuperSlab Registry から class_idx を取得 + SuperSlab* ss = hak_super_lookup((uintptr_t)base); + if (!ss) { + // エラー処理: Unknown pointer + return; + } + int class_idx = ss->class_idx; + +#else + // Phase 1: ヘッダーから取得 + void* base = ptr_user_to_base(user_ptr, 0); // 仮の class_idx + int class_idx = tiny_header_read_class(base); + base = ptr_user_to_base(user_ptr, class_idx); // 正しい base + +#endif + + // 共通処理 + // ... +} +``` + +**重要**: SuperSlab に `class_idx` フィールドがあるか確認してください。 +なければ追加が必要です。 + +**提出物**: +- [ ] Free パスの現状調査レポート +- [ ] class_idx 取得方法の決定 +- [ ] 修正済みコード +- [ ] テスト結果 + +--- + +### Task 2.5: tiny_nextptr.h Headerless対応 ⭐⭐ (HIGH) + +**目的**: Next pointer 操作を Headerless モードに対応 + +**場所**: `core/tiny_nextptr.h` + +**確認ポイント**: + +```c +// tiny_next_off() の Headerless 対応 +static inline size_t tiny_next_off(int class_idx) { +#if HAKMEM_TINY_HEADERLESS + // Headerless: 全クラスで offset = 0 + (void)class_idx; + return 0; +#else + // Phase 1: C0,C7 = 0, C1-C6 = 1 + return (0x7Eu >> class_idx) & 1u; +#endif +} +``` + +**提出物**: +- [ ] `tiny_nextptr.h` 修正完了 +- [ ] Freelist 操作のテスト + +--- + +### Task 2.6: TLS SLL Headerless対応 ⭐⭐ (HIGH) + +**目的**: TLS SLL push/pop を Headerless 対応に + +**場所**: `core/box/tls_sll_box.h` + +**修正ポイント**: + +1. **Push 時**: ヘッダー書き込みをスキップ (Headerless時) +2. **Pop 時**: ヘッダー検証をスキップ (Headerless時) +3. **TLS_SLL_HDR_RESET**: 発生しなくなる(ヘッダーがないため) + +```c +// tls_sll_push_impl 修正 +static inline bool tls_sll_push_impl(int class_idx, hak_base_ptr_t ptr, ...) { + // ... + +#if !HAKMEM_TINY_HEADERLESS + // Phase 1: ヘッダー書き込み + *(uint8_t*)b = (uint8_t)(0xa0 | (class_idx & 0x0f)); + __atomic_thread_fence(__ATOMIC_RELEASE); +#endif + + // ... +} + +// tls_sll_pop_impl 修正 +static inline bool tls_sll_pop_impl(int class_idx, hak_base_ptr_t* out, ...) { + // ... + +#if !HAKMEM_TINY_HEADERLESS + // Phase 1: ヘッダー検証 + uint8_t got = *(uint8_t*)raw_base; + uint8_t expect = (uint8_t)(0xa0 | (class_idx & 0x0f)); + if (got != expect) { + // TLS_SLL_HDR_RESET 処理 + } +#endif + + // ... +} +``` + +**提出物**: +- [ ] `tls_sll_box.h` 修正完了 +- [ ] TLS_SLL_HDR_RESET が発生しないことを確認 (Headerless時) + +--- + +### Task 2.7: 統合テスト ⭐⭐⭐ (CRITICAL) + +**目的**: Headerless モードの動作検証 + +**テスト手順**: + +```bash +cd /mnt/workdisk/public_share/hakmem + +# 1. Headerless ビルド +find . -name "*.o" -delete && find . -name "*.so" -delete +make shared -j8 EXTRA_CFLAGS="-DHAKMEM_TINY_HEADERLESS=1" + +# 2. sh8bench テスト(TLS_SLL_HDR_RESETが出ないことを確認) +LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/sh8bench 2>&1 | \ + grep -E "TLS_SLL_HDR_RESET|Total|error" + +# 期待結果: +# Total elapsed time for 8 threads: X.XX (XX.XX CPU) +# [TLS_SLL_HDR_RESET] → 出力されない! + +# 3. cfrac テスト +LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/cfrac 2>&1 | \ + grep -E "error|Error|SEGV" + +# 4. larson テスト +LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/larson 8 2>&1 | \ + grep -E "error|Error|SEGV" + +# 5. Phase 1 互換ビルド(回帰テスト) +find . -name "*.o" -delete && find . -name "*.so" -delete +make shared -j8 # デフォルト = Headerless OFF + +LD_PRELOAD=./libhakmem.so ./mimalloc-bench/out/bench/sh8bench 2>&1 | \ + grep -E "TLS_SLL_HDR_RESET|Total" +# → TLS_SLL_HDR_RESET は出る(既存動作) +``` + +**提出物**: +- [ ] Headerless ビルドのテスト結果 +- [ ] Phase 1 互換ビルドの回帰テスト結果 +- [ ] パフォーマンス比較(可能であれば) + +--- + +## 🔄 段階的移行計画 + +### Step 1: A/B フラグ導入 (Task 2.1) +``` +HAKMEM_TINY_HEADERLESS=0 → Phase 1 互換(デフォルト) +HAKMEM_TINY_HEADERLESS=1 → Headerless モード +``` + +### Step 2: Core 修正 (Task 2.2-2.6) +``` +各コンポーネントを #if HAKMEM_TINY_HEADERLESS で分岐 +``` + +### Step 3: 統合テスト (Task 2.7) +``` +両モードでテスト、回帰なし確認 +``` + +### Step 4: デフォルト切替(将来) +``` +Headerless モードをデフォルトに変更 +Phase 1 コードを削除(または Legacy として維持) +``` + +--- + +## ⚠️ 注意点 + +### SuperSlab Registry への依存 + +Headerless モードでは、`free()` 時に class_idx を SuperSlab から取得します。 +これは現在のアーキテクチャで既にサポートされているはずですが、確認が必要です。 + +```c +// 確認コマンド +grep -n "class_idx\|size_class" core/superslab/*.h core/hakmem_super_registry.c +``` + +もし SuperSlab に class_idx がない場合: +1. `SuperSlab` 構造体に `uint8_t class_idx` フィールドを追加 +2. Slab 作成時に class_idx を設定 + +### パフォーマンス考慮 + +Headerless モードでは: +- ✅ Allocation: ヘッダー書き込み削減 → 高速化 +- ⚠️ Free: SuperSlab lookup 必要 → 若干のコスト + +全体としてはトレードオフですが、lookup は既に実装されているため影響は最小限のはずです。 + +--- + +## 📊 成功指標 + +| 指標 | 目標値 | 測定方法 | +|------|--------|----------| +| TLS_SLL_HDR_RESET | 0件 | sh8bench実行時 | +| アラインメント | 16B | `malloc(15)` の戻り値 % 16 == 0 | +| パフォーマンス | ≤ 5% 低下 | sh8bench 実行時間 | +| 回帰テスト | 全Pass | cfrac, larson | +| ビルド | 成功 | 両モードでエラーなし | + +--- + +## 📞 進捗報告形式 + +各タスク完了時: + +```markdown +## Task [番号] 完了レポート + +**実装内容**: +- 修正ファイル: ... +- 主な変更: ... + +**テスト結果**: +- Headerless ビルド: ✅/❌ +- Phase 1 互換ビルド: ✅/❌ +- TLS_SLL_HDR_RESET: 発生なし/発生あり + +**備考**: +- 予期しない課題: ... +- 追加の検討事項: ... +``` + +--- + +## 🎁 最終ゴール + +Phase 2 完了後の理想形: + +```c +// Release ビルド(Headerless) +void* ptr = malloc(15); +// ptr = 0x7f...0000 (16B aligned!) +// オーバーヘッド: 0 + +free(ptr); +// SuperSlab lookup → class_idx 取得 → freelist へ + +// sh8bench: TLS_SLL_HDR_RESET なし! +// パフォーマンス: Phase 1 と同等以上 +``` + +--- + +## 参考資料 + +- `docs/REFACTOR_PLAN_GEMINI_ENHANCED.md` - 全体計画 +- `docs/REFACTORING_INSTRUCTION_FOR_GEMINI.md` - Phase 1 指示書 +- `docs/tls_sll_hdr_reset_final_report.md` - 根本原因分析 +- `core/box/tiny_layout_box.h` - Phase 1 で作成したレイアウト Box +- `core/box/ptr_conversion_box.h` - Phase 1 で修正したポインタ変換 Box + +--- + +Phase 2 の成功で、hakmem は C 標準準拠の高性能アロケータに進化します! +Gemini の実力に期待しています。よろしくお願いします!🚀