OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 // VM-specific implementation of the dart:mirrors library. | 5 // VM-specific implementation of the dart:mirrors library. |
6 | 6 |
7 import "dart:collection" show UnmodifiableListView, UnmodifiableMapView; | 7 import "dart:collection" show UnmodifiableListView, UnmodifiableMapView; |
8 import "dart:_internal" show LRUMap; | 8 import "dart:_internal" show Cache; |
9 | 9 |
10 final emptyList = new UnmodifiableListView([]); | 10 final emptyList = new UnmodifiableListView([]); |
11 final emptyMap = new UnmodifiableMapView({}); | 11 final emptyMap = new UnmodifiableMapView({}); |
12 | 12 |
13 class _InternalMirrorError { | 13 class _InternalMirrorError { |
14 final String _msg; | 14 final String _msg; |
15 const _InternalMirrorError(String this._msg); | 15 const _InternalMirrorError(String this._msg); |
16 String toString() => _msg; | 16 String toString() => _msg; |
17 } | 17 } |
18 | 18 |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
292 return other is _LocalInstanceMirror && | 292 return other is _LocalInstanceMirror && |
293 identical(_reflectee, other._reflectee); | 293 identical(_reflectee, other._reflectee); |
294 } | 294 } |
295 | 295 |
296 int get hashCode { | 296 int get hashCode { |
297 // Avoid hash collisions with the reflectee. This constant is in Smi range | 297 // Avoid hash collisions with the reflectee. This constant is in Smi range |
298 // and happens to be the inner padding from RFC 2104. | 298 // and happens to be the inner padding from RFC 2104. |
299 return identityHashCode(_reflectee) ^ 0x36363636; | 299 return identityHashCode(_reflectee) ^ 0x36363636; |
300 } | 300 } |
301 | 301 |
302 static var _getFieldClosures = new LRUMap.withShift(9); | 302 static var _getFieldClosures = new Cache.withInitialShift(4); |
303 static var _setFieldClosures = new LRUMap.withShift(9); | 303 static var _setFieldClosures = new Cache.withInitialShift(4); |
304 static var _getFieldCallCounts = new LRUMap.withShift(10); | 304 |
305 static var _setFieldCallCounts = new LRUMap.withShift(10); | 305 _createGetterClosure(unwrapped) { |
306 static const _closureThreshold = 20; | 306 var atPosition = unwrapped.indexOf('@'); |
307 if (atPosition == -1) { | |
308 // Public symbol. | |
309 return _eval('(x) => x.$unwrapped', null); | |
310 } else { | |
311 // Private symbol. | |
312 var withoutKey = unwrapped.substring(0, atPosition); | |
313 var privateKey = unwrapped.substring(atPosition); | |
314 return _eval('(x) => x.$withoutKey', privateKey); | |
315 } | |
316 } | |
307 | 317 |
308 _getFieldSlow(unwrapped) { | 318 _getFieldSlow(unwrapped) { |
309 // Slow path factored out to give the fast path a better chance at being | 319 // Slow path factored out to give the fast path a better chance at being |
310 // inlined. | 320 // inlined. |
311 var callCount = _getFieldCallCounts[unwrapped]; | |
312 if (callCount == null) { | |
313 callCount = 0; | |
314 } | |
315 if (callCount == _closureThreshold) { | |
316 // We've seen a successful setter invocation a few times: time to invest | |
317 // in a closure. | |
318 var f; | |
319 var atPosition = unwrapped.indexOf('@'); | |
320 if (atPosition == -1) { | |
321 // Public symbol. | |
322 f = _eval('(x) => x.$unwrapped', null); | |
323 } else { | |
324 // Private symbol. | |
325 var withoutKey = unwrapped.substring(0, atPosition); | |
326 var privateKey = unwrapped.substring(atPosition); | |
327 f = _eval('(x) => x.$withoutKey', privateKey); | |
328 } | |
329 _getFieldClosures[unwrapped] = f; | |
330 return reflect(f(_reflectee)); | |
331 } | |
332 var result = reflect(_invokeGetter(_reflectee, unwrapped)); | 321 var result = reflect(_invokeGetter(_reflectee, unwrapped)); |
333 // Only update call count if we don't throw to avoid creating closures for | 322 // Wait until success to avoid creating closures for non-existent getters. |
334 // non-existent getters. | 323 _getFieldClosures[unwrapped] = (r) { |
335 _getFieldCallCounts[unwrapped] = callCount + 1; | 324 return (_getFieldClosures[unwrapped] = _createGetterClosure(unwrapped))(r) ; |
Ivan Posva
2014/08/06 23:05:14
Long line?
| |
325 }; | |
336 return result; | 326 return result; |
337 } | 327 } |
338 | 328 |
339 InstanceMirror getField(Symbol memberName) { | 329 InstanceMirror getField(Symbol memberName) { |
340 var unwrapped = _n(memberName); | 330 var unwrapped = _n(memberName); |
341 var f = _getFieldClosures[unwrapped]; | 331 var f = _getFieldClosures[unwrapped]; |
342 return (f == null) ? _getFieldSlow(unwrapped) : reflect(f(_reflectee)); | 332 return (f == null) ? _getFieldSlow(unwrapped) : reflect(f(_reflectee)); |
343 } | 333 } |
344 | 334 |
335 _createSetterClosure(unwrapped) { | |
336 var atPosition = unwrapped.indexOf('@'); | |
337 if (atPosition == -1) { | |
338 // Public symbol. | |
339 return _eval('(x, v) => x.$unwrapped = v', null); | |
340 } else { | |
341 // Private symbol. | |
342 var withoutKey = unwrapped.substring(0, atPosition); | |
343 var privateKey = unwrapped.substring(atPosition); | |
344 return _eval('(x, v) => x.$withoutKey = v', privateKey); | |
345 } | |
346 } | |
347 | |
345 _setFieldSlow(unwrapped, arg) { | 348 _setFieldSlow(unwrapped, arg) { |
346 // Slow path factored out to give the fast path a better chance at being | 349 // Slow path factored out to give the fast path a better chance at being |
347 // inlined. | 350 // inlined. |
348 var callCount = _setFieldCallCounts[unwrapped]; | |
349 if (callCount == null) { | |
350 callCount = 0; | |
351 } | |
352 if (callCount == _closureThreshold) { | |
353 // We've seen a successful getter invocation a few times: time to invest | |
354 // in a closure. | |
355 var f; | |
356 var atPosition = unwrapped.indexOf('@'); | |
357 if (atPosition == -1) { | |
358 // Public symbol. | |
359 f = _eval('(x, v) => x.$unwrapped = v', null); | |
360 } else { | |
361 // Private symbol. | |
362 var withoutKey = unwrapped.substring(0, atPosition); | |
363 var privateKey = unwrapped.substring(atPosition); | |
364 f = _eval('(x, v) => x.$withoutKey = v', privateKey); | |
365 } | |
366 _setFieldClosures[unwrapped] = f; | |
367 return reflect(f(_reflectee, arg)); | |
368 } | |
369 _invokeSetter(_reflectee, unwrapped, arg); | 351 _invokeSetter(_reflectee, unwrapped, arg); |
370 var result = reflect(arg); | 352 var result = reflect(arg); |
371 // Only update call count if we don't throw to avoid creating closures for | 353 // Wait until success to avoid creating closures for non-existent setters. |
372 // non-existent setters. | 354 _setFieldClosures[unwrapped] = (r, v) { |
373 _setFieldCallCounts[unwrapped] = callCount + 1; | 355 return (_setFieldClosures[unwrapped] = _createSetterClosure(unwrapped))(r, v); |
356 }; | |
374 return result; | 357 return result; |
375 } | 358 } |
376 | 359 |
377 InstanceMirror setField(Symbol memberName, arg) { | 360 InstanceMirror setField(Symbol memberName, arg) { |
378 var unwrapped = _n(memberName); | 361 var unwrapped = _n(memberName); |
379 var f = _setFieldClosures[unwrapped]; | 362 var f = _setFieldClosures[unwrapped]; |
380 return (f == null) | 363 return (f == null) |
381 ? _setFieldSlow(unwrapped, arg) | 364 ? _setFieldSlow(unwrapped, arg) |
382 : reflect(f(_reflectee, arg)); | 365 : reflect(f(_reflectee, arg)); |
383 } | 366 } |
(...skipping 1185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1569 if (typeMirror == null) { | 1552 if (typeMirror == null) { |
1570 typeMirror = makeLocalTypeMirror(key); | 1553 typeMirror = makeLocalTypeMirror(key); |
1571 _instanitationCache[key] = typeMirror; | 1554 _instanitationCache[key] = typeMirror; |
1572 if (typeMirror is ClassMirror && !typeMirror._isGeneric) { | 1555 if (typeMirror is ClassMirror && !typeMirror._isGeneric) { |
1573 _declarationCache[key] = typeMirror; | 1556 _declarationCache[key] = typeMirror; |
1574 } | 1557 } |
1575 } | 1558 } |
1576 return typeMirror; | 1559 return typeMirror; |
1577 } | 1560 } |
1578 } | 1561 } |
OLD | NEW |