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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy