[ package:vm_service ] Prepare for 6.0.1 stable null-safe release There is no diff between this version and 6.0.1-nullsafety.1. This temporarily reverts commit 8d99d295da76c5ac381ea80623876cf04f23ee84. TEST=None Change-Id: I3597b3543c9ea9122865604b9ba07c99683a5355 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/182580 Reviewed-by: Nate Bosch <nbosch@google.com>
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md index f6a97c1..eb20917 100644 --- a/pkg/vm_service/CHANGELOG.md +++ b/pkg/vm_service/CHANGELOG.md
@@ -1,11 +1,7 @@ # Changelog -## 6.1.0-nullsafety.0 -- Added `identityHashCode` property to `HeapSnapshotObject`, which can be used to compare - objects across heap snapshots. -- Added `successors` iterable to `HeapSnapshotObject`, which provides a convenient way to - access children of a given object. -- Added `klass` getter to `HeapSnapshotObject`. +## 6.0.1 +- Stable null-safe release. ## 6.0.1-nullsafety.1 - Fix issue where some `Instance` properties were not being populated correctly. @@ -16,6 +12,7 @@ ## 6.0.0-nullsafety.4 - Fixed issue where response parsing could fail for `SourceReportRange.coverage` if no coverage information was provided. + ## 6.0.0-nullsafety.3 - Fixed issue where `Response.type` and classes which override `Response.type` were returning the name of the `package:vm_service` reference object (e.g., InstanceRef) instead of
diff --git a/pkg/vm_service/lib/src/snapshot_graph.dart b/pkg/vm_service/lib/src/snapshot_graph.dart index 4db040a..7e93eed 100644 --- a/pkg/vm_service/lib/src/snapshot_graph.dart +++ b/pkg/vm_service/lib/src/snapshot_graph.dart
@@ -15,9 +15,6 @@ _ReadStream(this._chunks); - bool get atEnd => ((_byteIndex >= _chunks[_chunkIndex].lengthInBytes) && - (_chunkIndex + 1 >= _chunks.length)); - int readByte() { while (_byteIndex >= _chunks[_chunkIndex].lengthInBytes) { _chunkIndex++; @@ -120,9 +117,6 @@ /// A representation of a class type captured in a memory snapshot. class HeapSnapshotClass { - /// The class ID representing this type. - int get classId => _classId; - /// The simple (not qualified) name of the class. String get name => _name; @@ -135,13 +129,12 @@ /// The list of fields in the class. List<HeapSnapshotField> get fields => _fields; - final int _classId; String _name = ''; String _libraryName = ''; late final Uri _libraryUri; final List<HeapSnapshotField> _fields = <HeapSnapshotField>[]; - HeapSnapshotClass._read(this._classId, _ReadStream reader) { + HeapSnapshotClass._read(_ReadStream reader) { // flags (reserved). reader.readUnsigned(); @@ -155,18 +148,6 @@ _populateFields(reader); } - HeapSnapshotClass._root() - : _classId = 0, - _name = 'Root', - _libraryName = '', - _libraryUri = Uri(); - - HeapSnapshotClass._sentinel() - : _classId = 0, - _name = 'Sentinel', - _libraryName = '', - _libraryUri = Uri(); - void _populateFields(_ReadStream reader) { final fieldCount = reader.readUnsigned(); for (int i = 0; i < fieldCount; ++i) { @@ -180,14 +161,6 @@ /// The class ID representing the type of this object. int get classId => _classId; - /// The class representing the type of this object. - HeapSnapshotClass get klass { - if (_classId <= 0) { - return HeapSnapshotClass._sentinel(); - } - return _graph._classes[_classId]; - } - /// The space used by this object in bytes. int get shallowSize => _shallowSize; @@ -197,54 +170,22 @@ /// A list of 1-origin indicies into [HeapSnapshotGraph.objects]. List<int> get references => _references; - /// The identity hash code of this object. - /// - /// If `identityHashCode` is 0, either the snapshot did not contain the list - /// of identity hash codes or this object cannot be compared across - /// snapshots. - int get identityHashCode => _identityHashCode; - - Iterable<HeapSnapshotObject> get successors sync* { - final startSuccessorIndex = _graph._firstSuccessors[_oid]; - final limitSuccessorIndex = _graph._firstSuccessors[_oid + 1]; - - for (int nextSuccessorIndex = startSuccessorIndex; - nextSuccessorIndex < limitSuccessorIndex; - ++nextSuccessorIndex) { - final successorId = _graph._successors[nextSuccessorIndex]; - yield _graph.objects[successorId]; - } - } - - final HeapSnapshotGraph _graph; - final int _oid; int _classId = -1; int _shallowSize = -1; - int _identityHashCode = 0; late final dynamic _data; final List<int> _references = <int>[]; - HeapSnapshotObject._sentinel(this._graph) - : _oid = 0, - _data = HeapSnapshotObjectNoData() { - _graph._firstSuccessors[_oid] = _graph._eid; - } - - HeapSnapshotObject._read(this._graph, this._oid, _ReadStream reader) { + HeapSnapshotObject._read(_ReadStream reader) { _classId = reader.readUnsigned(); _shallowSize = reader.readUnsigned(); _data = _getNonReferenceData(reader); - _graph._firstSuccessors[_oid] = _graph._eid; _populateReferences(reader); } void _populateReferences(_ReadStream reader) { final referencesCount = reader.readUnsigned(); for (int i = 0; i < referencesCount; ++i) { - int childOid = reader.readUnsigned(); - _references.add(childOid); - _graph._successors[_graph._eid] = childOid; - _graph._eid++; + _references.add(reader.readUnsigned()); } } } @@ -308,10 +249,6 @@ final List<HeapSnapshotExternalProperty> _externalProperties = <HeapSnapshotExternalProperty>[]; - late Uint32List _firstSuccessors; - late Uint32List _successors; - int _eid = 0; - /// Requests a heap snapshot for a given isolate and builds a /// [HeapSnapshotGraph]. /// @@ -353,31 +290,23 @@ _capacity = reader.readUnsigned(); _externalSize = reader.readUnsigned(); _populateClasses(reader); + _referenceCount = reader.readUnsigned(); _populateObjects(reader); _populateExternalProperties(reader); - _populateIdentityHashCodes(reader); } void _populateClasses(_ReadStream reader) { final classCount = reader.readUnsigned(); - _classes.add(HeapSnapshotClass._root()); - for (int i = 1; i <= classCount; ++i) { - final klass = HeapSnapshotClass._read(i, reader); - _classes.add(klass); + for (int i = 0; i < classCount; ++i) { + _classes.add(HeapSnapshotClass._read(reader)); } } void _populateObjects(_ReadStream reader) { - _referenceCount = reader.readUnsigned(); final objectCount = reader.readUnsigned(); - _firstSuccessors = _newUint32Array(objectCount + 2); - _successors = _newUint32Array(_referenceCount); - - _objects.add(HeapSnapshotObject._sentinel(this)); - for (int i = 1; i <= objectCount; ++i) { - _objects.add(HeapSnapshotObject._read(this, i, reader)); + for (int i = 0; i < objectCount; ++i) { + _objects.add(HeapSnapshotObject._read(reader)); } - _firstSuccessors[objectCount + 1] = _eid; } void _populateExternalProperties(_ReadStream reader) { @@ -386,29 +315,6 @@ _externalProperties.add(HeapSnapshotExternalProperty._read(reader)); } } - - void _populateIdentityHashCodes(_ReadStream reader) { - if (reader.atEnd) { - // Older VMs don't include identity hash codes. - return; - } - final objectCount = _objects.length; - for (int i = 1; i < objectCount; ++i) { - _objects[i]._identityHashCode = reader.readUnsigned(); - } - } - - Uint32List _newUint32Array(int size) { - try { - return Uint32List(size); - } on ArgumentError { - // JS throws a misleading invalid argument error. Convert to a more - // user-friendly message. - throw Exception( - 'OutOfMemoryError: Not enough memory available to analyze the snapshot.', - ); - } - } } const _kNoData = 0;
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml index 3e87a37..fcf9783 100644 --- a/pkg/vm_service/pubspec.yaml +++ b/pkg/vm_service/pubspec.yaml
@@ -3,7 +3,7 @@ A library to communicate with a service implementing the Dart VM service protocol. -version: 6.1.0-nullsafety.0 +version: 6.0.1 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/vm_service @@ -13,10 +13,10 @@ dependencies: dev_dependencies: - async: ^2.5.0-nullsafety.3 + async: ^2.5.0 markdown: ^4.0.0-nullsafety.0 mockito: ^5.0.0-nullsafety.1 - path: ^1.8.0-nullsafety.3 + path: ^1.8.0 pedantic: ^1.10.0-nullsafety.3 pub_semver: ^2.0.0-nullsafety.0 test: ^1.16.0-nullsafety.13
diff --git a/pkg/vm_service/test/common/test_helper.dart b/pkg/vm_service/test/common/test_helper.dart index cd6a983..634ec64 100644 --- a/pkg/vm_service/test/common/test_helper.dart +++ b/pkg/vm_service/test/common/test_helper.dart
@@ -133,7 +133,7 @@ fullArgs.add('--pause-isolates-on-start'); } if (pause_on_exit) { - fullArgs.add('--pause-isolates-on-exit'); + fullArgs.add('--pause-isolates-on-io.exit'); } if (!useAuthToken) { fullArgs.add('--disable-service-auth-codes');
diff --git a/pkg/vm_service/test/heap_snapshot_graph_test.dart b/pkg/vm_service/test/heap_snapshot_graph_test.dart index 51490ec..b9fbe10 100644 --- a/pkg/vm_service/test/heap_snapshot_graph_test.dart +++ b/pkg/vm_service/test/heap_snapshot_graph_test.dart
@@ -44,8 +44,7 @@ int actualShallowSize = 0; int actualRefCount = 0; snapshotGraph.objects.forEach((HeapSnapshotObject o) { - // -1 is the CID used by the sentinel. - expect(o.classId >= -1, isTrue); + expect(o.classId >= 0, isTrue); expect(o.data, isNotNull); expect(o.references, isNotNull); actualShallowSize += o.shallowSize; @@ -92,7 +91,7 @@ foosFound = 0; snapshotGraph.objects.forEach((HeapSnapshotObject o) { if (o.classId == 0) return; - if (o.classId == fooClassId) { + if (o.classId - 1 == fooClassId) { foosFound++; } });
diff --git a/pkg/vm_service/test/object_graph_identity_hash_test.dart b/pkg/vm_service/test/object_graph_identity_hash_test.dart deleted file mode 100644 index da61a9d..0000000 --- a/pkg/vm_service/test/object_graph_identity_hash_test.dart +++ /dev/null
@@ -1,159 +0,0 @@ -// Copyright (c) 2021, 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:collection'; - -import 'package:vm_service/vm_service.dart'; -import 'package:test/test.dart'; -import 'common/service_test_common.dart'; -import 'common/test_helper.dart'; - -class Foo {} - -class Bar {} - -class Container1 { - @pragma("vm:entry-point") - Foo foo = Foo(); - @pragma("vm:entry-point") - Bar bar = Bar(); -} - -class Container2 { - Container2(this.foo); - - @pragma("vm:entry-point") - Foo foo; - @pragma("vm:entry-point") - Bar bar = Bar(); -} - -class Container3 { - @pragma("vm:entry-point") - int number = 42; - @pragma("vm:entry-point") - double doub = 3.14; - @pragma("vm:entry-point") - String foo = 'foobar'; - @pragma("vm:entry-point") - bool bar = false; - @pragma("vm:entry-point") - late Map baz; - @pragma("vm:entry-point") - late LinkedHashMap linkedBaz; - @pragma("vm:entry-point") - late List list; - @pragma("vm:entry-point") - late List unmodifiableList; - - Container3() { - baz = { - 'a': 'b', - }; - linkedBaz = LinkedHashMap.from(baz); - list = [1, 2, 3]; - unmodifiableList = List.empty(); - } -} - -late Container1 c1; -late Container2 c2; -late Container3 c3; - -void script() { - c1 = Container1(); - c2 = Container2(c1.foo); - c3 = Container3(); -} - -late HeapSnapshotGraph snapshot1; -late HeapSnapshotObject snapshot1Foo; -late HeapSnapshotObject snapshot1Bar; - -late HeapSnapshotGraph snapshot2; -late HeapSnapshotObject snapshot2Foo; -late HeapSnapshotObject snapshot2Bar; - -late HeapSnapshotGraph snapshot3; - -final tests = <IsolateTest>[ - (VmService service, IsolateRef isolate) async { - snapshot1 = await HeapSnapshotGraph.getSnapshot(service, isolate); - - Iterable<HeapSnapshotObject> container1s = snapshot1.objects.where( - (HeapSnapshotObject obj) => obj.klass.name == 'Container1', - ); - expect(container1s.length, 1); - - final c1Obj = container1s.first; - - snapshot1Foo = c1Obj.successors.firstWhere( - (element) => element.klass.name == 'Foo', - ); - expect( - snapshot1Foo.identityHashCode != 0, - true, - ); - - snapshot1Bar = c1Obj.successors.firstWhere( - (element) => element.klass.name == 'Bar', - ); - expect( - snapshot1Bar.identityHashCode != 0, - true, - ); - }, - (VmService service, IsolateRef isolate) async { - snapshot2 = await HeapSnapshotGraph.getSnapshot(service, isolate); - ; - Iterable<HeapSnapshotObject> container2s = snapshot2.objects.where( - (HeapSnapshotObject obj) => obj.klass.name == 'Container2', - ); - expect(container2s.length, 1); - - final c2Obj = container2s.first; - - snapshot2Foo = c2Obj.successors.firstWhere( - (element) => element.klass.name == 'Foo', - ); - expect( - snapshot2Foo.identityHashCode != 0, - true, - ); - expect( - snapshot1Foo.identityHashCode == snapshot2Foo.identityHashCode, - true, - ); - - snapshot2Bar = c2Obj.successors.firstWhere( - (element) => element.klass.name == 'Bar', - ); - expect( - snapshot2Bar.identityHashCode != 0, - true, - ); - expect( - snapshot1Bar.identityHashCode != snapshot2Bar.identityHashCode, - true, - ); - }, - (VmService service, IsolateRef isolate) async { - snapshot3 = await HeapSnapshotGraph.getSnapshot(service, isolate); - Iterable<HeapSnapshotObject> container3s = snapshot3.objects.where( - (HeapSnapshotObject obj) => obj.klass.name == 'Container3', - ); - expect(container3s.length, 1); - final c3Obj = container3s.first; - for (final successor in c3Obj.successors) { - expect(successor.identityHashCode, 0); - } - }, -]; - -main(args) => runIsolateTests( - args, - tests, - testeeBefore: script, - pause_on_exit: true, - );
diff --git a/runtime/observatory/lib/object_graph.dart b/runtime/observatory/lib/object_graph.dart index 85f64df..f0adee0 100644 --- a/runtime/observatory/lib/object_graph.dart +++ b/runtime/observatory/lib/object_graph.dart
@@ -202,16 +202,11 @@ /// An object in a heap snapshot. abstract class SnapshotObject { - /// The identity hash code of this object, used to compare objects across - /// snapshots. If [identityHashCode] is 0, this object cannot be compared to - /// other objects. - int get identityHashCode; - - /// If this object has been obtained from [successors] or [predecessors], the - /// name of slot. Otherwise, the empty string. + // If this object has been obtained from [successors] or [predecessors], the + // name of slot. Otherwise, the empty string. String get label; - /// The value for primitives. Otherwise, the class name. + // The value for primitives. Otherwise, the class name. String get description; /// [internalSize] + [externalSize]. @@ -260,12 +255,10 @@ class _SnapshotObject implements SnapshotObject { final int _id; - final int identityHashCode; final _SnapshotGraph _graph; final String label; - _SnapshotObject._new(this._id, this._graph, this.label) - : identityHashCode = _graph._identityHashes![_id]; + _SnapshotObject._new(this._id, this._graph, this.label); bool operator ==(Object other) { if (other is _SnapshotObject) { @@ -351,7 +344,6 @@ late SnapshotObject _parent; late List<SnapshotObject> _children; - int get identityHashCode => 0; String get label => ""; String get description => _description; SnapshotClass get klass => _klass; @@ -813,9 +805,6 @@ onProgress.add("Loading external properties..."); await new Future(() => _readExternalProperties(stream!)); - onProgress.add("Loading object identity hash codes..."); - await new Future(() => _readObjectIdentityHashes(stream!)); - stream = null; onProgress.add("Compute class table..."); @@ -888,7 +877,6 @@ Uint32List? _externalSizes; Uint32List? _firstSuccs; Uint32List? _succs; - Uint32List? _identityHashes; // Intermediates. Uint32List? _vertex; @@ -1048,15 +1036,6 @@ _externalSizes = externalSizes; } - void _readObjectIdentityHashes(_ReadStream stream) { - final N = _N!; - final identityHashes = _newUint32Array(N + 1); - for (int oid = 1; oid <= N; ++oid) { - identityHashes[oid] = stream.readUnsigned(); - } - _identityHashes = identityHashes; - } - void _computeClassTable() { final N = _N!; final classes = _classes!;
diff --git a/runtime/observatory/tests/service/object_graph_identity_hash_test.dart b/runtime/observatory/tests/service/object_graph_identity_hash_test.dart deleted file mode 100644 index eb7c109..0000000 --- a/runtime/observatory/tests/service/object_graph_identity_hash_test.dart +++ /dev/null
@@ -1,160 +0,0 @@ -// Copyright (c) 2021, 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 'package:observatory/object_graph.dart'; -import 'package:observatory/service_io.dart'; -import 'package:test/test.dart'; -import 'service_test_common.dart'; -import 'test_helper.dart'; - -class Foo {} - -class Bar {} - -class Container1 { - @pragma("vm:entry-point") - Foo foo = Foo(); - @pragma("vm:entry-point") - Bar bar = Bar(); -} - -class Container2 { - Container2(this.foo); - - @pragma("vm:entry-point") - Foo foo; - @pragma("vm:entry-point") - Bar bar = Bar(); -} - -class Container3 { - @pragma("vm:entry-point") - int number = 42; - @pragma("vm:entry-point") - double doub = 3.14; - @pragma("vm:entry-point") - String foo = 'foobar'; - @pragma("vm:entry-point") - bool bar = false; - @pragma("vm:entry-point") - late Map baz; - @pragma("vm:entry-point") - late List list; - @pragma("vm:entry-point") - late List unmodifiableList; - - Container3() { - baz = { - 'a': 'b', - }; - list = [1, 2, 3]; - unmodifiableList = List.empty(); - } -} - -@pragma("vm:entry-point") -late Container1 c1; -@pragma("vm:entry-point") -late Container2 c2; -@pragma("vm:entry-point") -late Container3 c3; - -void script() { - c1 = Container1(); - c2 = Container2(c1.foo); - c3 = Container3(); -} - -late SnapshotGraph snapshot1; -late SnapshotObject snapshot1Foo; -late SnapshotObject snapshot1Bar; - -late SnapshotGraph snapshot2; -late SnapshotObject snapshot2Foo; -late SnapshotObject snapshot2Bar; - -late SnapshotGraph snapshot3; - -final tests = <IsolateTest>[ - (Isolate isolate) async { - snapshot1 = await isolate.fetchHeapSnapshot().done; - - Iterable<SnapshotObject> container1s = snapshot1.objects.where( - (SnapshotObject obj) => obj.klass.name == 'Container1', - ); - expect(container1s.length, 1); - - final c1Obj = container1s.first; - - c1Obj.successors.forEach((element) { - print(element.klass.name); - }); - snapshot1Foo = c1Obj.successors.firstWhere( - (element) => element.klass.name == 'Foo', - ); - expect( - snapshot1Foo.identityHashCode != 0, - true, - ); - - snapshot1Bar = c1Obj.successors.firstWhere( - (element) => element.klass.name == 'Bar', - ); - expect( - snapshot1Bar.identityHashCode != 0, - true, - ); - }, - (Isolate isolate) async { - snapshot2 = await isolate.fetchHeapSnapshot().done; - Iterable<SnapshotObject> container2s = snapshot2.objects.where( - (SnapshotObject obj) => obj.klass.name == 'Container2', - ); - expect(container2s.length, 1); - - final c2Obj = container2s.first; - - snapshot2Foo = c2Obj.successors.firstWhere( - (element) => element.klass.name == 'Foo', - ); - expect( - snapshot2Foo.identityHashCode != 0, - true, - ); - expect( - snapshot1Foo.identityHashCode == snapshot2Foo.identityHashCode, - true, - ); - - snapshot2Bar = c2Obj.successors.firstWhere( - (element) => element.klass.name == 'Bar', - ); - expect( - snapshot2Bar.identityHashCode != 0, - true, - ); - expect( - snapshot1Bar.identityHashCode != snapshot2Bar.identityHashCode, - true, - ); - }, - (Isolate isolate) async { - snapshot3 = await isolate.fetchHeapSnapshot().done; - Iterable<SnapshotObject> container3s = snapshot3.objects.where( - (SnapshotObject obj) => obj.klass.name == 'Container3', - ); - expect(container3s.length, 1); - final c3Obj = container3s.first; - for (final successor in c3Obj.successors) { - expect(successor.identityHashCode, 0); - } - }, -]; - -main(args) => runIsolateTests( - args, - tests, - testeeBefore: script, - pause_on_exit: true, - );
diff --git a/runtime/observatory_2/lib/object_graph.dart b/runtime/observatory_2/lib/object_graph.dart index 21b426a..0e891ce 100644 --- a/runtime/observatory_2/lib/object_graph.dart +++ b/runtime/observatory_2/lib/object_graph.dart
@@ -202,16 +202,11 @@ /// An object in a heap snapshot. abstract class SnapshotObject { - /// The identity hash code of this object, used to compare objects across - /// snapshots. If [identityHashCode] is 0, this object cannot be compared to - /// other objects. - int get identityHashCode; - - /// If this object has been obtained from [successors] or [predecessors], the - /// name of slot. Otherwise, the empty string. + // If this object has been obtained from [successors] or [predecessors], the + // name of slot. Otherwise, the empty string. String get label; - /// The value for primitives. Otherwise, the class name. + // The value for primitives. Otherwise, the class name. String get description; /// [internalSize] + [externalSize]. @@ -260,12 +255,10 @@ class _SnapshotObject implements SnapshotObject { final int _id; - final int identityHashCode; final _SnapshotGraph _graph; final String label; - _SnapshotObject._new(this._id, this._graph, this.label) - : identityHashCode = _graph._identityHashes[_id]; + _SnapshotObject._new(this._id, this._graph, this.label); bool operator ==(Object other) { if (other is _SnapshotObject) { @@ -351,7 +344,6 @@ SnapshotObject _parent; List<SnapshotObject> _children; - int get identityHashCode => 0; String get label => null; String get description => _description; SnapshotClass get klass => _klass; @@ -802,9 +794,6 @@ onProgress.add("Loading external properties..."); await new Future(() => _readExternalProperties(stream)); - onProgress.add("Loading object identity hash codes..."); - await new Future(() => _readObjectIdentityHashes(stream)); - stream = null; onProgress.add("Compute class table..."); @@ -877,7 +866,6 @@ Uint32List _externalSizes; Uint32List _firstSuccs; Uint32List _succs; - Uint32List _identityHashes; // Intermediates. Uint32List _vertex; @@ -1037,15 +1025,6 @@ _externalSizes = externalSizes; } - void _readObjectIdentityHashes(_ReadStream stream) { - final N = _N; - final identityHashes = _newUint32Array(N + 1); - for (int oid = 1; oid <= N; ++oid) { - identityHashes[oid] = stream.readUnsigned(); - } - _identityHashes = identityHashes; - } - void _computeClassTable() { final N = _N; final classes = _classes;
diff --git a/runtime/observatory_2/tests/service_2/object_graph_identity_hash_test.dart b/runtime/observatory_2/tests/service_2/object_graph_identity_hash_test.dart deleted file mode 100644 index ed5c71b..0000000 --- a/runtime/observatory_2/tests/service_2/object_graph_identity_hash_test.dart +++ /dev/null
@@ -1,160 +0,0 @@ -// Copyright (c) 2021, 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 'package:observatory_2/object_graph.dart'; -import 'package:observatory_2/service_io.dart'; -import 'package:test/test.dart'; -import 'service_test_common.dart'; -import 'test_helper.dart'; - -class Foo {} - -class Bar {} - -class Container1 { - @pragma("vm:entry-point") - Foo foo = Foo(); - @pragma("vm:entry-point") - Bar bar = Bar(); -} - -class Container2 { - Container2(this.foo); - - @pragma("vm:entry-point") - Foo foo; - @pragma("vm:entry-point") - Bar bar = Bar(); -} - -class Container3 { - @pragma("vm:entry-point") - int number = 42; - @pragma("vm:entry-point") - double doub = 3.14; - @pragma("vm:entry-point") - String foo = 'foobar'; - @pragma("vm:entry-point") - bool bar = false; - @pragma("vm:entry-point") - Map baz; - @pragma("vm:entry-point") - List list; - @pragma("vm:entry-point") - List unmodifiableList; - - Container3() { - baz = { - 'a': 'b', - }; - list = [1, 2, 3]; - unmodifiableList = List.empty(); - } -} - -@pragma("vm:entry-point") -Container1 c1; -@pragma("vm:entry-point") -Container2 c2; -@pragma("vm:entry-point") -Container3 c3; - -void script() { - c1 = Container1(); - c2 = Container2(c1.foo); - c3 = Container3(); -} - -SnapshotGraph snapshot1; -SnapshotObject snapshot1Foo; -SnapshotObject snapshot1Bar; - -SnapshotGraph snapshot2; -SnapshotObject snapshot2Foo; -SnapshotObject snapshot2Bar; - -SnapshotGraph snapshot3; - -final tests = <IsolateTest>[ - (Isolate isolate) async { - snapshot1 = await isolate.fetchHeapSnapshot().done; - - Iterable<SnapshotObject> container1s = snapshot1.objects.where( - (SnapshotObject obj) => obj.klass.name == 'Container1', - ); - expect(container1s.length, 1); - - final c1Obj = container1s.first; - - c1Obj.successors.forEach((element) { - print(element.klass.name); - }); - snapshot1Foo = c1Obj.successors.firstWhere( - (element) => element.klass.name == 'Foo', - ); - expect( - snapshot1Foo.identityHashCode != 0, - true, - ); - - snapshot1Bar = c1Obj.successors.firstWhere( - (element) => element.klass.name == 'Bar', - ); - expect( - snapshot1Bar.identityHashCode != 0, - true, - ); - }, - (Isolate isolate) async { - snapshot2 = await isolate.fetchHeapSnapshot().done; - Iterable<SnapshotObject> container2s = snapshot2.objects.where( - (SnapshotObject obj) => obj.klass.name == 'Container2', - ); - expect(container2s.length, 1); - - final c2Obj = container2s.first; - - snapshot2Foo = c2Obj.successors.firstWhere( - (element) => element.klass.name == 'Foo', - ); - expect( - snapshot2Foo.identityHashCode != 0, - true, - ); - expect( - snapshot1Foo.identityHashCode == snapshot2Foo.identityHashCode, - true, - ); - - snapshot2Bar = c2Obj.successors.firstWhere( - (element) => element.klass.name == 'Bar', - ); - expect( - snapshot2Bar.identityHashCode != 0, - true, - ); - expect( - snapshot1Bar.identityHashCode != snapshot2Bar.identityHashCode, - true, - ); - }, - (Isolate isolate) async { - snapshot3 = await isolate.fetchHeapSnapshot().done; - Iterable<SnapshotObject> container3s = snapshot3.objects.where( - (SnapshotObject obj) => obj.klass.name == 'Container3', - ); - expect(container3s.length, 1); - final c3Obj = container3s.first; - for (final successor in c3Obj.successors) { - expect(successor.identityHashCode, 0); - } - }, -]; - -main(args) => runIsolateTests( - args, - tests, - testeeBefore: script, - pause_on_exit: true, - );
diff --git a/runtime/vm/object_graph.cc b/runtime/vm/object_graph.cc index f71a1745..489b5e1 100644 --- a/runtime/vm/object_graph.cc +++ b/runtime/vm/object_graph.cc
@@ -1013,90 +1013,6 @@ DISALLOW_COPY_AND_ASSIGN(Pass2Visitor); }; -class Pass3Visitor : public ObjectVisitor { - public: - explicit Pass3Visitor(HeapSnapshotWriter* writer) - : ObjectVisitor(), isolate_(Isolate::Current()), writer_(writer) {} - - void VisitObject(ObjectPtr obj) { - if (obj->IsPseudoObject()) { - return; - } - writer_->WriteUnsigned(GetHash(obj)); - } - - private: - uint32_t GetHash(ObjectPtr obj) { - if (!obj->IsHeapObject()) return 0; - intptr_t cid = obj->GetClassId(); - uint32_t hash = 0; - switch (cid) { - case kForwardingCorpse: - case kFreeListElement: - case kSmiCid: - UNREACHABLE(); - case kArrayCid: - case kBoolCid: - case kCodeSourceMapCid: - case kCompressedStackMapsCid: - case kDoubleCid: - case kExternalOneByteStringCid: - case kExternalTwoByteStringCid: - case kGrowableObjectArrayCid: - case kImmutableArrayCid: - case kInstructionsCid: - case kInstructionsSectionCid: - case kLinkedHashMapCid: - case kMintCid: - case kNeverCid: - case kNullCid: - case kObjectPoolCid: - case kOneByteStringCid: - case kPcDescriptorsCid: - case kTwoByteStringCid: - case kVoidCid: - // Don't provide hash codes for objects with the above CIDs in order - // to try and avoid having to initialize identity hash codes for common - // primitives and types that don't have hash codes. - break; - default: { - hash = GetHashHelper(obj); - } - } - return hash; - } - - uint32_t GetHashHelper(ObjectPtr obj) { - uint32_t hash; -#if defined(HASH_IN_OBJECT_HEADER) - hash = Object::GetCachedHash(obj); - if (hash == 0) { - ASSERT( - !isolate_->group()->heap()->old_space()->IsObjectFromImagePages(obj)); - hash = isolate_->random()->NextUInt32(); - Object::SetCachedHash(obj, hash); - hash = Object::GetCachedHash(obj); - } -#else - Heap* heap = isolate_->group()->heap(); - hash = heap->GetHash(obj); - if (hash == 0) { - ASSERT(!heap->old_space()->IsObjectFromImagePages(obj)); - heap->SetHash(obj, isolate_->random()->NextUInt32()); - hash = heap->GetHash(obj); - } -#endif - return hash; - } - - // TODO(dartbug.com/36097): Once the shared class table contains more - // information than just the size (i.e. includes an immutable class - // descriptor), we can remove this dependency on the current isolate. - Isolate* isolate_; - HeapSnapshotWriter* const writer_; - - DISALLOW_COPY_AND_ASSIGN(Pass3Visitor); -}; void HeapSnapshotWriter::Write() { HeapIterationScope iteration(thread()); @@ -1265,18 +1181,6 @@ isolate()->group()->VisitWeakPersistentHandles(&visitor); } - { - // Identity hash codes - Pass3Visitor visitor(this); - - // Handle root object. - WriteUnsigned(0); - - // Handle visit rest of the objects. - iteration.IterateVMIsolateObjects(&visitor); - iteration.IterateObjects(&visitor); - } - ClearObjectIds(); Flush(true); }
diff --git a/runtime/vm/service/heap_snapshot.md b/runtime/vm/service/heap_snapshot.md index b2c167f..c32d562 100644 --- a/runtime/vm/service/heap_snapshot.md +++ b/runtime/vm/service/heap_snapshot.md
@@ -41,7 +41,7 @@ // The amount of memory reserved for this heap. At least as large as |shallowSize|. capacity : uleb128, - // The sum of sizes of all external properties in this graph. + // The sum of sizes of all external properites in this graph. externalSize : uleb128, classCount : uleb128, @@ -54,14 +54,6 @@ externalPropertyCount : uleb128, externalProperties : SnapshotExternalProperty[externalPropertyCount], - - // The list of identity hash codes corresponding to each entry in objects. - // A hash code of zero is invalid and cannot be used to determine equality - // between objects. If the same object is included in multiple - // HeapSnapshots, it will report the same identityHashCode. The converse is - // not true: two different objects may report the same identityHashCode - // (with low probability). - identityHashCodes: uint32[objectCount], } ```