File tree Expand file tree Collapse file tree 1 file changed +16
-1
lines changed
Expand file tree Collapse file tree 1 file changed +16
-1
lines changed Original file line number Diff line number Diff line change @@ -265,7 +265,22 @@ impl Object {
265265 let index = self . store . len ( ) ;
266266
267267 if index < self . store . capacity ( ) {
268- self . store . push ( Node :: new ( value) ) ;
268+ // Because we've just checked the capacity, we can avoid
269+ // using `push`, and instead do unsafe magic to memcpy
270+ // the new node at the correct index without additional
271+ // capacity or bound checks.
272+ unsafe {
273+ let node = Node :: new ( value) ;
274+ self . store . set_len ( index + 1 ) ;
275+ ptr:: copy_nonoverlapping (
276+ & node as * const Node ,
277+ self . store . as_mut_ptr ( ) . offset ( index as isize ) ,
278+ 1 ,
279+ ) ;
280+ // Since the Node has been copied, we need to forget about
281+ // the owned value, else we may run into use after free.
282+ mem:: forget ( node) ;
283+ }
269284 self . node_at_index_mut ( index) . attach_key ( key, hash) ;
270285 } else {
271286 self . store . push ( Node :: new ( value) ) ;
You can’t perform that action at this time.
0 commit comments