1
1
// We use the YARV bytecode constants which have a CRuby-style name
2
2
#![ allow( non_upper_case_globals) ]
3
3
4
- use std:: collections:: HashMap ;
5
-
6
4
use crate :: { cruby:: * , gc:: get_or_create_iseq_payload, hir_type:: { types:: { Empty , Fixnum } , Type } } ;
7
5
8
6
/// Ephemeral state for profiling runtime information
@@ -77,30 +75,30 @@ fn profile_insn(profiler: &mut Profiler, opcode: ruby_vminsn_type) {
77
75
/// Profile the Type of top-`n` stack operands
78
76
fn profile_operands ( profiler : & mut Profiler , n : usize ) {
79
77
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
+ }
86
82
for i in 0 ..n {
87
83
let opnd_type = Type :: from_value ( profiler. peek_at_stack ( ( n - i - 1 ) as isize ) ) ;
88
84
types[ i] = types[ i] . union ( opnd_type) ;
89
85
}
90
-
91
- profile. opnd_types . insert ( profiler. insn_idx , types) ;
92
86
}
93
87
94
- #[ derive( Default , Debug ) ]
88
+ #[ derive( Debug ) ]
95
89
pub struct IseqProfile {
96
90
/// Type information of YARV instruction operands, indexed by the instruction index
97
- opnd_types : HashMap < usize , Vec < Type > > ,
91
+ opnd_types : Vec < Vec < Type > > ,
98
92
}
99
93
100
94
impl IseqProfile {
95
+ pub fn new ( iseq_size : u32 ) -> Self {
96
+ Self { opnd_types : vec ! [ vec![ ] ; iseq_size as usize ] }
97
+ }
98
+
101
99
/// Get profiled operand types for a given instruction index
102
100
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 )
104
102
}
105
103
106
104
/// Return true if top-two stack operands are Fixnums
@@ -113,7 +111,7 @@ impl IseqProfile {
113
111
114
112
/// Run a given callback with every object in IseqProfile
115
113
pub fn each_object ( & self , callback : impl Fn ( VALUE ) ) {
116
- for types in self . opnd_types . values ( ) {
114
+ for types in & self . opnd_types {
117
115
for opnd_type in types {
118
116
if let Some ( object) = opnd_type. ruby_object ( ) {
119
117
callback ( object) ;
0 commit comments