Skip to content

Commit 49a1a0c

Browse files
committed
rt: Add length field to Arrays in heap snapshot
1 parent 3935f5d commit 49a1a0c

File tree

1 file changed

+40
-27
lines changed

1 file changed

+40
-27
lines changed

dora-runtime/src/snapshot.rs

Lines changed: 40 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ pub struct SnapshotGenerator<'a> {
2222
nodes: Vec<Node>,
2323
nodes_map: HashMap<Address, NodeId>,
2424
edges: Vec<Edge>,
25+
edge_buffer: Vec<Edge>,
2526
strings: Vec<String>,
2627
strings_map: HashMap<String, StringId>,
2728
shape_name_map: HashMap<NodeId, StringId>,
@@ -30,26 +31,30 @@ pub struct SnapshotGenerator<'a> {
3031
empty_string_id: StringId,
3132
shape_edge_name_id: StringId,
3233
shape_type_name_id: StringId,
34+
length_name_id: StringId,
3335
vm: &'a VM,
3436
}
3537

3638
impl<'a> SnapshotGenerator<'a> {
3739
pub fn new(vm: &'a VM, path: PathBuf) -> IoResult<SnapshotGenerator<'a>> {
3840
let f = File::create(path)?;
3941
let writer = BufWriter::new(f);
42+
let placeholder = StringId(0);
4043

4144
Ok(SnapshotGenerator {
4245
writer,
4346
nodes: Vec::new(),
4447
nodes_map: HashMap::new(),
4548
edges: Vec::new(),
49+
edge_buffer: Vec::new(),
4650
strings: Vec::new(),
4751
strings_map: HashMap::new(),
4852
shape_name_map: HashMap::new(),
4953
meta_space_start: vm.meta_space_start(),
50-
shape_edge_name_id: StringId(0), // Will be initialized later.
51-
shape_type_name_id: StringId(0),
52-
empty_string_id: StringId(0),
54+
shape_edge_name_id: placeholder, // Will be initialized later.
55+
shape_type_name_id: placeholder,
56+
empty_string_id: placeholder,
57+
length_name_id: placeholder,
5358
value_map: HashMap::new(),
5459
vm,
5560
})
@@ -70,6 +75,7 @@ impl<'a> SnapshotGenerator<'a> {
7075
self.empty_string_id = self.ensure_string("".to_string());
7176
self.shape_edge_name_id = self.ensure_string("shape".to_string());
7277
self.shape_type_name_id = self.ensure_string("Shape".to_string());
78+
self.length_name_id = self.ensure_string("length".to_string());
7379
}
7480

7581
fn iterate_roots(&mut self, threads: &[Arc<DoraThread>]) {
@@ -121,7 +127,7 @@ impl<'a> SnapshotGenerator<'a> {
121127

122128
fn iterate_heap(&mut self) {
123129
let swiper = self.vm.gc.collector().to_swiper();
124-
swiper.iterate_heap(self.vm, |address| self.process_object(self.vm, address));
130+
swiper.iterate_heap(self.vm, |address| self.process_object(address));
125131
}
126132

127133
fn verify_snapshot(&mut self) {
@@ -140,7 +146,7 @@ impl<'a> SnapshotGenerator<'a> {
140146
assert_eq!(self.edges.len(), edge_count);
141147
}
142148

143-
fn process_object(&mut self, vm: &VM, address: Address) {
149+
fn process_object(&mut self, address: Address) {
144150
let node_id = self.ensure_node(address);
145151
let object = address.to_obj();
146152
let size = object.size(self.meta_space_start);
@@ -151,27 +157,34 @@ impl<'a> SnapshotGenerator<'a> {
151157
self.node_mut(node_id).first_edge = EdgeId(self.edges.len());
152158
self.node_mut(node_id).self_size = size;
153159

154-
let mut edge_count = 1;
155-
self.add_edge(Edge {
160+
let edge_start_idx = self.edge_buffer.len();
161+
162+
self.edge_buffer.push(Edge {
156163
name_or_idx: self.shape_edge_name_id.0,
157164
to_node_index: shape_node_id,
158165
kind: EdgeKind::Property,
159166
});
160167

161-
edge_count += match shape.kind() {
168+
let mut is_string = false;
169+
170+
match shape.kind() {
162171
ShapeKind::Class(cls_id, type_params) => {
163-
self.process_class_object(address, *cls_id, type_params, shape)
172+
self.process_class_object(address, *cls_id, type_params, shape);
164173
}
165174
ShapeKind::Array(cls_id, type_params) => {
166-
self.process_array_object(address, *cls_id, type_params, shape)
175+
self.process_array_object(address, *cls_id, type_params, shape);
167176
}
168-
ShapeKind::String => 0,
169-
_ => 0,
170-
};
171177

172-
self.node_mut(node_id).edge_count = edge_count;
178+
ShapeKind::String => {
179+
is_string = true;
180+
}
181+
_ => {}
182+
}
173183

174-
if std::ptr::eq(vm.known.string_shape(), shape) {
184+
self.node_mut(node_id).edge_count = self.edge_buffer.len() - edge_start_idx;
185+
self.edges.extend(self.edge_buffer.drain(edge_start_idx..));
186+
187+
if is_string {
175188
let value: String = Str::cast(object).content_utf8().into();
176189
self.node_mut(node_id).name = Some(self.ensure_string(value));
177190
self.node_mut(node_id).kind = NodeKind::String;
@@ -256,8 +269,7 @@ impl<'a> SnapshotGenerator<'a> {
256269
cls_id: ClassId,
257270
type_params: &BytecodeTypeArray,
258271
shape: &Shape,
259-
) -> usize {
260-
let mut edge_count = 0;
272+
) {
261273
let class = self.vm.class(cls_id);
262274

263275
for (field_idx, field) in class.fields.iter().enumerate() {
@@ -274,15 +286,12 @@ impl<'a> SnapshotGenerator<'a> {
274286
};
275287

276288
let field_name_idx = self.ensure_string(field_name);
277-
self.add_edge(Edge {
289+
self.edge_buffer.push(Edge {
278290
name_or_idx: field_name_idx.0,
279291
to_node_index: value_node_id,
280292
kind: EdgeKind::Property,
281293
});
282-
edge_count += 1;
283294
}
284-
285-
edge_count
286295
}
287296

288297
fn process_value(&mut self, value_address: Address, ty: &BytecodeType) -> NodeId {
@@ -347,8 +356,7 @@ impl<'a> SnapshotGenerator<'a> {
347356
_cls_id: ClassId,
348357
type_params: &BytecodeTypeArray,
349358
shape: &Shape,
350-
) -> usize {
351-
let mut edge_count = 0;
359+
) {
352360
let array: Ref<Array<u8>> = address.into();
353361
let length = array.len();
354362

@@ -359,18 +367,23 @@ impl<'a> SnapshotGenerator<'a> {
359367
assert_eq!(type_params.len(), 1);
360368
let ty = type_params[0].clone();
361369

370+
let length_id = self.ensure_value(format!("{}", length));
371+
372+
self.edge_buffer.push(Edge {
373+
name_or_idx: self.length_name_id.0,
374+
to_node_index: length_id,
375+
kind: EdgeKind::Property,
376+
});
377+
362378
for element_idx in 0..length {
363379
let element_node_id = self.process_value(element_addr, &ty);
364-
self.add_edge(Edge {
380+
self.edge_buffer.push(Edge {
365381
name_or_idx: element_idx,
366382
to_node_index: element_node_id,
367383
kind: EdgeKind::Element,
368384
});
369-
edge_count += 1;
370385
element_addr = element_addr.offset(element_size);
371386
}
372-
373-
edge_count
374387
}
375388

376389
fn add_edge(&mut self, edge: Edge) -> EdgeId {

0 commit comments

Comments
 (0)