Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library defines runtime operations on objects used by the code | 5 /// This library defines runtime operations on objects used by the code |
| 6 /// generator. | 6 /// generator. |
| 7 part of dart._runtime; | 7 part of dart._runtime; |
| 8 | 8 |
| 9 class InvocationImpl extends Invocation { | 9 class InvocationImpl extends Invocation { |
| 10 final Symbol memberName; | 10 final Symbol memberName; |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 if (namedArgs == null) return {}; | 26 if (namedArgs == null) return {}; |
| 27 return new Map.fromIterable( | 27 return new Map.fromIterable( |
| 28 getOwnPropertyNames(namedArgs), | 28 getOwnPropertyNames(namedArgs), |
| 29 key: _dartSymbol, | 29 key: _dartSymbol, |
| 30 value: (k) => JS('', '#[#]', namedArgs, k)); | 30 value: (k) => JS('', '#[#]', namedArgs, k)); |
| 31 } | 31 } |
| 32 } | 32 } |
| 33 | 33 |
| 34 dload(obj, field) { | 34 dload(obj, field) { |
| 35 var f = _canonicalMember(obj, field); | 35 var f = _canonicalMember(obj, field); |
| 36 _trackCall(obj, f); | 36 _trackCall(obj); |
| 37 if (f != null) { | 37 if (f != null) { |
| 38 if (hasMethod(obj, f)) return bind(obj, f, JS('', 'void 0')); | 38 if (hasMethod(obj, f)) return bind(obj, f, JS('', 'void 0')); |
| 39 return JS('', '#[#]', obj, f); | 39 return JS('', '#[#]', obj, f); |
| 40 } | 40 } |
| 41 return noSuchMethod(obj, | 41 return noSuchMethod(obj, |
| 42 new InvocationImpl(field, JS('', '[]'), isGetter: true)); | 42 new InvocationImpl(field, JS('', '[]'), isGetter: true)); |
| 43 } | 43 } |
| 44 | 44 |
| 45 dput(obj, field, value) { | 45 dput(obj, field, value) { |
| 46 var f = _canonicalMember(obj, field); | 46 var f = _canonicalMember(obj, field); |
| 47 _trackCall(obj, f); | 47 _trackCall(obj); |
| 48 if (f != null) { | 48 if (f != null) { |
| 49 return JS('', '#[#] = #', obj, f, value); | 49 return JS('', '#[#] = #', obj, f, value); |
| 50 } | 50 } |
| 51 return noSuchMethod(obj, | 51 return noSuchMethod(obj, |
| 52 new InvocationImpl(field, JS('', '[#]', value), isSetter: true)); | 52 new InvocationImpl(field, JS('', '[#]', value), isSetter: true)); |
| 53 } | 53 } |
| 54 | 54 |
| 55 /// Check that a function of a given type can be applied to | 55 /// Check that a function of a given type can be applied to |
| 56 /// actuals. | 56 /// actuals. |
| 57 _checkApply(type, actuals) => JS('', '''(() => { | 57 _checkApply(type, actuals) => JS('', '''(() => { |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 99 var last = JS('', '#[#.length - 1]', args, args); | 99 var last = JS('', '#[#.length - 1]', args, args); |
| 100 if (JS('bool', '# != null && #.__proto__ === Object.prototype', | 100 if (JS('bool', '# != null && #.__proto__ === Object.prototype', |
| 101 last, last)) { | 101 last, last)) { |
| 102 return JS('', '#.pop()', args); | 102 return JS('', '#.pop()', args); |
| 103 } | 103 } |
| 104 } | 104 } |
| 105 return null; | 105 return null; |
| 106 } | 106 } |
| 107 | 107 |
| 108 _checkAndCall(f, ftype, obj, typeArgs, args, name) => JS('', '''(() => { | 108 _checkAndCall(f, ftype, obj, typeArgs, args, name) => JS('', '''(() => { |
| 109 $_trackCall($obj, $name); | 109 $_trackCall($obj); |
| 110 | 110 |
| 111 let originalTarget = obj === void 0 ? f : obj; | 111 let originalTarget = obj === void 0 ? f : obj; |
| 112 | 112 |
| 113 function callNSM() { | 113 function callNSM() { |
| 114 return $noSuchMethod(originalTarget, new $InvocationImpl( | 114 return $noSuchMethod(originalTarget, new $InvocationImpl( |
| 115 $name, $args, | 115 $name, $args, |
| 116 {namedArguments: $extractNamedArgs($args), isMethod: true})); | 116 {namedArguments: $extractNamedArgs($args), isMethod: true})); |
| 117 } | 117 } |
| 118 if (!($f instanceof Function)) { | 118 if (!($f instanceof Function)) { |
| 119 // We're not a function (and hence not a method either) | 119 // We're not a function (and hence not a method either) |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 175 // TODO(jmesserly): nSM should include type args? | 175 // TODO(jmesserly): nSM should include type args? |
| 176 return callNSM(); | 176 return callNSM(); |
| 177 })()'''); | 177 })()'''); |
| 178 | 178 |
| 179 dcall(f, @rest args) => _checkAndCall( | 179 dcall(f, @rest args) => _checkAndCall( |
| 180 f, _getRuntimeType(f), JS('', 'void 0'), null, args, 'call'); | 180 f, _getRuntimeType(f), JS('', 'void 0'), null, args, 'call'); |
| 181 | 181 |
| 182 dgcall(f, typeArgs, @rest args) => _checkAndCall( | 182 dgcall(f, typeArgs, @rest args) => _checkAndCall( |
| 183 f, _getRuntimeType(f), JS('', 'void 0'), typeArgs, args, 'call'); | 183 f, _getRuntimeType(f), JS('', 'void 0'), typeArgs, args, 'call'); |
| 184 | 184 |
| 185 Map<String, int> _callMethodStats = new Map(); | 185 class _MethodStats { |
| 186 final String typeName; | |
| 187 final String frame; | |
| 188 int count; | |
| 189 | |
| 190 _MethodStats(this.typeName, this.frame) { | |
| 191 count = 0; | |
| 192 } | |
| 193 } | |
| 194 | |
| 195 Map<String, _MethodStats> _callMethodStats = new Map(); | |
| 186 | 196 |
| 187 List<List<Object>> getDynamicStats() { | 197 List<List<Object>> getDynamicStats() { |
| 188 List<List<Object>> ret = []; | 198 List<List<Object>> ret = []; |
| 189 | 199 |
| 190 var keys = _callMethodStats.keys.toList(); | 200 var keys = _callMethodStats.keys.toList(); |
| 191 | 201 |
| 192 keys.sort((a, b) => _callMethodStats[b].compareTo(_callMethodStats[a])); | 202 keys.sort((a, b) => _callMethodStats[b].count.compareTo(_callMethodStats[a].co unt)); |
|
Jennifer Messerly
2016/09/06 16:34:29
long line
(we sadly can't auto format these files
Jacob
2016/09/06 16:37:02
Done.
| |
| 193 for (var key in keys) { | 203 for (var key in keys) { |
| 194 int count = _callMethodStats[key]; | 204 var stats = _callMethodStats[key]; |
| 195 ret.add([key, count]); | 205 ret.add([stats.typeName, stats.frame, stats.count]); |
| 196 } | 206 } |
| 197 | 207 |
| 198 return ret; | 208 return ret; |
| 199 } | 209 } |
| 200 | 210 |
| 201 clearDynamicStats() { | 211 clearDynamicStats() { |
| 202 _callMethodStats.clear(); | 212 _callMethodStats.clear(); |
| 203 } | 213 } |
| 204 | 214 |
| 205 bool trackProfile = JS('bool', 'dart.global.trackDdcProfile'); | 215 bool trackProfile = JS('bool', 'dart.global.trackDdcProfile'); |
| 206 | 216 |
| 207 _trackCall(obj, name) { | 217 _trackCall(obj) { |
| 208 if (JS('bool', '!#', trackProfile)) return; | 218 if (JS('bool', '!#', trackProfile)) return; |
| 209 | 219 |
| 210 var actual = getReifiedType(obj); | 220 var actual = getReifiedType(obj); |
| 211 String stackStr = JS('String', "new Error().stack"); | 221 String stackStr = JS('String', "new Error().stack"); |
| 212 var stack = stackStr.split('\n at '); | 222 var stack = stackStr.split('\n at '); |
| 213 var src = ''; | 223 var src = ''; |
| 214 for (int i = 2; i < stack.length; ++i) { | 224 for (int i = 2; i < stack.length; ++i) { |
| 215 var frame = stack[i]; | 225 var frame = stack[i]; |
| 216 if (!frame.contains('dart_sdk.js')) { | 226 if (!frame.contains('dart_sdk.js')) { |
| 217 src = frame; | 227 src = frame; |
| 218 break; | 228 break; |
| 219 } | 229 } |
| 220 } | 230 } |
| 221 | 231 |
| 222 name = "${typeName(actual)}.$name <$src>"; | 232 var actualTypeName = typeName(actual); |
| 223 if (_callMethodStats.containsKey(name)) { | 233 _callMethodStats.putIfAbsent("$actualTypeName <$src>", |
| 224 _callMethodStats[name] = _callMethodStats[name] + 1; | 234 () => new _MethodStats(actualTypeName, src)).count++; |
| 225 } else { | |
| 226 _callMethodStats[name] = 1; | |
| 227 } | |
| 228 } | 235 } |
| 229 | 236 |
| 230 /// Shared code for dsend, dindex, and dsetindex. | 237 /// Shared code for dsend, dindex, and dsetindex. |
| 231 _callMethod(obj, name, typeArgs, args, displayName) { | 238 _callMethod(obj, name, typeArgs, args, displayName) { |
| 232 var symbol = _canonicalMember(obj, name); | 239 var symbol = _canonicalMember(obj, name); |
| 233 if (symbol == null) { | 240 if (symbol == null) { |
| 234 return noSuchMethod(obj, | 241 return noSuchMethod(obj, |
| 235 new InvocationImpl(displayName, args, isMethod: true)); | 242 new InvocationImpl(displayName, args, isMethod: true)); |
| 236 } | 243 } |
| 237 var f = obj != null ? JS('', '#[#]', obj, symbol) : null; | 244 var f = obj != null ? JS('', '#[#]', obj, symbol) : null; |
| (...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 733 if (obj != null && getExtensionType(obj) != null) { | 740 if (obj != null && getExtensionType(obj) != null) { |
| 734 return JS('', 'dartx.#', name); | 741 return JS('', 'dartx.#', name); |
| 735 } | 742 } |
| 736 | 743 |
| 737 // Check for certain names that we can't use in JS | 744 // Check for certain names that we can't use in JS |
| 738 if (name == 'constructor' || name == 'prototype') { | 745 if (name == 'constructor' || name == 'prototype') { |
| 739 name = '+' + name; | 746 name = '+' + name; |
| 740 } | 747 } |
| 741 return name; | 748 return name; |
| 742 } | 749 } |
| OLD | NEW |