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 |