| OLD | NEW |
| 1 // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2017, 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 /// This file supports profiling dynamic calls. | 5 /// This file supports profiling dynamic calls. |
| 6 part of dart._runtime; | 6 part of dart._runtime; |
| 7 | 7 |
| 8 class _MethodStats { | 8 class _MethodStats { |
| 9 final String typeName; | 9 final String typeName; |
| 10 final String frame; | 10 final String frame; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 // Skip first two lines as the first couple frames are from the dart | 65 // Skip first two lines as the first couple frames are from the dart |
| 66 // runtime. | 66 // runtime. |
| 67 for (int i = 2; i < frames.length; ++i) { | 67 for (int i = 2; i < frames.length; ++i) { |
| 68 var frame = frames[i]; | 68 var frame = frames[i]; |
| 69 var mappedFrame = _frameMappingCache.putIfAbsent(frame, () { | 69 var mappedFrame = _frameMappingCache.putIfAbsent(frame, () { |
| 70 return stackTraceMapper('\n${frame}'); | 70 return stackTraceMapper('\n${frame}'); |
| 71 }); | 71 }); |
| 72 if (!mappedFrame.contains('dart:_runtime/operations.dart') && | 72 if (!mappedFrame.contains('dart:_runtime/operations.dart') && |
| 73 !mappedFrame.contains('dart:_runtime/profile.dart')) { | 73 !mappedFrame.contains('dart:_runtime/profile.dart')) { |
| 74 src = mappedFrame; | 74 src = mappedFrame; |
| 75 |
| 75 break; | 76 break; |
| 76 } | 77 } |
| 77 } | 78 } |
| 78 | 79 |
| 79 var actualTypeName = typeName(record.type); | 80 var actualTypeName = typeName(record.type); |
| 80 callMethodStats | 81 callMethodStats |
| 81 .putIfAbsent("$actualTypeName <$src>", | 82 .putIfAbsent("$actualTypeName <$src>", |
| 82 () => new _MethodStats(actualTypeName, src)) | 83 () => new _MethodStats(actualTypeName, src)) |
| 83 .count += recordRatio; | 84 .count += recordRatio; |
| 84 } | 85 } |
| (...skipping 22 matching lines...) Expand all Loading... |
| 107 var stats = callMethodStats[key]; | 108 var stats = callMethodStats[key]; |
| 108 ret.add([stats.typeName, stats.frame, stats.count.round()]); | 109 ret.add([stats.typeName, stats.frame, stats.count.round()]); |
| 109 } | 110 } |
| 110 return ret; | 111 return ret; |
| 111 } | 112 } |
| 112 | 113 |
| 113 clearDynamicStats() { | 114 clearDynamicStats() { |
| 114 _callMethodRecords.clear(); | 115 _callMethodRecords.clear(); |
| 115 } | 116 } |
| 116 | 117 |
| 117 bool _trackProfile = false; | 118 // We need to set this property while the sdk is only partially initialized |
| 119 // so we cannot use a regular Dart field. |
| 120 bool get _trackProfile => JS('bool', 'dart.__trackProfile'); |
| 118 | 121 |
| 119 void trackProfile(bool flag) { | 122 void trackProfile(bool flag) { |
| 120 _trackProfile = flag; | 123 JS('', 'dart.__trackProfile = #', flag); |
| 121 } | 124 } |
| 122 | 125 |
| 123 _trackCall(obj) { | 126 _trackCall(obj) { |
| 124 if (JS('bool', '!#', trackProfile)) return; | 127 if (JS('bool', '!#', _trackProfile)) return; |
| 125 int index = -1; | 128 int index = -1; |
| 126 _totalCallRecords++; | 129 _totalCallRecords++; |
| 127 if (_callMethodRecords.length == _callRecordSampleSize) { | 130 if (_callMethodRecords.length == _callRecordSampleSize) { |
| 128 // Ensure that each sample has an equal | 131 // Ensure that each sample has an equal |
| 129 // _callRecordSampleSize / _totalCallRecords chance of inclusion | 132 // _callRecordSampleSize / _totalCallRecords chance of inclusion |
| 130 // by choosing to include the new record in the sample the with the | 133 // by choosing to include the new record in the sample the with the |
| 131 // appropriate probability randomly evicting one of the existing records. | 134 // appropriate probability randomly evicting one of the existing records. |
| 132 // Unfortunately we can't use the excellent Random.nextInt method defined | 135 // Unfortunately we can't use the excellent Random.nextInt method defined |
| 133 // by Dart from within this library. | 136 // by Dart from within this library. |
| 134 index = JS('int', 'Math.floor(Math.random() * #)', _totalCallRecords); | 137 index = JS('int', 'Math.floor(Math.random() * #)', _totalCallRecords); |
| 135 if (index >= _callMethodRecords.length) return; // don't sample | 138 if (index >= _callMethodRecords.length) return; // don't sample |
| 136 } | 139 } |
| 137 var record = | 140 var record = |
| 138 new _CallMethodRecord(JS('', 'new Error()'), getReifiedType(obj)); | 141 new _CallMethodRecord(JS('', 'new Error()'), getReifiedType(obj)); |
| 139 if (index == -1) { | 142 if (index == -1) { |
| 140 _callMethodRecords.add(record); | 143 _callMethodRecords.add(record); |
| 141 } else { | 144 } else { |
| 142 _callMethodRecords[index] = record; | 145 _callMethodRecords[index] = record; |
| 143 } | 146 } |
| 144 } | 147 } |
| OLD | NEW |