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 _canonicalFieldName(obj, name, args, displayName) => JS('', '''(() => { | 9 _canonicalFieldName(obj, name, args, displayName) => JS('', '''(() => { |
| 10 $name = $canonicalMember($obj, $name); | 10 $name = $canonicalMember($obj, $name); |
| 11 if ($name) return $name; | 11 if ($name) return $name; |
| 12 // TODO(jmesserly): in the future we might have types that "overlay" Dart | 12 // TODO(jmesserly): in the future we might have types that "overlay" Dart |
| 13 // methods while also exposing the full native API, e.g. dart:html vs | 13 // methods while also exposing the full native API, e.g. dart:html vs |
| 14 // dart:dom. To support that we'd need to fall back to the normal name | 14 // dart:dom. To support that we'd need to fall back to the normal name |
| 15 // if an extension method wasn't found. | 15 // if an extension method wasn't found. |
| 16 $throwNoSuchMethodFunc($obj, $displayName, $args); | 16 $throwNoSuchMethodFunc($obj, $displayName, $args); |
| 17 })()'''); | 17 })()'''); |
| 18 | 18 |
| 19 dload(obj, field) => JS('', '''(() => { | 19 dload(obj, field) => JS('', '''(() => { |
| 20 $_trackCall(obj, $field, null); | |
| 20 $field = $_canonicalFieldName($obj, $field, [], $field); | 21 $field = $_canonicalFieldName($obj, $field, [], $field); |
| 21 if ($hasMethod($obj, $field)) { | 22 if ($hasMethod($obj, $field)) { |
| 22 return $bind($obj, $field); | 23 return $bind($obj, $field); |
| 23 } | 24 } |
| 24 // TODO(vsm): Implement NSM robustly. An 'in' check breaks on certain | 25 // TODO(vsm): Implement NSM robustly. An 'in' check breaks on certain |
| 25 // types. hasOwnProperty doesn't chase the proto chain. | 26 // types. hasOwnProperty doesn't chase the proto chain. |
| 26 // Also, do we want an NSM on regular JS objects? | 27 // Also, do we want an NSM on regular JS objects? |
| 27 // See: https://github.com/dart-lang/dev_compiler/issues/169 | 28 // See: https://github.com/dart-lang/dev_compiler/issues/169 |
| 28 let result = $obj[$field]; | 29 let result = $obj[$field]; |
| 29 return result; | 30 return result; |
| 30 })()'''); | 31 })()'''); |
| 31 | 32 |
| 32 dput(obj, field, value) => JS('', '''(() => { | 33 dput(obj, field, value) => JS('', '''(() => { |
| 33 $field = $_canonicalFieldName($obj, $field, [$value], $field); | 34 $field = $_canonicalFieldName($obj, $field, [$value], $field); |
| 35 $_trackCall(obj, $field, null); | |
| 36 | |
| 34 // TODO(vsm): Implement NSM and type checks. | 37 // TODO(vsm): Implement NSM and type checks. |
| 35 // See: https://github.com/dart-lang/dev_compiler/issues/170 | 38 // See: https://github.com/dart-lang/dev_compiler/issues/170 |
| 36 $obj[$field] = $value; | 39 $obj[$field] = $value; |
| 37 return $value; | 40 return $value; |
| 38 })()'''); | 41 })()'''); |
| 39 | 42 |
| 40 /// Check that a function of a given type can be applied to | 43 /// Check that a function of a given type can be applied to |
| 41 /// actuals. | 44 /// actuals. |
| 42 _checkApply(type, actuals) => JS('', '''(() => { | 45 _checkApply(type, actuals) => JS('', '''(() => { |
| 43 if ($actuals.length < $type.args.length) return false; | 46 if ($actuals.length < $type.args.length) return false; |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 81 throwNoSuchMethod(obj, name, pArgs, nArgs, extras) => JS('', '''(() => { | 84 throwNoSuchMethod(obj, name, pArgs, nArgs, extras) => JS('', '''(() => { |
| 82 $throw_(new $NoSuchMethodError($obj, $_dartSymbol($name), $pArgs, $nArgs, $ext ras)); | 85 $throw_(new $NoSuchMethodError($obj, $_dartSymbol($name), $pArgs, $nArgs, $ext ras)); |
| 83 })()'''); | 86 })()'''); |
| 84 | 87 |
| 85 throwNoSuchMethodFunc(obj, name, pArgs, opt_func) => JS('', '''(() => { | 88 throwNoSuchMethodFunc(obj, name, pArgs, opt_func) => JS('', '''(() => { |
| 86 if ($obj === void 0) $obj = $opt_func; | 89 if ($obj === void 0) $obj = $opt_func; |
| 87 $throwNoSuchMethod($obj, $name, $pArgs); | 90 $throwNoSuchMethod($obj, $name, $pArgs); |
| 88 })()'''); | 91 })()'''); |
| 89 | 92 |
| 90 _checkAndCall(f, ftype, obj, typeArgs, args, name) => JS('', '''(() => { | 93 _checkAndCall(f, ftype, obj, typeArgs, args, name) => JS('', '''(() => { |
| 94 $_trackCall(obj, name, f.toString()); | |
| 95 | |
| 91 let originalFunction = $f; | 96 let originalFunction = $f; |
| 92 if (!($f instanceof Function)) { | 97 if (!($f instanceof Function)) { |
| 93 // We're not a function (and hence not a method either) | 98 // We're not a function (and hence not a method either) |
| 94 // Grab the `call` method if it's not a function. | 99 // Grab the `call` method if it's not a function. |
| 95 if ($f != null) { | 100 if ($f != null) { |
| 96 $ftype = $getMethodType($f, 'call'); | 101 $ftype = $getMethodType($f, 'call'); |
| 97 $f = $f.call; | 102 $f = $f.call; |
| 98 } | 103 } |
| 99 if (!($f instanceof Function)) { | 104 if (!($f instanceof Function)) { |
| 100 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction); | 105 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction); |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 150 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction); | 155 $throwNoSuchMethodFunc($obj, $name, $args, originalFunction); |
| 151 })()'''); | 156 })()'''); |
| 152 | 157 |
| 153 dcall(f, @rest args) => _checkAndCall( | 158 dcall(f, @rest args) => _checkAndCall( |
| 154 f, _getRuntimeType(f), JS('', 'void 0'), null, args, 'call'); | 159 f, _getRuntimeType(f), JS('', 'void 0'), null, args, 'call'); |
| 155 | 160 |
| 156 | 161 |
| 157 dgcall(f, typeArgs, @rest args) => _checkAndCall( | 162 dgcall(f, typeArgs, @rest args) => _checkAndCall( |
| 158 f, _getRuntimeType(f), JS('', 'void 0'), typeArgs, args, 'call'); | 163 f, _getRuntimeType(f), JS('', 'void 0'), typeArgs, args, 'call'); |
| 159 | 164 |
| 165 Map<String, int> _callMethodStats = new Map(); | |
| 166 | |
| 167 class ProfileEntry { | |
| 168 final String key; | |
| 169 final num count; | |
| 170 | |
| 171 ProfileEntry(this.key, this.count); | |
| 172 } | |
| 173 | |
| 174 dumpDynamicStats() { | |
|
Jacob
2016/06/01 20:48:20
rename dumpDynamicStats()
to
List<ProfileEntry> g
priscillalee
2016/06/01 21:03:33
Done.
| |
| 175 List<ProfileEntry> ret = new List(); | |
| 176 | |
| 177 var keys = _callMethodStats.keys.toList(); | |
| 178 | |
| 179 keys.sort((a, b) => _callMethodStats[b].compareTo(_callMethodStats[a])); | |
| 180 for (var key in keys) { | |
| 181 int count = _callMethodStats[key]; | |
| 182 ret.add(new ProfileEntry(key, count)); | |
| 183 } | |
| 184 | |
| 185 return ret; | |
| 186 } | |
| 187 | |
| 188 clearDynamicStats() { | |
| 189 _callMethodStats.clear(); | |
| 190 } | |
| 191 | |
| 192 bool _trackProfile = false; | |
| 193 | |
| 194 set trackProfile(bool value) { | |
| 195 _trackProfile = value; | |
| 196 } | |
| 197 | |
| 198 get trackProfile => _trackProfile; | |
| 199 | |
| 200 _trackCall(obj, name, displayName) { | |
| 201 if (!_trackProfile) return; | |
| 202 | |
| 203 var actual = getReifiedType(obj); | |
| 204 String stackStr = JS('String', "new Error().stack"); | |
| 205 var stack = stackStr.split('\n at '); | |
| 206 String src = ''; | |
|
Jacob
2016/06/01 20:48:20
nit: change String to var
priscillalee
2016/06/01 21:03:33
Done.
| |
| 207 for (int i = 2; i < stack.length; ++i) { | |
| 208 var frame = stack[i]; | |
| 209 if (!frame.contains('dev_compiler/lib/runtime/dart_sdk.js')) { | |
| 210 src = frame; | |
| 211 break; | |
| 212 } | |
| 213 } | |
| 214 | |
| 215 name = "${typeName(actual)}.$name <$src>"; | |
| 216 if (_callMethodStats.containsKey(name)) { | |
| 217 _callMethodStats[name] = _callMethodStats[name] + 1; | |
| 218 } else { | |
| 219 _callMethodStats[name] = 1; | |
| 220 } | |
| 221 } | |
| 160 | 222 |
| 161 /// Shared code for dsend, dindex, and dsetindex. | 223 /// Shared code for dsend, dindex, and dsetindex. |
| 162 _callMethod(obj, name, typeArgs, args, displayName) { | 224 _callMethod(obj, name, typeArgs, args, displayName) { |
| 225 _trackCall(obj, name, displayName); | |
| 163 var symbol = _canonicalFieldName(obj, name, args, displayName); | 226 var symbol = _canonicalFieldName(obj, name, args, displayName); |
| 164 var f = obj != null ? JS('', '#[#]', obj, symbol) : null; | 227 var f = obj != null ? JS('', '#[#]', obj, symbol) : null; |
| 165 var ftype = getMethodType(obj, symbol); | 228 var ftype = getMethodType(obj, symbol); |
| 166 return _checkAndCall(f, ftype, obj, typeArgs, args, displayName); | 229 return _checkAndCall(f, ftype, obj, typeArgs, args, displayName); |
| 167 } | 230 } |
| 168 | 231 |
| 169 dsend(obj, method, @rest args) => _callMethod(obj, method, null, args, method); | 232 dsend(obj, method, @rest args) => _callMethod(obj, method, null, args, method); |
| 170 | 233 |
| 171 dgsend(obj, typeArgs, method, @rest args) => | 234 dgsend(obj, typeArgs, method, @rest args) => |
| 172 _callMethod(obj, method, typeArgs, args, method); | 235 _callMethod(obj, method, typeArgs, args, method); |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 587 constructor(dartIterator) { | 650 constructor(dartIterator) { |
| 588 this.dartIterator = dartIterator; | 651 this.dartIterator = dartIterator; |
| 589 } | 652 } |
| 590 next() { | 653 next() { |
| 591 let i = this.dartIterator; | 654 let i = this.dartIterator; |
| 592 let done = !i.moveNext(); | 655 let done = !i.moveNext(); |
| 593 return { done: done, value: done ? void 0 : i.current }; | 656 return { done: done, value: done ? void 0 : i.current }; |
| 594 } | 657 } |
| 595 } | 658 } |
| 596 '''); | 659 '''); |
| OLD | NEW |