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-
64use 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
7876fn 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 ) ]
9589pub 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
10094impl 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