Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(85)

Side by Side Diff: pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart

Issue 3002393002: optimize extension member symbols in DDC, issue #30531 (Closed)
Patch Set: small tweak Created 3 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/dev_compiler/lib/src/compiler/code_generator.dart ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 the operations that define and manipulate Dart 5 /// This library defines the operations that define and manipulate Dart
6 /// classes. Included in this are: 6 /// classes. Included in this are:
7 /// - Generics 7 /// - Generics
8 /// - Class metadata 8 /// - Class metadata
9 /// - Extension methods 9 /// - Extension methods
10 /// 10 ///
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
384 bool hasSetter(type, name) => _hasSigEntry(type, _setterSig, name); 384 bool hasSetter(type, name) => _hasSigEntry(type, _setterSig, name);
385 bool hasField(type, name) => _hasSigEntry(type, _fieldSig, name); 385 bool hasField(type, name) => _hasSigEntry(type, _fieldSig, name);
386 386
387 final _extensionType = JS('', 'Symbol("extensionType")'); 387 final _extensionType = JS('', 'Symbol("extensionType")');
388 388
389 /// This assumes that obj is not null 389 /// This assumes that obj is not null
390 getExtensionType(obj) => JS('', '#[#]', obj, _extensionType); 390 getExtensionType(obj) => JS('', '#[#]', obj, _extensionType);
391 391
392 final dartx = JS('', 'dartx'); 392 final dartx = JS('', 'dartx');
393 393
394 getExtensionSymbol(name) {
395 var sym = JS('', 'dartx[#]', name);
396 if (sym == null) {
397 sym = JS('', 'Symbol("dartx." + #.toString())', name);
398 JS('', 'dartx[#] = #', name, sym);
399 }
400 return sym;
401 }
402
403 defineExtensionNames(names) =>
404 JS('', '#.forEach(#)', names, getExtensionSymbol);
405
406 /// Install properties in prototype-first order. Properties / descriptors from 394 /// Install properties in prototype-first order. Properties / descriptors from
407 /// more specific types should overwrite ones from less specific types. 395 /// more specific types should overwrite ones from less specific types.
408 void _installProperties(jsProto, dartType, installedParent) { 396 void _installProperties(jsProto, dartType, installedParent) {
409 if (JS('bool', '# === #', dartType, Object)) { 397 if (JS('bool', '# === #', dartType, Object)) {
410 _installPropertiesForObject(jsProto); 398 _installPropertiesForObject(jsProto);
411 return; 399 return;
412 } 400 }
413 // If the extension methods of the parent have been installed on the parent 401 // If the extension methods of the parent have been installed on the parent
414 // of [jsProto], the methods will be available via prototype inheritance. 402 // of [jsProto], the methods will be available via prototype inheritance.
415 var dartSupertype = JS('', '#.__proto__', dartType); 403 var dartSupertype = JS('', '#.__proto__', dartType);
416 if (JS('bool', '# !== #', dartSupertype, installedParent)) { 404 if (JS('bool', '# !== #', dartSupertype, installedParent)) {
417 _installProperties(jsProto, dartSupertype, installedParent); 405 _installProperties(jsProto, dartSupertype, installedParent);
418 } 406 }
419 407
420 var dartProto = JS('', '#.prototype', dartType); 408 var dartProto = JS('', '#.prototype', dartType);
421 copyTheseProperties(jsProto, dartProto, getOwnPropertySymbols(dartProto)); 409 copyTheseProperties(jsProto, dartProto, getOwnPropertySymbols(dartProto));
422 } 410 }
423 411
424 void _installPropertiesForObject(jsProto) { 412 void _installPropertiesForObject(jsProto) {
425 // core.Object members need to be copied from the non-symbol name to the 413 // core.Object members need to be copied from the non-symbol name to the
426 // symbol name. 414 // symbol name.
427 var coreObjProto = JS('', '#.prototype', Object); 415 var coreObjProto = JS('', '#.prototype', Object);
428 var names = getOwnPropertyNames(coreObjProto); 416 var names = getOwnPropertyNames(coreObjProto);
429 for (int i = 0; i < JS('int', '#.length', names); ++i) { 417 for (int i = 0; i < JS('int', '#.length', names); ++i) {
430 var name = JS('', '#[#]', names, i); 418 var name = JS('', '#[#]', names, i);
431 var desc = getOwnPropertyDescriptor(coreObjProto, name); 419 var desc = getOwnPropertyDescriptor(coreObjProto, name);
432 defineProperty(jsProto, getExtensionSymbol(name), desc); 420 defineProperty(jsProto, JS('', '#.#', dartx, name), desc);
433 } 421 }
434 } 422 }
435 423
436 final _extensionMap = JS('', 'new Map()'); 424 final _extensionMap = JS('', 'new Map()');
437 425
438 _applyExtension(jsType, dartExtType) => JS('', '''(() => { 426 _applyExtension(jsType, dartExtType) => JS('', '''(() => {
439 // TODO(vsm): Not all registered js types are real. 427 // TODO(vsm): Not all registered js types are real.
440 if (!$jsType) return; 428 if (!$jsType) return;
441 429
442 let jsProto = $jsType.prototype; 430 let jsProto = $jsType.prototype;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 /// MyType.prototype[dartx.remove] = MyType.prototype.remove; 482 /// MyType.prototype[dartx.remove] = MyType.prototype.remove;
495 /// 483 ///
496 // TODO(jmesserly): essentially this gives two names to the same method. 484 // TODO(jmesserly): essentially this gives two names to the same method.
497 // This benefit is roughly equivalent call performance either way, but the 485 // This benefit is roughly equivalent call performance either way, but the
498 // cost is we need to call defineExtensionMembers any time a subclass 486 // cost is we need to call defineExtensionMembers any time a subclass
499 // overrides one of these methods. 487 // overrides one of these methods.
500 defineExtensionMembers(type, methodNames) => JS('', '''(() => { 488 defineExtensionMembers(type, methodNames) => JS('', '''(() => {
501 let proto = $type.prototype; 489 let proto = $type.prototype;
502 for (let name of $methodNames) { 490 for (let name of $methodNames) {
503 let method = $getOwnPropertyDescriptor(proto, name); 491 let method = $getOwnPropertyDescriptor(proto, name);
504 $defineProperty(proto, $getExtensionSymbol(name), method); 492 $defineProperty(proto, $dartx[name], method);
505 } 493 }
506 // Ensure the signature is available too. 494 // Ensure the signature is available too.
507 // TODO(jmesserly): not sure if we can do this in a cleaner way. Essentially 495 // TODO(jmesserly): not sure if we can do this in a cleaner way. Essentially
508 // we need to copy the signature (and in the future, other data like 496 // we need to copy the signature (and in the future, other data like
509 // annotations) any time we copy a method as part of our metaprogramming. 497 // annotations) any time we copy a method as part of our metaprogramming.
510 // It might be more friendly to JS metaprogramming if we include this info 498 // It might be more friendly to JS metaprogramming if we include this info
511 // on the function. 499 // on the function.
512 500
513 function upgradeSig(sigF) { 501 function upgradeSig(sigF) {
514 let originalSigDesc = $getOwnPropertyDescriptor($type, sigF); 502 let originalSigDesc = $getOwnPropertyDescriptor($type, sigF);
515 if (originalSigDesc === void 0) return; 503 if (originalSigDesc === void 0) return;
516 let originalSigFn = originalSigDesc.get; 504 let originalSigFn = originalSigDesc.get;
517 $defineMemoizedGetter(type, sigF, function() { 505 $defineMemoizedGetter(type, sigF, function() {
518 let sig = originalSigFn(); 506 let sig = originalSigFn();
519 let propertyNames = Object.getOwnPropertyNames(sig); 507 let propertyNames = Object.getOwnPropertyNames(sig);
520 for (let name of methodNames) { 508 for (let name of methodNames) {
521 if (name in sig) { 509 if (name in sig) {
522 sig[$getExtensionSymbol(name)] = sig[name]; 510 sig[$dartx[name]] = sig[name];
523 } 511 }
524 } 512 }
525 return sig; 513 return sig;
526 }); 514 });
527 }; 515 };
528 upgradeSig($_methodSig); 516 upgradeSig($_methodSig);
529 upgradeSig($_fieldSig); 517 upgradeSig($_fieldSig);
530 upgradeSig($_getterSig); 518 upgradeSig($_getterSig);
531 upgradeSig($_setterSig); 519 upgradeSig($_setterSig);
532 })()'''); 520 })()''');
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 final isList = JS('', 'Symbol("_is_List")'); 606 final isList = JS('', 'Symbol("_is_List")');
619 607
620 /// The well known symbol for testing `is Map` 608 /// The well known symbol for testing `is Map`
621 final isMap = JS('', 'Symbol("_is_Map")'); 609 final isMap = JS('', 'Symbol("_is_Map")');
622 610
623 /// The well known symbol for testing `is Stream` 611 /// The well known symbol for testing `is Stream`
624 final isStream = JS('', 'Symbol("_is_Stream")'); 612 final isStream = JS('', 'Symbol("_is_Stream")');
625 613
626 /// The well known symbol for testing `is StreamSubscription` 614 /// The well known symbol for testing `is StreamSubscription`
627 final isStreamSubscription = JS('', 'Symbol("_is_StreamSubscription")'); 615 final isStreamSubscription = JS('', 'Symbol("_is_StreamSubscription")');
OLDNEW
« no previous file with comments | « pkg/dev_compiler/lib/src/compiler/code_generator.dart ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698