@@ -54,6 +54,7 @@ use crate::runtime::vm::{
5454} ;
5555use crate :: vm:: VMMemoryDefinition ;
5656use crate :: { Engine , EngineWeak , prelude:: * } ;
57+ use core:: hash:: BuildHasher ;
5758use core:: sync:: atomic:: AtomicUsize ;
5859use core:: {
5960 alloc:: Layout ,
@@ -111,12 +112,66 @@ enum TraceInfo {
111112 } ,
112113}
113114
115+ /// A hasher that doesn't hash, for use in the trace-info hash map, where we are
116+ /// just using scalar keys and aren't overly concerned with collision-based DoS.
117+ #[ derive( Default ) ]
118+ struct NopHasher ( u64 ) ;
119+
120+ impl BuildHasher for NopHasher {
121+ type Hasher = Self ;
122+
123+ #[ inline]
124+ fn build_hasher ( & self ) -> Self :: Hasher {
125+ NopHasher :: default ( )
126+ }
127+ }
128+
129+ impl core:: hash:: Hasher for NopHasher {
130+ #[ inline]
131+ fn finish ( & self ) -> u64 {
132+ self . 0
133+ }
134+
135+ #[ inline]
136+ fn write ( & mut self , bytes : & [ u8 ] ) {
137+ let mut hash = self . 0 . to_ne_bytes ( ) ;
138+ let n = hash. len ( ) . min ( bytes. len ( ) ) ;
139+ hash[ ..n] . copy_from_slice ( bytes) ;
140+ self . 0 = u64:: from_ne_bytes ( hash) ;
141+ }
142+
143+ #[ inline]
144+ fn write_u8 ( & mut self , i : u8 ) {
145+ self . write_u64 ( i. into ( ) ) ;
146+ }
147+
148+ #[ inline]
149+ fn write_u16 ( & mut self , i : u16 ) {
150+ self . write_u64 ( i. into ( ) )
151+ }
152+
153+ #[ inline]
154+ fn write_u32 ( & mut self , i : u32 ) {
155+ self . write_u64 ( i. into ( ) )
156+ }
157+
158+ #[ inline]
159+ fn write_u64 ( & mut self , i : u64 ) {
160+ self . 0 = i;
161+ }
162+
163+ #[ inline]
164+ fn write_usize ( & mut self , i : usize ) {
165+ self . write_u64 ( i. try_into ( ) . unwrap ( ) ) ;
166+ }
167+ }
168+
114169/// A deferred reference-counting (DRC) heap.
115170struct DrcHeap {
116171 engine : EngineWeak ,
117172
118173 /// For every type that we have allocated in this heap, how do we trace it?
119- trace_infos : HashMap < VMSharedTypeIndex , TraceInfo > ,
174+ trace_infos : HashMap < VMSharedTypeIndex , TraceInfo , NopHasher > ,
120175
121176 /// Count of how many no-gc scopes we are currently within.
122177 no_gc_count : u64 ,
@@ -158,9 +213,11 @@ impl DrcHeap {
158213 /// Construct a new, default DRC heap.
159214 fn new ( engine : & Engine ) -> Result < Self > {
160215 log:: trace!( "allocating new DRC heap" ) ;
216+ let mut trace_infos = HashMap :: default ( ) ;
217+ trace_infos. reserve ( 1 ) ;
161218 Ok ( Self {
162219 engine : engine. weak ( ) ,
163- trace_infos : HashMap :: with_capacity ( 1 ) ,
220+ trace_infos,
164221 no_gc_count : 0 ,
165222 over_approximated_stack_roots : Box :: new ( None ) ,
166223 memory : None ,
0 commit comments