Chromium Code Reviews| 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"; | 7 import "dart:collection"; |
| 8 | 8 |
| 9 final emptyList = new UnmodifiableListView([]); | 9 final emptyList = new UnmodifiableListView([]); |
| 10 final emptyMap = new _UnmodifiableMapView({}); | 10 final emptyMap = new _UnmodifiableMapView({}); |
| (...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 325 } | 325 } |
| 326 } | 326 } |
| 327 if (!found) { | 327 if (!found) { |
| 328 throw new ArgumentError( | 328 throw new ArgumentError( |
| 329 "${MirrorSystem.getName(type.simpleName)} has no instance method " | 329 "${MirrorSystem.getName(type.simpleName)} has no instance method " |
| 330 "${MirrorSystem.getName(selector)}"); | 330 "${MirrorSystem.getName(selector)}"); |
| 331 } | 331 } |
| 332 return new _InvocationTrampoline(this, selector); | 332 return new _InvocationTrampoline(this, selector); |
| 333 } | 333 } |
| 334 | 334 |
| 335 // TODO(16539): Make these weak or soft. | |
| 336 static var _getFieldClosures = new HashMap(); | |
| 337 static var _setFieldClosures = new HashMap(); | |
| 338 static var _getFieldCallCounts = new HashMap(); | |
| 339 static var _setFieldCallCounts = new HashMap(); | |
| 340 | |
| 341 _getFieldSlow(unwrapped) { | |
| 342 // Slow path factored out to give the fast path a better chance at being | |
| 343 // inlined. | |
| 344 var callCount = _getFieldCallCounts[unwrapped]; | |
| 345 if (callCount == null) { | |
| 346 callCount = 0; | |
| 347 } | |
| 348 if (callCount == 20) { | |
|
Ivan Posva
2014/02/05 22:23:44
How about naming this arbitrary constant and pulli
rmacnak
2014/02/05 22:56:31
Done.
| |
| 349 // We've seen a success getter invocation a few times: time to invest in a | |
| 350 // closure. | |
| 351 var f; | |
| 352 var atPosition = unwrapped.indexOf('@'); | |
| 353 if (atPosition == -1) { | |
| 354 // Public symbol. | |
| 355 f = _eval('(x) => x.$unwrapped', null); | |
| 356 } else { | |
| 357 // Private symbol. | |
| 358 var withoutKey = unwrapped.substring(0, atPosition); | |
| 359 var privateKey = unwrapped.substring(atPosition); | |
| 360 f = _eval('(x) => x.$withoutKey', privateKey); | |
| 361 } | |
| 362 _getFieldClosures[unwrapped] = f; | |
| 363 _getFieldCallCounts.remove(unwrapped); // We won't look for this again. | |
| 364 return reflect(f(_reflectee)); | |
| 365 } | |
| 366 var result = reflect(_invokeGetter(_reflectee, unwrapped)); | |
| 367 // Only update call count if we don't throw to avoid creating closures for | |
| 368 // non-existent getters. | |
| 369 _getFieldCallCounts[unwrapped] = callCount + 1; | |
| 370 return result; | |
| 371 } | |
| 372 | |
| 373 InstanceMirror getField(Symbol memberName) { | |
| 374 var unwrapped = _n(memberName); | |
| 375 var f = _getFieldClosures[unwrapped]; | |
| 376 return (f == null) | |
|
Ivan Posva
2014/02/05 22:23:44
return (f == null) ?
_getFieldSlow(unwrapped
rmacnak
2014/02/05 22:56:31
Done.
| |
| 377 ? _getFieldSlow(unwrapped) | |
| 378 : reflect(f(_reflectee)); | |
| 379 } | |
| 380 | |
| 381 _setFieldSlow(unwrapped, arg) { | |
| 382 // Slow path factored out to give the fast path a better chance at being | |
| 383 // inlined. | |
| 384 var callCount = _setFieldCallCounts[unwrapped]; | |
| 385 if (callCount == null) { | |
| 386 callCount = 0; | |
| 387 } | |
| 388 if (callCount == 20) { | |
| 389 // We've seen a success getter invocation a few times: time to invest in a | |
| 390 // closure. | |
| 391 var f; | |
| 392 var atPosition = unwrapped.indexOf('@'); | |
| 393 if (atPosition == -1) { | |
| 394 // Public symbol. | |
| 395 f = _eval('(x, v) => x.$unwrapped = v', null); | |
| 396 } else { | |
| 397 // Private symbol. | |
| 398 var withoutKey = unwrapped.substring(0, atPosition); | |
| 399 var privateKey = unwrapped.substring(atPosition); | |
| 400 f = _eval('(x, v) => x.$withoutKey = v', privateKey); | |
| 401 } | |
| 402 _setFieldClosures[unwrapped] = f; | |
| 403 _setFieldCallCounts.remove(unwrapped); | |
| 404 return reflect(f(_reflectee, arg)); | |
| 405 } | |
| 406 _invokeSetter(_reflectee, unwrapped, arg); | |
| 407 var result = reflect(arg); | |
| 408 // Only update call count if we don't throw to avoid creating closures for | |
| 409 // non-existent setters. | |
| 410 _setFieldCallCounts[unwrapped] = callCount + 1; | |
| 411 return result; | |
| 412 } | |
| 413 | |
| 414 InstanceMirror setField(Symbol memberName, arg) { | |
| 415 var unwrapped = _n(memberName); | |
| 416 var f = _setFieldClosures[unwrapped]; | |
| 417 return (f == null) | |
| 418 ? _setFieldSlow(unwrapped, arg) | |
| 419 : reflect(f(_reflectee, arg)); | |
| 420 } | |
| 421 | |
| 422 static _eval(expression, privateKey) | |
| 423 native "Mirrors_evalInLibraryWithPrivateKey"; | |
| 424 | |
| 335 // Override to include the receiver in the arguments. | 425 // Override to include the receiver in the arguments. |
| 336 InstanceMirror invoke(Symbol memberName, | 426 InstanceMirror invoke(Symbol memberName, |
| 337 List positionalArguments, | 427 List positionalArguments, |
| 338 [Map<Symbol, dynamic> namedArguments]) { | 428 [Map<Symbol, dynamic> namedArguments]) { |
| 339 int numPositionalArguments = positionalArguments.length + 1; // Receiver. | 429 int numPositionalArguments = positionalArguments.length + 1; // Receiver. |
| 340 int numNamedArguments = namedArguments != null ? namedArguments.length : 0; | 430 int numNamedArguments = namedArguments != null ? namedArguments.length : 0; |
| 341 int numArguments = numPositionalArguments + numNamedArguments; | 431 int numArguments = numPositionalArguments + numNamedArguments; |
| 342 List arguments = new List(numArguments); | 432 List arguments = new List(numArguments); |
| 343 arguments[0] = _reflectee; // Receiver. | 433 arguments[0] = _reflectee; // Receiver. |
| 344 arguments.setRange(1, numPositionalArguments, positionalArguments); | 434 arguments.setRange(1, numPositionalArguments, positionalArguments); |
| (...skipping 1147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1492 if (typeMirror == null) { | 1582 if (typeMirror == null) { |
| 1493 typeMirror = makeLocalTypeMirror(key); | 1583 typeMirror = makeLocalTypeMirror(key); |
| 1494 _instanitationCache[key] = typeMirror; | 1584 _instanitationCache[key] = typeMirror; |
| 1495 if (typeMirror is ClassMirror && !typeMirror._isGeneric) { | 1585 if (typeMirror is ClassMirror && !typeMirror._isGeneric) { |
| 1496 _declarationCache[key] = typeMirror; | 1586 _declarationCache[key] = typeMirror; |
| 1497 } | 1587 } |
| 1498 } | 1588 } |
| 1499 return typeMirror; | 1589 return typeMirror; |
| 1500 } | 1590 } |
| 1501 } | 1591 } |
| OLD | NEW |