phase_9_79b_2 (PIC skeleton): Add monomorphic PIC hit counters\n- VM stores per-(receiver-type, method_id/name) hit counts\n- execute_boxcall records hits before dispatch\n- CURRENT_TASK updated

This commit is contained in:
Moe Charm
2025-08-26 20:59:37 +09:00
parent edbc38daad
commit 35049606f3
3 changed files with 53 additions and 1 deletions

View File

@ -12,7 +12,8 @@
- Builderが解決可能なBoxCallに`method_id`を付与(未解決は遅延)✅ 実装/Printer表示
2) 9.79b.2: VM VTable Thunks + Mono-PIC
- `execute_boxcall`をvtable+thunkの単一路線へユニバーサル0..3のfast-path追加✅ スケルトン
- call-site単位のモモーフィックPICを追加Key設計とカウンタ導入、最適化は後段)🟡 途中
- call-site単位のモモーフィックPICを追加Key設計とカウンタ導入・記録まで)✅ スケルトン
- 次: 安定閾値での直呼び最適化(後段)
### すぐ試せるコマンド
```bash

View File

@ -208,6 +208,8 @@ pub struct VM {
pub(super) instr_counter: std::collections::HashMap<&'static str, usize>,
/// Execution start time for optional stats
pub(super) exec_start: Option<Instant>,
/// Mono-PIC skeleton: global hit counters keyed by (recv_type, method_id/name)
pub(super) boxcall_pic_hits: std::collections::HashMap<String, u32>,
// Phase 9.78a: Add unified Box handling components
// TODO: Re-enable when interpreter refactoring is complete
// /// Box registry for creating all Box types
@ -268,6 +270,7 @@ impl VM {
module: None,
instr_counter: std::collections::HashMap::new(),
exec_start: None,
boxcall_pic_hits: std::collections::HashMap::new(),
// TODO: Re-enable when interpreter refactoring is complete
// box_registry: Arc::new(UnifiedBoxRegistry::new()),
// #[cfg(all(feature = "plugins", not(target_arch = "wasm32")))]
@ -293,6 +296,7 @@ impl VM {
module: None,
instr_counter: std::collections::HashMap::new(),
exec_start: None,
boxcall_pic_hits: std::collections::HashMap::new(),
}
}

View File

@ -15,6 +15,49 @@ use super::{VM, VMValue, VMError};
use super::vm::ControlFlow;
impl VM {
/// Build a PIC key from receiver and method identity
fn build_pic_key(&self, recv: &VMValue, method: &str, method_id: Option<u16>) -> String {
let rkey = match recv {
VMValue::Integer(_) => "Int",
VMValue::Float(_) => "Float",
VMValue::Bool(_) => "Bool",
VMValue::String(_) => "String",
VMValue::Future(_) => "Future",
VMValue::Void => "Void",
VMValue::BoxRef(b) => {
// Using dynamic type name as fingerprint (will migrate to numeric id later)
return if let Some(mid) = method_id {
format!("BoxRef:{}#{}", b.type_name(), mid)
} else {
format!("BoxRef:{}#{}", b.type_name(), method)
};
}
};
if let Some(mid) = method_id {
format!("{}#{}", rkey, mid)
} else {
format!("{}#{}", rkey, method)
}
}
/// Record a PIC hit for the given key (skeleton: increments a counter)
fn pic_record_hit(&mut self, key: &str) {
use std::collections::hash_map::Entry;
match self.boxcall_pic_hits.entry(key.to_string()) {
Entry::Occupied(mut e) => {
let v = e.get_mut();
*v = v.saturating_add(1);
if std::env::var("NYASH_VM_PIC_DEBUG").ok().as_deref() == Some("1") {
if *v == 8 || *v == 32 {
eprintln!("[PIC] Hot BoxCall site '{}' hits={} (skeleton)", key, v);
}
}
}
Entry::Vacant(v) => {
v.insert(1);
}
}
}
/// Execute a constant instruction
pub(super) fn execute_const(&mut self, dst: ValueId, value: &ConstValue) -> Result<ControlFlow, VMError> {
let vm_value = VMValue::from(value);
@ -508,6 +551,10 @@ impl VM {
// Debug logging if enabled
let debug_boxcall = std::env::var("NYASH_VM_DEBUG_BOXCALL").is_ok();
// Record PIC hit (per-receiver-type × method)
let pic_key = self.build_pic_key(&recv, method, method_id);
self.pic_record_hit(&pic_key);
// Fast path: universal method slots via method_id (0..3)
if let Some(mid) = method_id {
if let Some(fast_res) = self.try_fast_universal(mid, &recv, args)? {