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

Side by Side Diff: runtime/vm/ast.cc

Issue 1320673012: Lookup getter/setter symbols before alllocating them, thus eliminating extra String allocations in … (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Formatting Created 5 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 | « runtime/lib/integers.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | 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) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, 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 #include "vm/ast.h" 5 #include "vm/ast.h"
6 #include "vm/compiler.h" 6 #include "vm/compiler.h"
7 #include "vm/dart_entry.h" 7 #include "vm/dart_entry.h"
8 #include "vm/isolate.h" 8 #include "vm/isolate.h"
9 #include "vm/object_store.h" 9 #include "vm/object_store.h"
10 #include "vm/resolver.h" 10 #include "vm/resolver.h"
(...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after
565 } 565 }
566 566
567 567
568 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) { 568 AstNode* StaticGetterNode::MakeAssignmentNode(AstNode* rhs) {
569 Thread* thread = Thread::Current(); 569 Thread* thread = Thread::Current();
570 Zone* zone = thread->zone(); 570 Zone* zone = thread->zone();
571 Isolate* isolate = thread->isolate(); 571 Isolate* isolate = thread->isolate();
572 if (is_super_getter()) { 572 if (is_super_getter()) {
573 ASSERT(receiver() != NULL); 573 ASSERT(receiver() != NULL);
574 const String& setter_name = 574 const String& setter_name =
575 String::ZoneHandle(zone, Field::SetterSymbol(field_name_)); 575 String::ZoneHandle(zone, Field::LookupSetterSymbol(field_name_));
576 Function& setter = Function::ZoneHandle(zone, 576 Function& setter = Function::ZoneHandle(zone);
577 Resolver::ResolveDynamicAnyArgs(cls(), setter_name)); 577 if (!setter_name.IsNull()) {
578 setter = Resolver::ResolveDynamicAnyArgs(cls(), setter_name);
579 }
578 if (setter.IsNull() || setter.is_abstract()) { 580 if (setter.IsNull() || setter.is_abstract()) {
579 // No instance setter found in super class chain, 581 // No instance setter found in super class chain,
580 // noSuchMethod will be called at runtime. 582 // noSuchMethod will be called at runtime.
581 return new StaticSetterNode(token_pos(), 583 return new StaticSetterNode(token_pos(),
582 receiver(), 584 receiver(),
583 cls(), 585 cls(),
584 field_name_, 586 field_name_,
585 rhs); 587 rhs);
586 } 588 }
587 return new StaticSetterNode(token_pos(), 589 return new StaticSetterNode(token_pos(),
(...skipping 23 matching lines...) Expand all
611 rhs = new AssignableNode(field.token_pos(), 613 rhs = new AssignableNode(field.token_pos(),
612 rhs, 614 rhs,
613 AbstractType::ZoneHandle(zone, field.type()), 615 AbstractType::ZoneHandle(zone, field.type()),
614 field_name_); 616 field_name_);
615 } 617 }
616 return new StoreStaticFieldNode(token_pos(), field, rhs); 618 return new StoreStaticFieldNode(token_pos(), field, rhs);
617 } 619 }
618 } 620 }
619 621
620 // No field found in prefix. Look for a setter function. 622 // No field found in prefix. Look for a setter function.
621 const String& setter_name = String::Handle(zone, 623 const String& setter_name =
622 Field::SetterName(field_name_)); 624 String::Handle(zone, Field::LookupSetterSymbol(field_name_));
623 obj = prefix.LookupObject(setter_name); 625 if (!setter_name.IsNull()) {
624 if (obj.IsFunction()) { 626 obj = prefix.LookupObject(setter_name);
625 const Function& setter = Function::ZoneHandle(zone, 627 if (obj.IsFunction()) {
626 Function::Cast(obj).raw()); 628 const Function& setter =
627 ASSERT(setter.is_static() && setter.IsSetterFunction()); 629 Function::ZoneHandle(zone, Function::Cast(obj).raw());
628 return new StaticSetterNode( 630 ASSERT(setter.is_static() && setter.IsSetterFunction());
629 token_pos(), NULL, field_name_, setter, rhs); 631 return new StaticSetterNode(
632 token_pos(), NULL, field_name_, setter, rhs);
633 }
630 } 634 }
631 635
632 // No writeable field and no setter found in the prefix. Return a 636 // No writeable field and no setter found in the prefix. Return a
633 // non-existing setter that will throw an NSM error. 637 // non-existing setter that will throw an NSM error.
634 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); 638 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
635 } 639 }
636 640
637 if (owner().IsLibrary()) { 641 if (owner().IsLibrary()) {
638 const Library& library = Library::Cast(owner()); 642 const Library& library = Library::Cast(owner());
639 Object& obj = Object::Handle(zone, library.ResolveName(field_name_)); 643 Object& obj = Object::Handle(zone, library.ResolveName(field_name_));
640 if (obj.IsField()) { 644 if (obj.IsField()) {
641 const Field& field = Field::ZoneHandle(zone, Field::Cast(obj).raw()); 645 const Field& field = Field::ZoneHandle(zone, Field::Cast(obj).raw());
642 if (!field.is_final()) { 646 if (!field.is_final()) {
643 if (isolate->flags().type_checks()) { 647 if (isolate->flags().type_checks()) {
644 rhs = new AssignableNode(field.token_pos(), 648 rhs = new AssignableNode(field.token_pos(),
645 rhs, 649 rhs,
646 AbstractType::ZoneHandle(zone, field.type()), 650 AbstractType::ZoneHandle(zone, field.type()),
647 field_name_); 651 field_name_);
648 } 652 }
649 return new StoreStaticFieldNode(token_pos(), field, rhs); 653 return new StoreStaticFieldNode(token_pos(), field, rhs);
650 } 654 }
651 } 655 }
652 656
653 // No field found in library. Look for a setter function. 657 // No field found in library. Look for a setter function.
654 const String& setter_name = String::Handle(zone, 658 const String& setter_name =
655 Field::SetterName(field_name_)); 659 String::Handle(zone, Field::LookupSetterSymbol(field_name_));
656 obj = library.ResolveName(setter_name); 660 if (!setter_name.IsNull()) {
657 if (obj.IsFunction()) { 661 obj = library.ResolveName(setter_name);
658 const Function& setter = Function::ZoneHandle(zone, 662 if (obj.IsFunction()) {
659 Function::Cast(obj).raw()); 663 const Function& setter =
660 ASSERT(setter.is_static() && setter.IsSetterFunction()); 664 Function::ZoneHandle(zone, Function::Cast(obj).raw());
661 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); 665 ASSERT(setter.is_static() && setter.IsSetterFunction());
666 return
667 new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs);
668 }
662 } 669 }
663 670
664 // No writeable field and no setter found in the library. Return a 671 // No writeable field and no setter found in the library. Return a
665 // non-existing setter that will throw an NSM error. 672 // non-existing setter that will throw an NSM error.
666 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); 673 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
667 } 674 }
668 675
669 const Function& setter = 676 const Function& setter =
670 Function::ZoneHandle(zone, cls().LookupSetterFunction(field_name_)); 677 Function::ZoneHandle(zone, cls().LookupSetterFunction(field_name_));
671 if (!setter.IsNull() && setter.IsStaticFunction()) { 678 if (!setter.IsNull() && setter.IsStaticFunction()) {
672 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs); 679 return new StaticSetterNode(token_pos(), NULL, field_name_, setter, rhs);
673 } 680 }
674 // Could not find a static setter. Look for a field. 681 // Could not find a static setter. Look for a field.
675 // Access to a lazily initialized static field that has not yet been 682 // Access to a lazily initialized static field that has not yet been
676 // initialized is compiled to a static implicit getter. 683 // initialized is compiled to a static implicit getter.
677 // A setter may not exist for such a field. 684 // A setter may not exist for such a field.
678 const Field& field = Field::ZoneHandle(zone, 685 const Field& field = Field::ZoneHandle(zone,
679 cls().LookupStaticField(field_name_)); 686 cls().LookupStaticField(field_name_));
680 if (!field.IsNull()) { 687 if (!field.IsNull()) {
681 if (field.is_final()) { 688 if (field.is_final()) {
682 // Attempting to assign to a final variable will cause a NoSuchMethodError 689 // Attempting to assign to a final variable will cause a NoSuchMethodError
683 // to be thrown. Change static getter to non-existent static setter in 690 // to be thrown. Change static getter to non-existent static setter in
684 // order to trigger the throw at runtime. 691 // order to trigger the throw at runtime.
685 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs); 692 return new StaticSetterNode(token_pos(), NULL, cls(), field_name_, rhs);
686 } 693 }
687 #if defined(DEBUG) 694 #if defined(DEBUG)
688 const String& getter_name = String::Handle(zone, 695 const String& getter_name =
689 Field::GetterName(field_name_)); 696 String::Handle(zone, Field::LookupGetterSymbol(field_name_));
697 ASSERT(!getter_name.IsNull());
690 const Function& getter = 698 const Function& getter =
691 Function::Handle(zone, cls().LookupStaticFunction(getter_name)); 699 Function::Handle(zone, cls().LookupStaticFunction(getter_name));
692 ASSERT(!getter.IsNull() && 700 ASSERT(!getter.IsNull() &&
693 (getter.kind() == RawFunction::kImplicitStaticFinalGetter)); 701 (getter.kind() == RawFunction::kImplicitStaticFinalGetter));
694 #endif 702 #endif
695 if (isolate->flags().type_checks()) { 703 if (isolate->flags().type_checks()) {
696 rhs = new AssignableNode( 704 rhs = new AssignableNode(
697 field.token_pos(), 705 field.token_pos(),
698 rhs, 706 rhs,
699 AbstractType::ZoneHandle(zone, field.type()), 707 AbstractType::ZoneHandle(zone, field.type()),
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
734 } 742 }
735 return true; 743 return true;
736 } 744 }
737 745
738 746
739 const Instance* StaticGetterNode::EvalConstExpr() const { 747 const Instance* StaticGetterNode::EvalConstExpr() const {
740 if (is_deferred_reference_) { 748 if (is_deferred_reference_) {
741 return NULL; 749 return NULL;
742 } 750 }
743 const String& getter_name = 751 const String& getter_name =
744 String::Handle(Field::GetterName(this->field_name())); 752 String::Handle(Field::LookupGetterSymbol(this->field_name()));
753 if (getter_name.IsNull()) {
754 return NULL;
755 }
745 const Function& getter_func = 756 const Function& getter_func =
746 Function::Handle(this->cls().LookupStaticFunction(getter_name)); 757 Function::Handle(this->cls().LookupStaticFunction(getter_name));
747 if (getter_func.IsNull() || !getter_func.is_const()) { 758 if (getter_func.IsNull() || !getter_func.is_const()) {
748 return NULL; 759 return NULL;
749 } 760 }
750 const Object& result = Object::Handle( 761 const Object& result = Object::Handle(
751 DartEntry::InvokeFunction(getter_func, Object::empty_array())); 762 DartEntry::InvokeFunction(getter_func, Object::empty_array()));
752 if (result.IsError() || result.IsNull()) { 763 if (result.IsError() || result.IsNull()) {
753 // TODO(turnidge): We could get better error messages by returning 764 // TODO(turnidge): We could get better error messages by returning
754 // the Error object directly to the parser. This will involve 765 // the Error object directly to the parser. This will involve
755 // replumbing all of the EvalConstExpr methods. 766 // replumbing all of the EvalConstExpr methods.
756 return NULL; 767 return NULL;
757 } 768 }
758 return &Instance::ZoneHandle(Instance::Cast(result).raw()); 769 return &Instance::ZoneHandle(Instance::Cast(result).raw());
759 } 770 }
760 771
761 } // namespace dart 772 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/lib/integers.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698