| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 import 'dart:html'; | 5 import 'dart:html'; |
| 6 import 'dart:async'; | 6 import 'dart:async'; |
| 7 import 'package:observatory/models.dart' as M; | 7 import 'package:observatory/models.dart' as M; |
| 8 import 'package:observatory/src/elements/class_ref.dart'; | 8 import 'package:observatory/src/elements/class_ref.dart'; |
| 9 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; | 9 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; |
| 10 import 'package:observatory/src/elements/helpers/tag.dart'; | 10 import 'package:observatory/src/elements/helpers/tag.dart'; |
| 11 import 'package:observatory/src/elements/inbound_references.dart'; | 11 import 'package:observatory/src/elements/inbound_references.dart'; |
| 12 import 'package:observatory/src/elements/retaining_path.dart'; | 12 import 'package:observatory/src/elements/retaining_path.dart'; |
| 13 import 'package:observatory/src/elements/sentinel_value.dart'; | 13 import 'package:observatory/src/elements/sentinel_value.dart'; |
| 14 import 'package:observatory/src/elements/strongly_reachable_instances.dart'; | 14 import 'package:observatory/src/elements/strongly_reachable_instances.dart'; |
| 15 import 'package:observatory/src/elements/top_retaining_instances.dart'; | 15 import 'package:observatory/src/elements/top_retaining_instances.dart'; |
| 16 import 'package:observatory/utils.dart'; | 16 import 'package:observatory/utils.dart'; |
| 17 | 17 |
| 18 class ClassInstancesElement extends HtmlElement implements Renderable { | 18 class ClassInstancesElement extends HtmlElement implements Renderable { |
| 19 static const tag = const Tag<ClassInstancesElement>('class-instances', | 19 static const tag = |
| 20 dependencies: const [ | 20 const Tag<ClassInstancesElement>('class-instances', dependencies: const [ |
| 21 ClassRefElement.tag, | 21 ClassRefElement.tag, |
| 22 InboundReferencesElement.tag, | 22 InboundReferencesElement.tag, |
| 23 RetainingPathElement.tag, | 23 RetainingPathElement.tag, |
| 24 TopRetainingInstancesElement.tag | 24 TopRetainingInstancesElement.tag |
| 25 ]); | 25 ]); |
| 26 | 26 |
| 27 RenderingScheduler<ClassInstancesElement> _r; | 27 RenderingScheduler<ClassInstancesElement> _r; |
| 28 | 28 |
| 29 Stream<RenderedEvent<ClassInstancesElement>> get onRendered => _r.onRendered; | 29 Stream<RenderedEvent<ClassInstancesElement>> get onRendered => _r.onRendered; |
| 30 | 30 |
| 31 M.IsolateRef _isolate; | 31 M.IsolateRef _isolate; |
| 32 M.Class _cls; | 32 M.Class _cls; |
| 33 M.RetainedSizeRepository _retainedSizes; | 33 M.RetainedSizeRepository _retainedSizes; |
| 34 M.ReachableSizeRepository _reachableSizes; | 34 M.ReachableSizeRepository _reachableSizes; |
| 35 M.StronglyReachableInstancesRepository _stronglyReachableInstances; | 35 M.StronglyReachableInstancesRepository _stronglyReachableInstances; |
| 36 M.TopRetainingInstancesRepository _topRetainingInstances; | 36 M.TopRetainingInstancesRepository _topRetainingInstances; |
| 37 M.InstanceRepository _instances; | 37 M.InstanceRepository _instances; |
| 38 M.Guarded<M.Instance> _retainedSize = null; | 38 M.Guarded<M.Instance> _retainedSize = null; |
| 39 bool _loadingRetainedBytes = false; | 39 bool _loadingRetainedBytes = false; |
| 40 M.Guarded<M.Instance> _reachableSize = null; | 40 M.Guarded<M.Instance> _reachableSize = null; |
| 41 bool _loadingReachableBytes = false; | 41 bool _loadingReachableBytes = false; |
| 42 | 42 |
| 43 M.IsolateRef get isolate => _isolate; | 43 M.IsolateRef get isolate => _isolate; |
| 44 M.Class get cls => _cls; | 44 M.Class get cls => _cls; |
| 45 | 45 |
| 46 factory ClassInstancesElement(M.IsolateRef isolate, M.Class cls, | 46 factory ClassInstancesElement( |
| 47 M.IsolateRef isolate, |
| 48 M.Class cls, |
| 47 M.RetainedSizeRepository retainedSizes, | 49 M.RetainedSizeRepository retainedSizes, |
| 48 M.ReachableSizeRepository reachableSizes, | 50 M.ReachableSizeRepository reachableSizes, |
| 49 M.StronglyReachableInstancesRepository stronglyReachableInstances, | 51 M.StronglyReachableInstancesRepository stronglyReachableInstances, |
| 50 M.TopRetainingInstancesRepository topRetainingInstances, | 52 M.TopRetainingInstancesRepository topRetainingInstances, |
| 51 M.InstanceRepository instances, | 53 M.InstanceRepository instances, |
| 52 {RenderingQueue queue}) { | 54 {RenderingQueue queue}) { |
| 53 assert(isolate != null); | 55 assert(isolate != null); |
| 54 assert(cls != null); | 56 assert(cls != null); |
| 55 assert(retainedSizes != null); | 57 assert(retainedSizes != null); |
| 56 assert(reachableSizes != null); | 58 assert(reachableSizes != null); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 81 void detached() { | 83 void detached() { |
| 82 super.detached(); | 84 super.detached(); |
| 83 _r.disable(notify: true); | 85 _r.disable(notify: true); |
| 84 children = []; | 86 children = []; |
| 85 } | 87 } |
| 86 | 88 |
| 87 StronglyReachableInstancesElement _strong; | 89 StronglyReachableInstancesElement _strong; |
| 88 TopRetainingInstancesElement _topRetainig; | 90 TopRetainingInstancesElement _topRetainig; |
| 89 | 91 |
| 90 void render() { | 92 void render() { |
| 91 _strong = _strong ?? new StronglyReachableInstancesElement(_isolate, | 93 _strong = _strong ?? |
| 92 _cls, _stronglyReachableInstances, _instances, queue: _r.queue); | 94 new StronglyReachableInstancesElement( |
| 93 _topRetainig = _topRetainig ?? new TopRetainingInstancesElement(_isolate, | 95 _isolate, _cls, _stronglyReachableInstances, _instances, |
| 94 _cls, _topRetainingInstances, _instances, queue: _r.queue); | 96 queue: _r.queue); |
| 95 final instanceCount = _cls.newSpace.current.instances + | 97 _topRetainig = _topRetainig ?? |
| 96 _cls.oldSpace.current.instances; | 98 new TopRetainingInstancesElement( |
| 97 final size = Utils.formatSize(_cls.newSpace.current.bytes + | 99 _isolate, _cls, _topRetainingInstances, _instances, |
| 98 _cls.oldSpace.current.bytes); | 100 queue: _r.queue); |
| 101 final instanceCount = |
| 102 _cls.newSpace.current.instances + _cls.oldSpace.current.instances; |
| 103 final size = Utils |
| 104 .formatSize(_cls.newSpace.current.bytes + _cls.oldSpace.current.bytes); |
| 99 children = [ | 105 children = [ |
| 100 new DivElement()..classes = ['memberList'] | 106 new DivElement() |
| 107 ..classes = ['memberList'] |
| 101 ..children = [ | 108 ..children = [ |
| 102 new DivElement()..classes = const ['memberItem'] | 109 new DivElement() |
| 110 ..classes = const ['memberItem'] |
| 103 ..children = [ | 111 ..children = [ |
| 104 new DivElement()..classes = const ['memberName'] | 112 new DivElement() |
| 113 ..classes = const ['memberName'] |
| 105 ..text = 'currently allocated', | 114 ..text = 'currently allocated', |
| 106 new DivElement()..classes = const ['memberValue'] | 115 new DivElement() |
| 116 ..classes = const ['memberValue'] |
| 107 ..text = 'count ${instanceCount} (shallow size ${size})' | 117 ..text = 'count ${instanceCount} (shallow size ${size})' |
| 108 ], | 118 ], |
| 109 new DivElement()..classes = ['memberItem'] | 119 new DivElement() |
| 120 ..classes = ['memberItem'] |
| 110 ..children = [ | 121 ..children = [ |
| 111 new DivElement()..classes = ['memberName'] | 122 new DivElement() |
| 123 ..classes = ['memberName'] |
| 112 ..text = 'strongly reachable ', | 124 ..text = 'strongly reachable ', |
| 113 new DivElement()..classes = ['memberValue'] | 125 new DivElement() |
| 126 ..classes = ['memberValue'] |
| 114 ..children = [_strong] | 127 ..children = [_strong] |
| 115 ], | 128 ], |
| 116 new DivElement()..classes = ['memberItem'] | 129 new DivElement() |
| 130 ..classes = ['memberItem'] |
| 117 ..title = 'Space reachable from this object, ' | 131 ..title = 'Space reachable from this object, ' |
| 118 'excluding class references' | 132 'excluding class references' |
| 119 ..children = [ | 133 ..children = [ |
| 120 new DivElement()..classes = ['memberName'] | 134 new DivElement() |
| 135 ..classes = ['memberName'] |
| 121 ..text = 'Reachable size ', | 136 ..text = 'Reachable size ', |
| 122 new DivElement()..classes = ['memberValue'] | 137 new DivElement() |
| 138 ..classes = ['memberValue'] |
| 123 ..children = _createReachableSizeValue() | 139 ..children = _createReachableSizeValue() |
| 124 ], | 140 ], |
| 125 new DivElement()..classes = ['memberItem'] | 141 new DivElement() |
| 142 ..classes = ['memberItem'] |
| 126 ..title = 'Space that would be reclaimed if references to this ' | 143 ..title = 'Space that would be reclaimed if references to this ' |
| 127 'object were replaced with null' | 144 'object were replaced with null' |
| 128 ..children = [ | 145 ..children = [ |
| 129 new DivElement()..classes = ['memberName'] | 146 new DivElement() |
| 147 ..classes = ['memberName'] |
| 130 ..text = 'Retained size ', | 148 ..text = 'Retained size ', |
| 131 new DivElement()..classes = ['memberValue'] | 149 new DivElement() |
| 150 ..classes = ['memberValue'] |
| 132 ..children = _createRetainedSizeValue() | 151 ..children = _createRetainedSizeValue() |
| 133 ], | 152 ], |
| 134 new DivElement()..classes = ['memberItem'] | 153 new DivElement() |
| 154 ..classes = ['memberItem'] |
| 135 ..children = [ | 155 ..children = [ |
| 136 new DivElement()..classes = ['memberName'] | 156 new DivElement() |
| 157 ..classes = ['memberName'] |
| 137 ..text = 'toplist by retained memory ', | 158 ..text = 'toplist by retained memory ', |
| 138 new DivElement()..classes = ['memberValue'] | 159 new DivElement() |
| 160 ..classes = ['memberValue'] |
| 139 ..children = [_topRetainig] | 161 ..children = [_topRetainig] |
| 140 ] | 162 ] |
| 141 ] | 163 ] |
| 142 ]; | 164 ]; |
| 143 } | 165 } |
| 144 | 166 |
| 145 List<Element> _createReachableSizeValue() { | 167 List<Element> _createReachableSizeValue() { |
| 146 final content = <Element>[]; | 168 final content = <Element>[]; |
| 147 if (_reachableSize != null) { | 169 if (_reachableSize != null) { |
| 148 if (_reachableSize.isSentinel) { | 170 if (_reachableSize.isSentinel) { |
| 149 content.add( | 171 content.add(new SentinelValueElement(_reachableSize.asSentinel, |
| 150 new SentinelValueElement(_reachableSize.asSentinel, queue: _r.queue) | 172 queue: _r.queue)); |
| 151 ); | |
| 152 } else { | 173 } else { |
| 153 content.add( | 174 content.add(new SpanElement() |
| 154 new SpanElement()..text = Utils.formatSize(int.parse( | 175 ..text = Utils |
| 155 _reachableSize.asValue.valueAsString)) | 176 .formatSize(int.parse(_reachableSize.asValue.valueAsString))); |
| 156 ); | |
| 157 } | 177 } |
| 158 } else { | 178 } else { |
| 159 content.add( | 179 content.add(new SpanElement()..text = '...'); |
| 160 new SpanElement()..text = '...' | |
| 161 ); | |
| 162 } | 180 } |
| 163 final button = new ButtonElement()..classes = ['reachable_size'] | 181 final button = new ButtonElement() |
| 182 ..classes = ['reachable_size'] |
| 164 ..disabled = _loadingReachableBytes | 183 ..disabled = _loadingReachableBytes |
| 165 ..text = '↺'; | 184 ..text = '↺'; |
| 166 button.onClick.listen((_) async { | 185 button.onClick.listen((_) async { |
| 167 button.disabled = true; | 186 button.disabled = true; |
| 168 _loadingReachableBytes = true; | 187 _loadingReachableBytes = true; |
| 169 _reachableSize = await _reachableSizes.get(_isolate, _cls.id); | 188 _reachableSize = await _reachableSizes.get(_isolate, _cls.id); |
| 170 _r.dirty(); | 189 _r.dirty(); |
| 171 }); | 190 }); |
| 172 content.add(button); | 191 content.add(button); |
| 173 return content; | 192 return content; |
| 174 } | 193 } |
| 175 | 194 |
| 176 List<Element> _createRetainedSizeValue() { | 195 List<Element> _createRetainedSizeValue() { |
| 177 final content = <Element>[]; | 196 final content = <Element>[]; |
| 178 if (_retainedSize != null) { | 197 if (_retainedSize != null) { |
| 179 if (_retainedSize.isSentinel) { | 198 if (_retainedSize.isSentinel) { |
| 180 content.add( | 199 content.add(new SentinelValueElement(_retainedSize.asSentinel, |
| 181 new SentinelValueElement(_retainedSize.asSentinel, queue: _r.queue) | 200 queue: _r.queue)); |
| 182 ); | |
| 183 } else { | 201 } else { |
| 184 content.add( | 202 content.add(new SpanElement() |
| 185 new SpanElement()..text = Utils.formatSize(int.parse( | 203 ..text = |
| 186 _retainedSize.asValue.valueAsString)) | 204 Utils.formatSize(int.parse(_retainedSize.asValue.valueAsString))); |
| 187 ); | |
| 188 } | 205 } |
| 189 } else { | 206 } else { |
| 190 content.add( | 207 content.add(new SpanElement()..text = '...'); |
| 191 new SpanElement()..text = '...' | |
| 192 ); | |
| 193 } | 208 } |
| 194 final button = new ButtonElement()..classes = ['retained_size'] | 209 final button = new ButtonElement() |
| 210 ..classes = ['retained_size'] |
| 195 ..disabled = _loadingRetainedBytes | 211 ..disabled = _loadingRetainedBytes |
| 196 ..text = '↺'; | 212 ..text = '↺'; |
| 197 button.onClick.listen((_) async { | 213 button.onClick.listen((_) async { |
| 198 button.disabled = true; | 214 button.disabled = true; |
| 199 _loadingRetainedBytes = true; | 215 _loadingRetainedBytes = true; |
| 200 _retainedSize = await _retainedSizes.get(_isolate, _cls.id); | 216 _retainedSize = await _retainedSizes.get(_isolate, _cls.id); |
| 201 _r.dirty(); | 217 _r.dirty(); |
| 202 }); | 218 }); |
| 203 content.add(button); | 219 content.add(button); |
| 204 return content; | 220 return content; |
| 205 } | 221 } |
| 206 } | 222 } |
| OLD | NEW |