1- use std:: borrow :: Borrow ;
1+ use std:: collections :: HashMap ;
22
33use super :: {
4- element_array:: { ElementArrayKey , ElementsVector } ,
4+ element_array:: { ElementArrayKey , ElementDescriptor , ElementsVector } ,
55 indexes:: { BaseIndex , ElementIndex , TypedArrayIndex } ,
66 Heap ,
77} ;
@@ -36,7 +36,10 @@ use crate::ecmascript::{
3636 GlobalEnvironmentIndex , ObjectEnvironmentIndex , RealmIdentifier ,
3737 } ,
3838 scripts_and_modules:: script:: ScriptIdentifier ,
39- types:: { bigint:: HeapBigInt , HeapNumber , HeapString , OrdinaryObject , Symbol , Value } ,
39+ types:: {
40+ bigint:: HeapBigInt , HeapNumber , HeapString , OrdinaryObject , Symbol , Value ,
41+ BUILTIN_STRINGS_LIST ,
42+ } ,
4043} ;
4144
4245#[ derive( Debug ) ]
@@ -273,8 +276,8 @@ impl WorkQueues {
273276 scripts : Vec :: with_capacity ( heap. scripts . len ( ) / 4 ) ,
274277 sets : Vec :: with_capacity ( heap. sets . len ( ) / 4 ) ,
275278 shared_array_buffers : Vec :: with_capacity ( heap. shared_array_buffers . len ( ) / 4 ) ,
276- strings : Vec :: with_capacity ( heap. strings . len ( ) / 4 ) ,
277- symbols : Vec :: with_capacity ( heap. symbols . len ( ) / 4 ) ,
279+ strings : Vec :: with_capacity ( ( heap. strings . len ( ) / 4 ) . max ( BUILTIN_STRINGS_LIST . len ( ) ) ) ,
280+ symbols : Vec :: with_capacity ( ( heap. symbols . len ( ) / 4 ) . max ( 13 ) ) ,
278281 typed_arrays : Vec :: with_capacity ( heap. typed_arrays . len ( ) / 4 ) ,
279282 weak_maps : Vec :: with_capacity ( heap. weak_maps . len ( ) / 4 ) ,
280283 weak_refs : Vec :: with_capacity ( heap. weak_refs . len ( ) / 4 ) ,
@@ -416,7 +419,7 @@ impl CompactionList {
416419 . unwrap_or ( 0 )
417420 }
418421
419- pub ( crate ) fn shift_index < T > ( & self , index : & mut BaseIndex < T > ) {
422+ pub ( crate ) fn shift_index < T : ? Sized > ( & self , index : & mut BaseIndex < T > ) {
420423 let base_index = index. into_u32_index ( ) ;
421424 * index = BaseIndex :: from_u32_index ( base_index - self . get_shift_for_index ( base_index) ) ;
422425 }
@@ -711,26 +714,32 @@ where
711714 }
712715}
713716
714- pub ( crate ) fn mark_array_with_u32_length < T : HeapMarkAndSweep + std :: fmt :: Debug , const N : usize > (
717+ pub ( crate ) fn mark_array_with_u32_length < T : HeapMarkAndSweep , const N : usize > (
715718 array : & Option < [ T ; N ] > ,
716719 queues : & mut WorkQueues ,
717720 length : u32 ,
718721) {
719- let length: u32 = * length. borrow ( ) ;
720-
721722 array. as_ref ( ) . unwrap ( ) [ ..length as usize ]
722723 . iter ( )
723724 . for_each ( |value| {
724725 value. mark_values ( queues) ;
725726 } ) ;
726727}
727728
729+ pub ( crate ) fn mark_descriptors (
730+ descriptors : & HashMap < u32 , ElementDescriptor > ,
731+ queues : & mut WorkQueues ,
732+ ) {
733+ for descriptor in descriptors. values ( ) {
734+ descriptor. mark_values ( queues) ;
735+ }
736+ }
737+
728738fn sweep_array_with_u32_length < T : HeapMarkAndSweep , const N : usize > (
729739 array : & mut Option < [ T ; N ] > ,
730740 compactions : & CompactionLists ,
731741 length : u32 ,
732742) {
733- let length: u32 = * length. borrow ( ) ;
734743 if length == 0 {
735744 return ;
736745 }
@@ -741,15 +750,16 @@ fn sweep_array_with_u32_length<T: HeapMarkAndSweep, const N: usize>(
741750 } ) ;
742751}
743752
744- pub ( crate ) fn sweep_heap_vector_values < T : HeapMarkAndSweep > (
753+ pub ( crate ) fn sweep_heap_vector_values < T : HeapMarkAndSweep + std :: fmt :: Debug > (
745754 vec : & mut Vec < T > ,
746755 compactions : & CompactionLists ,
747756 bits : & [ bool ] ,
748757) {
749758 assert_eq ! ( vec. len( ) , bits. len( ) ) ;
750759 let mut iter = bits. iter ( ) ;
751760 vec. retain_mut ( |item| {
752- if * iter. next ( ) . unwrap ( ) {
761+ let do_retain = iter. next ( ) . unwrap ( ) ;
762+ if * do_retain {
753763 item. sweep_values ( compactions) ;
754764 true
755765 } else {
@@ -811,3 +821,41 @@ pub(crate) fn sweep_heap_u32_elements_vector_values<const N: usize>(
811821 }
812822 } ) ;
813823}
824+
825+ pub ( crate ) fn sweep_heap_elements_vector_descriptors < T > (
826+ descriptors : & mut HashMap < ElementIndex , HashMap < u32 , ElementDescriptor > > ,
827+ compactions : & CompactionLists ,
828+ self_compactions : & CompactionList ,
829+ marks : & [ ( bool , T ) ] ,
830+ ) {
831+ let mut keys_to_remove = Vec :: with_capacity ( marks. len ( ) / 4 ) ;
832+ let mut keys_to_reassign = Vec :: with_capacity ( marks. len ( ) / 4 ) ;
833+ for ( key, descriptor) in descriptors. iter_mut ( ) {
834+ let old_key = * key;
835+ if !marks. get ( key. into_index ( ) ) . unwrap ( ) . 0 {
836+ keys_to_remove. push ( old_key) ;
837+ } else {
838+ for descriptor in descriptor. values_mut ( ) {
839+ descriptor. sweep_values ( compactions) ;
840+ }
841+ let mut new_key = old_key;
842+ self_compactions. shift_index ( & mut new_key) ;
843+ if new_key != old_key {
844+ keys_to_reassign. push ( ( old_key, new_key) ) ;
845+ }
846+ }
847+ }
848+ keys_to_remove. sort ( ) ;
849+ keys_to_reassign. sort ( ) ;
850+ for old_key in keys_to_remove. iter ( ) {
851+ // println!("Dropping descriptors at key {:?}: {:?}", old_key, descriptors.get(old_key).unwrap());
852+ descriptors. remove ( old_key) ;
853+ }
854+ for ( old_key, new_key) in keys_to_reassign {
855+ // SAFETY: The old key came from iterating descriptors, and the same
856+ // key cannot appear in both keys to remove and keys to reassign. Thus
857+ // the key must necessarily exist in the descriptors hash map.
858+ let descriptor = unsafe { descriptors. remove ( & old_key) . unwrap_unchecked ( ) } ;
859+ descriptors. insert ( new_key, descriptor) ;
860+ }
861+ }
0 commit comments