Skip to content

Commit 42ffd3c

Browse files
committed
ZJIT: Use Vec, not HashMap, for storing ISEQ profiles
1 parent 51252ef commit 42ffd3c

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

zjit/src/gc.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::ffi::c_void;
44
use crate::{cruby::*, profile::IseqProfile, virtualmem::CodePtr};
55

66
/// This is all the data ZJIT stores on an ISEQ. We mark objects in this struct on GC.
7-
#[derive(Default, Debug)]
7+
#[derive(Debug)]
88
pub struct IseqPayload {
99
/// Type information of YARV instruction operands
1010
pub profile: IseqProfile,
@@ -15,6 +15,12 @@ pub struct IseqPayload {
1515
// TODO: Add references to GC offsets in JIT code
1616
}
1717

18+
impl IseqPayload {
19+
fn new(iseq_size: u32) -> Self {
20+
Self { profile: IseqProfile::new(iseq_size), start_ptr: None }
21+
}
22+
}
23+
1824
/// Get the payload object associated with an iseq. Create one if none exists.
1925
pub fn get_or_create_iseq_payload(iseq: IseqPtr) -> &'static mut IseqPayload {
2026
type VoidPtr = *mut c_void;
@@ -26,7 +32,8 @@ pub fn get_or_create_iseq_payload(iseq: IseqPtr) -> &'static mut IseqPayload {
2632
// We drop the payload with Box::from_raw when the GC frees the iseq and calls us.
2733
// NOTE(alan): Sometimes we read from an iseq without ever writing to it.
2834
// We allocate in those cases anyways.
29-
let new_payload = IseqPayload::default();
35+
let iseq_size = get_iseq_encoded_size(iseq);
36+
let new_payload = IseqPayload::new(iseq_size);
3037
let new_payload = Box::into_raw(Box::new(new_payload));
3138
rb_iseq_set_zjit_payload(iseq, new_payload as VoidPtr);
3239

zjit/src/profile.rs

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// We use the YARV bytecode constants which have a CRuby-style name
22
#![allow(non_upper_case_globals)]
33

4-
use std::collections::HashMap;
5-
64
use crate::{cruby::*, gc::get_or_create_iseq_payload, hir_type::{types::{Empty, Fixnum}, Type}};
75

86
/// Ephemeral state for profiling runtime information
@@ -77,30 +75,30 @@ fn profile_insn(profiler: &mut Profiler, opcode: ruby_vminsn_type) {
7775
/// Profile the Type of top-`n` stack operands
7876
fn profile_operands(profiler: &mut Profiler, n: usize) {
7977
let profile = &mut get_or_create_iseq_payload(profiler.iseq).profile;
80-
let mut types = if let Some(types) = profile.opnd_types.get(&profiler.insn_idx) {
81-
types.clone()
82-
} else {
83-
vec![Empty; n]
84-
};
85-
78+
let types = &mut profile.opnd_types[profiler.insn_idx];
79+
if types.len() <= n {
80+
types.resize(n, Empty);
81+
}
8682
for i in 0..n {
8783
let opnd_type = Type::from_value(profiler.peek_at_stack((n - i - 1) as isize));
8884
types[i] = types[i].union(opnd_type);
8985
}
90-
91-
profile.opnd_types.insert(profiler.insn_idx, types);
9286
}
9387

94-
#[derive(Default, Debug)]
88+
#[derive(Debug)]
9589
pub struct IseqProfile {
9690
/// Type information of YARV instruction operands, indexed by the instruction index
97-
opnd_types: HashMap<usize, Vec<Type>>,
91+
opnd_types: Vec<Vec<Type>>,
9892
}
9993

10094
impl IseqProfile {
95+
pub fn new(iseq_size: u32) -> Self {
96+
Self { opnd_types: vec![vec![]; iseq_size as usize] }
97+
}
98+
10199
/// Get profiled operand types for a given instruction index
102100
pub fn get_operand_types(&self, insn_idx: usize) -> Option<&[Type]> {
103-
self.opnd_types.get(&insn_idx).map(|types| types.as_slice())
101+
self.opnd_types.get(insn_idx).map(|v| &**v)
104102
}
105103

106104
/// Return true if top-two stack operands are Fixnums
@@ -113,7 +111,7 @@ impl IseqProfile {
113111

114112
/// Run a given callback with every object in IseqProfile
115113
pub fn each_object(&self, callback: impl Fn(VALUE)) {
116-
for types in self.opnd_types.values() {
114+
for types in &self.opnd_types {
117115
for opnd_type in types {
118116
if let Some(object) = opnd_type.ruby_object() {
119117
callback(object);

0 commit comments

Comments
 (0)