Skip to content

Commit 5bd9f11

Browse files
committed
refactor(set): flatten set data
1 parent 14e6a98 commit 5bd9f11

File tree

3 files changed

+45
-62
lines changed

3 files changed

+45
-62
lines changed

nova_vm/src/ecmascript/builtins/keyed_collections/set_objects/set_constructor.rs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@ use crate::{
1818
builders::builtin_function_builder::BuiltinFunctionBuilder,
1919
builtins::{
2020
ArgumentsList, Behaviour, Builtin, BuiltinGetter, BuiltinIntrinsicConstructor,
21-
array::ArrayHeap,
22-
ordinary::ordinary_create_from_constructor,
23-
set::{Set, data::SetData},
21+
array::ArrayHeap, ordinary::ordinary_create_from_constructor, set::Set,
2422
},
2523
execution::{Agent, JsResult, ProtoIntrinsics, Realm, agent::ExceptionType},
2624
types::{
@@ -144,10 +142,9 @@ impl SetConstructor {
144142
let array_heap = ArrayHeap::new(elements, arrays);
145143
let primitive_heap = PrimitiveHeap::new(bigints, numbers, strings);
146144

147-
let SetData {
148-
values, set_data, ..
149-
} = &mut sets[set].borrow_mut(&primitive_heap);
150-
let set_data = set_data.get_mut();
145+
let set_heap_data = &mut sets[set].borrow_mut(&primitive_heap);
146+
let values = &mut set_heap_data.values;
147+
let set_data = set_heap_data.set_data.get_mut();
151148

152149
let hasher = |value: Value| {
153150
let mut hasher = AHasher::default();

nova_vm/src/ecmascript/builtins/keyed_collections/set_objects/set_prototype.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::{
2020
map_objects::map_prototype::canonicalize_keyed_collection_key,
2121
set_objects::set_iterator_objects::set_iterator::SetIterator,
2222
},
23-
set::{Set, data::SetData},
23+
set::Set,
2424
},
2525
execution::{Agent, JsResult, Realm, agent::ExceptionType},
2626
types::{BUILTIN_STRING_MEMORY, IntoValue, Number, PropertyKey, String, Value},
@@ -115,10 +115,9 @@ impl SetPrototype {
115115
// 3. Set value to CanonicalizeKeyedCollectionKey(value).
116116
let value = canonicalize_keyed_collection_key(numbers, value);
117117

118-
let SetData {
119-
values, set_data, ..
120-
} = &mut sets[s].borrow_mut(&primitive_heap);
121-
let set_data = set_data.get_mut();
118+
let set_heap_data = &mut sets[s].borrow_mut(&primitive_heap);
119+
let values = &mut set_heap_data.values;
120+
let set_data = set_heap_data.set_data.get_mut();
122121
let hasher = |value: Value| {
123122
let mut hasher = AHasher::default();
124123
value.hash(&primitive_heap, &mut hasher);
@@ -207,10 +206,9 @@ impl SetPrototype {
207206
value.hash(&primitive_heap, &mut hasher);
208207
hasher.finish()
209208
};
210-
let SetData {
211-
values, set_data, ..
212-
} = &mut sets[s].borrow_mut(&primitive_heap);
213-
let set_data = set_data.get_mut();
209+
let set_heap_data = &mut sets[s].borrow_mut(&primitive_heap);
210+
let values = &mut set_heap_data.values;
211+
let set_data = set_heap_data.set_data.get_mut();
214212
// 4. For each element e of S.[[SetData]], do
215213
if let Ok(entry) = set_data.find_entry(value_hash, |hash_equal_index| {
216214
let found_value = values[*hash_equal_index as usize].unwrap();
@@ -372,10 +370,9 @@ impl SetPrototype {
372370
..
373371
} = &agent.heap;
374372
let primitive_heap = PrimitiveHeap::new(bigints, numbers, strings);
375-
let SetData {
376-
values, set_data, ..
377-
} = &sets[s].borrow(&primitive_heap);
378-
let set_data = set_data.borrow();
373+
let set_heap_data = &sets[s].borrow(&primitive_heap);
374+
let values = &set_heap_data.values;
375+
let set_data = set_heap_data.set_data.borrow();
379376

380377
// 3. Set value to CanonicalizeKeyedCollectionKey(value).
381378
let value = canonicalize_keyed_collection_key(&primitive_heap, value);

nova_vm/src/ecmascript/builtins/set/data.rs

Lines changed: 31 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,22 @@ use core::{
1717
sync::atomic::{AtomicBool, Ordering},
1818
};
1919
use hashbrown::{HashTable, hash_table::Entry};
20+
use soavec_derive::SoAble;
2021

21-
#[derive(Debug, Default)]
22+
#[derive(Debug, Default, SoAble)]
2223
pub struct SetHeapData<'a> {
2324
pub(crate) object_index: Option<OrdinaryObject<'a>>,
24-
set_data: SetData<'a>,
25+
pub(crate) values: Vec<Option<Value<'a>>>,
26+
/// Low-level hash table pointing to value indexes.
27+
pub(crate) set_data: RefCell<HashTable<u32>>,
28+
/// Flag that lets the Set know if it needs to rehash its primitive keys.
29+
///
30+
/// This happens when an object key needs to be moved in the set_data
31+
/// during garbage collection, and the move results in a primitive key
32+
/// moving as well. The primitive key's hash cannot be calculated during
33+
/// garbage collection due to the heap data being concurrently sweeped on
34+
/// another thread.
35+
pub(crate) needs_primitive_rehashing: AtomicBool,
2536
// TODO: When an non-terminal (start or end) iterator exists for the Set,
2637
// the items in the set cannot be compacted.
2738
// pub(crate) observed: bool;
@@ -38,58 +49,40 @@ impl<'a> SetHeapData<'a> {
3849
// 2. For each element e of setData, do
3950
// a. If e is not EMPTY, set count to count + 1.
4051
// 3. Return count.
41-
self.set_data.set_data.borrow().len() as u32
52+
self.set_data.borrow().len() as u32
4253
}
4354

4455
pub fn values(&self, _gc: NoGcScope<'a, '_>) -> &[Option<Value<'a>>] {
45-
&self.set_data.values
56+
&self.values
4657
}
4758

4859
pub fn clear(&mut self) {
4960
// 3. For each element e of S.[[SetData]], do
5061
// a. Replace the element of S.[[SetData]] whose value is e with an
5162
// element whose value is EMPTY.
52-
self.set_data.set_data.get_mut().clear();
53-
self.set_data.values.fill(None);
63+
self.set_data.get_mut().clear();
64+
self.values.fill(None);
5465
}
5566

56-
pub(crate) fn borrow(&self, arena: &impl PrimitiveHeapIndexable) -> &SetData<'a> {
57-
self.set_data.rehash_if_needed(arena);
58-
&self.set_data
67+
pub(crate) fn borrow(&self, arena: &impl PrimitiveHeapIndexable) -> &Self {
68+
self.rehash_if_needed(arena);
69+
self
5970
}
6071

61-
pub(crate) fn borrow_mut(&mut self, arena: &impl PrimitiveHeapIndexable) -> &mut SetData<'a> {
62-
self.set_data.rehash_if_needed(arena);
63-
&mut self.set_data
72+
pub(crate) fn borrow_mut(&mut self, arena: &impl PrimitiveHeapIndexable) -> &mut Self {
73+
self.rehash_if_needed(arena);
74+
self
6475
}
6576
}
6677

67-
#[derive(Debug, Default)]
68-
pub(crate) struct SetData<'a> {
69-
pub(crate) values: Vec<Option<Value<'a>>>,
70-
/// Low-level hash table pointing to value indexes.
71-
pub(crate) set_data: RefCell<HashTable<u32>>,
72-
/// Flag that lets the Set know if it needs to rehash its primitive keys.
73-
///
74-
/// This happens when an object key needs to be moved in the set_data
75-
/// during garbage collection, and the move results in a primitive key
76-
/// moving as well. The primitive key's hash cannot be calculated during
77-
/// garbage collection due to the heap data being concurrently sweeped on
78-
/// another thread.
79-
pub(crate) needs_primitive_rehashing: AtomicBool,
80-
}
81-
82-
impl SetData<'_> {
78+
impl SetHeapData<'_> {
8379
fn rehash_if_needed(&self, arena: &impl PrimitiveHeapIndexable) {
8480
if !self.needs_primitive_rehashing.load(Ordering::Relaxed) {
8581
return;
8682
}
87-
let SetData {
88-
values, set_data, ..
89-
} = self;
90-
let mut set_data = set_data.borrow_mut();
83+
let mut set_data = self.set_data.borrow_mut();
9184

92-
rehash_set_data(values, &mut set_data, arena);
85+
rehash_set_data(&self.values, &mut set_data, arena);
9386
self.needs_primitive_rehashing
9487
.store(false, Ordering::Relaxed);
9588
}
@@ -160,25 +153,21 @@ impl HeapMarkAndSweep for SetHeapData<'static> {
160153
fn mark_values(&self, queues: &mut WorkQueues) {
161154
let Self {
162155
object_index,
163-
set_data,
156+
values,
157+
..
164158
} = self;
165159
object_index.mark_values(queues);
166-
set_data
167-
.values
168-
.iter()
169-
.for_each(|value| value.mark_values(queues));
160+
values.iter().for_each(|value| value.mark_values(queues));
170161
}
171162

172163
fn sweep_values(&mut self, compactions: &CompactionLists) {
173164
let Self {
174165
object_index,
175-
set_data,
176-
} = self;
177-
let SetData {
178166
values,
179167
set_data,
180168
needs_primitive_rehashing,
181-
} = set_data;
169+
..
170+
} = self;
182171
let set_data = set_data.get_mut();
183172
object_index.sweep_values(compactions);
184173

0 commit comments

Comments
 (0)