| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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 part of repositories; | 5 part of repositories; |
| 6 | 6 |
| 7 String _tagToString(M.SampleProfileTag tag) { | 7 String _tagToString(M.SampleProfileTag tag) { |
| 8 switch (tag) { | 8 switch (tag) { |
| 9 case M.SampleProfileTag.userVM: return 'UserVM'; | 9 case M.SampleProfileTag.userVM: |
| 10 case M.SampleProfileTag.userOnly: return 'UserOnly'; | 10 return 'UserVM'; |
| 11 case M.SampleProfileTag.vmUser: return 'VMUser'; | 11 case M.SampleProfileTag.userOnly: |
| 12 case M.SampleProfileTag.vmOnly: return 'VMOnly'; | 12 return 'UserOnly'; |
| 13 case M.SampleProfileTag.none: return 'None'; | 13 case M.SampleProfileTag.vmUser: |
| 14 return 'VMUser'; |
| 15 case M.SampleProfileTag.vmOnly: |
| 16 return 'VMOnly'; |
| 17 case M.SampleProfileTag.none: |
| 18 return 'None'; |
| 14 } | 19 } |
| 15 throw new Exception('Unknown SampleProfileTag: $tag'); | 20 throw new Exception('Unknown SampleProfileTag: $tag'); |
| 16 } | 21 } |
| 17 | 22 |
| 18 class SampleProfileLoadingProgressEvent | 23 class SampleProfileLoadingProgressEvent |
| 19 implements M.SampleProfileLoadingProgressEvent { | 24 implements M.SampleProfileLoadingProgressEvent { |
| 20 final SampleProfileLoadingProgress progress; | 25 final SampleProfileLoadingProgress progress; |
| 21 SampleProfileLoadingProgressEvent(this.progress); | 26 SampleProfileLoadingProgressEvent(this.progress); |
| 22 } | 27 } |
| 23 | 28 |
| 24 class SampleProfileLoadingProgress extends M.SampleProfileLoadingProgress { | 29 class SampleProfileLoadingProgress extends M.SampleProfileLoadingProgress { |
| 25 StreamController<SampleProfileLoadingProgressEvent> _onProgress = | 30 StreamController<SampleProfileLoadingProgressEvent> _onProgress = |
| 26 new StreamController<SampleProfileLoadingProgressEvent>.broadcast(); | 31 new StreamController<SampleProfileLoadingProgressEvent>.broadcast(); |
| 27 Stream<SampleProfileLoadingProgressEvent> get onProgress => | 32 Stream<SampleProfileLoadingProgressEvent> get onProgress => |
| 28 _onProgress.stream; | 33 _onProgress.stream; |
| 29 | 34 |
| 30 final S.Isolate isolate; | 35 final S.Isolate isolate; |
| 31 final S.Class cls; | 36 final S.Class cls; |
| 32 final M.SampleProfileTag tag; | 37 final M.SampleProfileTag tag; |
| 33 final bool clear; | 38 final bool clear; |
| 34 | 39 |
| 35 M.SampleProfileLoadingStatus _status = M.SampleProfileLoadingStatus.fetching; | 40 M.SampleProfileLoadingStatus _status = M.SampleProfileLoadingStatus.fetching; |
| 36 double _progress = 0.0; | 41 double _progress = 0.0; |
| 37 final Stopwatch _fetchingTime = new Stopwatch(); | 42 final Stopwatch _fetchingTime = new Stopwatch(); |
| 38 final Stopwatch _loadingTime = new Stopwatch(); | 43 final Stopwatch _loadingTime = new Stopwatch(); |
| 39 CpuProfile _profile; | 44 CpuProfile _profile; |
| 40 | 45 |
| 41 M.SampleProfileLoadingStatus get status => _status; | 46 M.SampleProfileLoadingStatus get status => _status; |
| 42 double get progress => _progress; | 47 double get progress => _progress; |
| 43 Duration get fetchingTime => _fetchingTime.elapsed; | 48 Duration get fetchingTime => _fetchingTime.elapsed; |
| 44 Duration get loadingTime => _loadingTime.elapsed; | 49 Duration get loadingTime => _loadingTime.elapsed; |
| 45 CpuProfile get profile => _profile; | 50 CpuProfile get profile => _profile; |
| 46 | 51 |
| 47 SampleProfileLoadingProgress(this.isolate, this.tag, | 52 SampleProfileLoadingProgress(this.isolate, this.tag, this.clear, {this.cls}) { |
| 48 this.clear, {this.cls}) { | 53 _run(); |
| 49 _run(); | |
| 50 } | 54 } |
| 51 | 55 |
| 52 Future _run() async { | 56 Future _run() async { |
| 53 _fetchingTime.start(); | 57 _fetchingTime.start(); |
| 54 try { | 58 try { |
| 55 if (clear) { | 59 if (clear) { |
| 56 await isolate.invokeRpc('_clearCpuProfile', { }); | 60 await isolate.invokeRpc('_clearCpuProfile', {}); |
| 57 } | 61 } |
| 58 | 62 |
| 59 final response = cls != null | 63 final response = cls != null |
| 60 ? await cls.getAllocationSamples(_tagToString(tag)) | 64 ? await cls.getAllocationSamples(_tagToString(tag)) |
| 61 : await isolate.invokeRpc('_getCpuProfile', | 65 : await isolate |
| 62 { 'tags': _tagToString(tag) }); | 66 .invokeRpc('_getCpuProfile', {'tags': _tagToString(tag)}); |
| 63 | 67 |
| 64 _fetchingTime.stop(); | 68 _fetchingTime.stop(); |
| 65 _loadingTime.start(); | 69 _loadingTime.start(); |
| 66 _status = M.SampleProfileLoadingStatus.loading; | 70 _status = M.SampleProfileLoadingStatus.loading; |
| 67 _triggerOnProgress(); | 71 _triggerOnProgress(); |
| 68 | 72 |
| 69 CpuProfile profile = new CpuProfile(); | 73 CpuProfile profile = new CpuProfile(); |
| 70 | 74 |
| 71 Stream<double> progress = profile.loadProgress(isolate, response); | 75 Stream<double> progress = profile.loadProgress(isolate, response); |
| 72 progress.listen((value) { _progress = value; _triggerOnProgress(); }); | 76 progress.listen((value) { |
| 77 _progress = value; |
| 78 _triggerOnProgress(); |
| 79 }); |
| 73 | 80 |
| 74 await progress.drain(); | 81 await progress.drain(); |
| 75 | 82 |
| 76 profile.buildFunctionCallerAndCallees(); | 83 profile.buildFunctionCallerAndCallees(); |
| 77 _profile = profile; | 84 _profile = profile; |
| 78 | 85 |
| 79 _loadingTime.stop(); | 86 _loadingTime.stop(); |
| 80 _status = M.SampleProfileLoadingStatus.loaded; | 87 _status = M.SampleProfileLoadingStatus.loaded; |
| 81 _triggerOnProgress(); | 88 _triggerOnProgress(); |
| 82 } catch (e) { | 89 } catch (e) { |
| 83 if (e is S.ServerRpcException) { | 90 if (e is S.ServerRpcException) { |
| 84 if (e.code == S.ServerRpcException.kFeatureDisabled) { | 91 if (e.code == S.ServerRpcException.kFeatureDisabled) { |
| 85 _status = M.SampleProfileLoadingStatus.disabled; | 92 _status = M.SampleProfileLoadingStatus.disabled; |
| 86 _triggerOnProgress(); | 93 _triggerOnProgress(); |
| 87 } | 94 } |
| 88 } | 95 } |
| 89 rethrow; | 96 rethrow; |
| 90 } finally { | 97 } finally { |
| 91 _onProgress.close(); | 98 _onProgress.close(); |
| 92 } | 99 } |
| 93 } | 100 } |
| 94 | 101 |
| 95 void _triggerOnProgress() { | 102 void _triggerOnProgress() { |
| 96 _onProgress.add(new SampleProfileLoadingProgressEvent(this)); | 103 _onProgress.add(new SampleProfileLoadingProgressEvent(this)); |
| 97 } | 104 } |
| 98 | 105 |
| 99 void reuse() { | 106 void reuse() { |
| 100 _onProgress = | 107 _onProgress = |
| 101 new StreamController<SampleProfileLoadingProgressEvent>.broadcast(); | 108 new StreamController<SampleProfileLoadingProgressEvent>.broadcast(); |
| 102 (() async { | 109 (() async { |
| 103 _triggerOnProgress(); | 110 _triggerOnProgress(); |
| 104 _onProgress.close(); | 111 _onProgress.close(); |
| 105 }()); | 112 }()); |
| 106 } | 113 } |
| 107 } | 114 } |
| 108 | 115 |
| 109 class IsolateSampleProfileRepository | 116 class IsolateSampleProfileRepository |
| 110 implements M.IsolateSampleProfileRepository { | 117 implements M.IsolateSampleProfileRepository { |
| 111 SampleProfileLoadingProgress _last; | 118 SampleProfileLoadingProgress _last; |
| 112 | 119 |
| 113 Stream<SampleProfileLoadingProgressEvent> get(M.IsolateRef i, | 120 Stream<SampleProfileLoadingProgressEvent> get( |
| 114 M.SampleProfileTag t, {bool clear: false, bool forceFetch: false}) { | 121 M.IsolateRef i, M.SampleProfileTag t, |
| 122 {bool clear: false, bool forceFetch: false}) { |
| 115 assert(clear != null); | 123 assert(clear != null); |
| 116 assert(forceFetch != null); | 124 assert(forceFetch != null); |
| 117 S.Isolate isolate = i as S.Isolate; | 125 S.Isolate isolate = i as S.Isolate; |
| 118 assert(isolate != null); | 126 assert(isolate != null); |
| 119 if (_last != null && !clear && !forceFetch && _last.isolate == isolate) { | 127 if (_last != null && !clear && !forceFetch && _last.isolate == isolate) { |
| 120 _last.reuse(); | 128 _last.reuse(); |
| 121 } else { | 129 } else { |
| 122 _last = new SampleProfileLoadingProgress(isolate, t, clear); | 130 _last = new SampleProfileLoadingProgress(isolate, t, clear); |
| 123 } | 131 } |
| 124 return _last.onProgress; | 132 return _last.onProgress; |
| 125 } | 133 } |
| 126 } | 134 } |
| 127 | 135 |
| 128 class ClassSampleProfileRepository | 136 class ClassSampleProfileRepository implements M.ClassSampleProfileRepository { |
| 129 implements M.ClassSampleProfileRepository { | 137 Stream<SampleProfileLoadingProgressEvent> get( |
| 130 Stream<SampleProfileLoadingProgressEvent> get(M.Isolate i, M.ClassRef c, | 138 M.Isolate i, M.ClassRef c, M.SampleProfileTag t) { |
| 131 M.SampleProfileTag t) { | |
| 132 S.Isolate isolate = i as S.Isolate; | 139 S.Isolate isolate = i as S.Isolate; |
| 133 S.Class cls = c as S.Class; | 140 S.Class cls = c as S.Class; |
| 134 assert(isolate != null); | 141 assert(isolate != null); |
| 135 assert(cls != null); | 142 assert(cls != null); |
| 136 return new SampleProfileLoadingProgress(isolate, t, | 143 return new SampleProfileLoadingProgress(isolate, t, false, cls: cls) |
| 137 false, cls: cls).onProgress; | 144 .onProgress; |
| 138 } | 145 } |
| 139 | 146 |
| 140 Future enable(M.IsolateRef i, M.ClassRef c) { | 147 Future enable(M.IsolateRef i, M.ClassRef c) { |
| 141 S.Class cls = c as S.Class; | 148 S.Class cls = c as S.Class; |
| 142 assert(cls != null); | 149 assert(cls != null); |
| 143 return cls.setTraceAllocations(true); | 150 return cls.setTraceAllocations(true); |
| 144 } | 151 } |
| 145 | 152 |
| 146 Future disable(M.IsolateRef i, M.ClassRef c) { | 153 Future disable(M.IsolateRef i, M.ClassRef c) { |
| 147 S.Class cls = c as S.Class; | 154 S.Class cls = c as S.Class; |
| 148 assert(cls != null); | 155 assert(cls != null); |
| 149 return cls.setTraceAllocations(false); | 156 return cls.setTraceAllocations(false); |
| 150 } | 157 } |
| 151 } | 158 } |
| OLD | NEW |