[vm] Avoid repeating fields in heapsnapshot class descriptions

Fixes https://github.com/dart-lang/sdk/issues/49710

TEST=tests/vm/dart{,_2}/heap_snapshot_regress_49710_test.dart

Change-Id: Ib2c31a582381dcfaf12739b9d0c7e28d98063791
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/255813
Reviewed-by: Ryan Macnak <rmacnak@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
Martin Kustermann
2022-08-19 16:51:45 +00:00
committed by Commit Bot
parent 325e401bd2
commit d68ca2cc57
4 changed files with 67 additions and 3 deletions
@@ -0,0 +1,30 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'dart:_internal';
import 'package:expect/expect.dart';
import 'package:path/path.dart' as path;
import 'heap_snapshot_test.dart';
import 'use_flag_test_helper.dart';
main() async {
if (const bool.fromEnvironment('dart.vm.product')) return;
await withTempDir('heap_snapshot_test', (String dir) async {
final file = path.join(dir, 'state1.heapsnapshot');
VMInternalsForTesting.writeHeapSnapshotToFile(file);
final snapshot = loadHeapSnapshotFromFile(file);
for (final klass in snapshot.classes) {
// Ensure field indices are unique.
final fields = klass.fields.toList()..sort((a, b) => a.index - b.index);
int lastIndex = -1;
for (int i = 0; i < fields.length; ++i) {
Expect.notEquals(lastIndex, fields[i].index);
lastIndex = fields[i].index;
}
}
});
}
@@ -0,0 +1,32 @@
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// @dart=2.9
import 'dart:_internal';
import 'package:expect/expect.dart';
import 'package:path/path.dart' as path;
import 'heap_snapshot_test.dart';
import 'use_flag_test_helper.dart';
main() async {
if (const bool.fromEnvironment('dart.vm.product')) return;
await withTempDir('heap_snapshot_test', (String dir) async {
final file = path.join(dir, 'state1.heapsnapshot');
VMInternalsForTesting.writeHeapSnapshotToFile(file);
final snapshot = loadHeapSnapshotFromFile(file);
for (final klass in snapshot.classes) {
// Ensure field indices are unique.
final fields = klass.fields.toList()..sort((a, b) => a.index - b.index);
int lastIndex = -1;
for (int i = 0; i < fields.length; ++i) {
Expect.notEquals(lastIndex, fields[i].index);
lastIndex = fields[i].index;
}
}
});
}
+4 -2
View File
@@ -1338,16 +1338,18 @@ void HeapSnapshotWriter::Write() {
}
WriteUtf8(""); // Reserved
bool via_offsets_table = false;
intptr_t field_count = 0;
intptr_t min_offset = kIntptrMax;
for (const auto& entry : OffsetsTable::offsets_table()) {
if (entry.class_id == cid) {
via_offsets_table = true;
field_count++;
intptr_t offset = entry.offset;
min_offset = Utils::Minimum(min_offset, offset);
}
}
if (cls.is_finalized()) {
if (!via_offsets_table && cls.is_finalized()) {
do {
fields = cls.fields();
if (!fields.IsNull()) {
@@ -1376,7 +1378,7 @@ void HeapSnapshotWriter::Write() {
WriteUtf8(""); // Reserved
}
}
if (cls.is_finalized()) {
if (!via_offsets_table && cls.is_finalized()) {
do {
fields = cls.fields();
if (!fields.IsNull()) {
+1 -1
View File
@@ -166,7 +166,7 @@ namespace dart {
F(LinkedHashMap, hash_mask_) \
F(LinkedHashMap, data_) \
F(LinkedHashMap, used_data_) \
F(LinkedHashSet, deleted_keys_) \
F(LinkedHashMap, deleted_keys_) \
F(LinkedHashSet, type_arguments_) \
F(LinkedHashSet, index_) \
F(LinkedHashSet, hash_mask_) \