Add Phase 2 Headerless implementation instruction for Gemini
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 <gemini@example.com> Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
518
docs/PHASE2_HEADERLESS_INSTRUCTION_FOR_GEMINI.md
Normal file
518
docs/PHASE2_HEADERLESS_INSTRUCTION_FOR_GEMINI.md
Normal file
@ -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 の実力に期待しています。よろしくお願いします!🚀
|
||||
Reference in New Issue
Block a user