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

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

Issue 2989493002: Simplify and fix implicit closure check, speed up Closure_equals (Closed)
Patch Set: Created 3 years, 5 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
OLDNEW
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 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/become.h" 10 #include "vm/become.h"
(...skipping 5583 matching lines...) Expand 10 before | Expand all | Expand 10 after
5594 } 5594 }
5595 5595
5596 const char* Function::KindToCString(RawFunction::Kind kind) { 5596 const char* Function::KindToCString(RawFunction::Kind kind) {
5597 switch (kind) { 5597 switch (kind) {
5598 case RawFunction::kRegularFunction: 5598 case RawFunction::kRegularFunction:
5599 return "RegularFunction"; 5599 return "RegularFunction";
5600 break; 5600 break;
5601 case RawFunction::kClosureFunction: 5601 case RawFunction::kClosureFunction:
5602 return "ClosureFunction"; 5602 return "ClosureFunction";
5603 break; 5603 break;
5604 case RawFunction::kImplicitClosureFunction:
5605 return "ImplicitClosureFunction";
5606 break;
5604 case RawFunction::kSignatureFunction: 5607 case RawFunction::kSignatureFunction:
5605 return "SignatureFunction"; 5608 return "SignatureFunction";
5606 break; 5609 break;
5607 case RawFunction::kGetterFunction: 5610 case RawFunction::kGetterFunction:
5608 return "GetterFunction"; 5611 return "GetterFunction";
5609 break; 5612 break;
5610 case RawFunction::kSetterFunction: 5613 case RawFunction::kSetterFunction:
5611 return "SetterFunction"; 5614 return "SetterFunction";
5612 break; 5615 break;
5613 case RawFunction::kConstructor: 5616 case RawFunction::kConstructor:
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
5980 return is_inlinable() && !is_external() && !is_generated_body() && 5983 return is_inlinable() && !is_external() && !is_generated_body() &&
5981 !thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone()); 5984 !thread->isolate()->debugger()->HasBreakpoint(*this, thread->zone());
5982 #endif 5985 #endif
5983 } 5986 }
5984 5987
5985 intptr_t Function::NumParameters() const { 5988 intptr_t Function::NumParameters() const {
5986 return num_fixed_parameters() + NumOptionalParameters(); 5989 return num_fixed_parameters() + NumOptionalParameters();
5987 } 5990 }
5988 5991
5989 intptr_t Function::NumImplicitParameters() const { 5992 intptr_t Function::NumImplicitParameters() const {
5990 if (kind() == RawFunction::kConstructor) { 5993 RawFunction::Kind k = kind();
zra 2017/07/21 19:54:16 const
alexmarkov 2017/07/21 20:51:41 Done.
5994 if (k == RawFunction::kConstructor) {
5991 // Type arguments for factory; instance for generative constructor. 5995 // Type arguments for factory; instance for generative constructor.
5992 return 1; 5996 return 1;
5993 } 5997 }
5994 if ((kind() == RawFunction::kClosureFunction) || 5998 if ((k == RawFunction::kClosureFunction) ||
5995 (kind() == RawFunction::kSignatureFunction)) { 5999 (k == RawFunction::kImplicitClosureFunction) ||
6000 (k == RawFunction::kSignatureFunction)) {
5996 return 1; // Closure object. 6001 return 1; // Closure object.
5997 } 6002 }
5998 if (!is_static()) { 6003 if (!is_static()) {
5999 // Closure functions defined inside instance (i.e. non-static) functions are 6004 // Closure functions defined inside instance (i.e. non-static) functions are
6000 // marked as non-static, but they do not have a receiver. 6005 // marked as non-static, but they do not have a receiver.
6001 // Closures are handled above. 6006 // Closures are handled above.
6002 ASSERT((kind() != RawFunction::kClosureFunction) && 6007 ASSERT((k != RawFunction::kClosureFunction) &&
6003 (kind() != RawFunction::kSignatureFunction)); 6008 (k != RawFunction::kImplicitClosureFunction) &&
6009 (k != RawFunction::kSignatureFunction));
6004 return 1; // Receiver. 6010 return 1; // Receiver.
6005 } 6011 }
6006 return 0; // No implicit parameters. 6012 return 0; // No implicit parameters.
6007 } 6013 }
6008 6014
6009 bool Function::AreValidArgumentCounts(intptr_t num_type_arguments, 6015 bool Function::AreValidArgumentCounts(intptr_t num_type_arguments,
6010 intptr_t num_arguments, 6016 intptr_t num_arguments,
6011 intptr_t num_named_arguments, 6017 intptr_t num_named_arguments,
6012 String* error_message) const { 6018 String* error_message) const {
6013 if ((num_type_arguments != 0) && 6019 if ((num_type_arguments != 0) &&
(...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after
6523 return true; 6529 return true;
6524 } 6530 }
6525 6531
6526 // The compiler generates an implicit constructor if a class definition 6532 // The compiler generates an implicit constructor if a class definition
6527 // does not contain an explicit constructor or factory. The implicit 6533 // does not contain an explicit constructor or factory. The implicit
6528 // constructor has the same token position as the owner class. 6534 // constructor has the same token position as the owner class.
6529 bool Function::IsImplicitConstructor() const { 6535 bool Function::IsImplicitConstructor() const {
6530 return IsGenerativeConstructor() && (token_pos() == end_token_pos()); 6536 return IsGenerativeConstructor() && (token_pos() == end_token_pos());
6531 } 6537 }
6532 6538
6533 bool Function::IsImplicitClosureFunction() const {
6534 if (!IsClosureFunction()) {
6535 return false;
6536 }
6537 const Function& parent = Function::Handle(parent_function());
6538 return (parent.implicit_closure_function() == raw());
6539 }
6540
6541 bool Function::IsImplicitStaticClosureFunction(RawFunction* func) { 6539 bool Function::IsImplicitStaticClosureFunction(RawFunction* func) {
6542 NoSafepointScope no_safepoint; 6540 NoSafepointScope no_safepoint;
6543 uint32_t kind_tag = func->ptr()->kind_tag_; 6541 uint32_t kind_tag = func->ptr()->kind_tag_;
6544 if (KindBits::decode(kind_tag) != RawFunction::kClosureFunction) { 6542 return (KindBits::decode(kind_tag) ==
6545 return false; 6543 RawFunction::kImplicitClosureFunction) &&
6546 } 6544 StaticBit::decode(kind_tag);
6547 if (!StaticBit::decode(kind_tag)) {
6548 return false;
6549 }
6550 RawClosureData* data = reinterpret_cast<RawClosureData*>(func->ptr()->data_);
6551 RawFunction* parent_function = data->ptr()->parent_function_;
6552 return (parent_function->ptr()->data_ == reinterpret_cast<RawObject*>(func));
6553 } 6545 }
6554 6546
6555 bool Function::IsConstructorClosureFunction() const { 6547 bool Function::IsConstructorClosureFunction() const {
6556 return IsClosureFunction() && 6548 return IsClosureFunction() &&
6557 String::Handle(name()).StartsWith(Symbols::ConstructorClosurePrefix()); 6549 String::Handle(name()).StartsWith(Symbols::ConstructorClosurePrefix());
6558 } 6550 }
6559 6551
6560 RawFunction* Function::New(Heap::Space space) { 6552 RawFunction* Function::New(Heap::Space space) {
6561 ASSERT(Object::function_class() != Class::null()); 6553 ASSERT(Object::function_class() != Class::null());
6562 RawObject* raw = 6554 RawObject* raw =
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
6606 NOT_IN_PRECOMPILED(result.set_optimized_instruction_count(0)); 6598 NOT_IN_PRECOMPILED(result.set_optimized_instruction_count(0));
6607 NOT_IN_PRECOMPILED(result.set_optimized_call_site_count(0)); 6599 NOT_IN_PRECOMPILED(result.set_optimized_call_site_count(0));
6608 result.set_kernel_offset(0); 6600 result.set_kernel_offset(0);
6609 result.set_is_optimizable(is_native ? false : true); 6601 result.set_is_optimizable(is_native ? false : true);
6610 result.set_is_inlinable(true); 6602 result.set_is_inlinable(true);
6611 result.set_allows_hoisting_check_class(true); 6603 result.set_allows_hoisting_check_class(true);
6612 result.set_allows_bounds_check_generalization(true); 6604 result.set_allows_bounds_check_generalization(true);
6613 result.SetInstructionsSafe( 6605 result.SetInstructionsSafe(
6614 Code::Handle(StubCode::LazyCompile_entry()->code())); 6606 Code::Handle(StubCode::LazyCompile_entry()->code()));
6615 if (kind == RawFunction::kClosureFunction || 6607 if (kind == RawFunction::kClosureFunction ||
6608 kind == RawFunction::kImplicitClosureFunction ||
6616 kind == RawFunction::kConvertedClosureFunction) { 6609 kind == RawFunction::kConvertedClosureFunction) {
6617 ASSERT(space == Heap::kOld); 6610 ASSERT(space == Heap::kOld);
6618 const ClosureData& data = ClosureData::Handle(ClosureData::New()); 6611 const ClosureData& data = ClosureData::Handle(ClosureData::New());
6619 result.set_data(data); 6612 result.set_data(data);
6620 } else if (kind == RawFunction::kSignatureFunction) { 6613 } else if (kind == RawFunction::kSignatureFunction) {
6621 const SignatureData& data = 6614 const SignatureData& data =
6622 SignatureData::Handle(SignatureData::New(space)); 6615 SignatureData::Handle(SignatureData::New(space));
6623 result.set_data(data); 6616 result.set_data(data);
6624 } else { 6617 } else {
6625 // Functions other than signature functions have no reason to be allocated 6618 // Functions other than signature functions have no reason to be allocated
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
6671 clone.set_parameter_types(array); 6664 clone.set_parameter_types(array);
6672 for (intptr_t i = 0; i < num_params; i++) { 6665 for (intptr_t i = 0; i < num_params; i++) {
6673 type = clone.ParameterTypeAt(i); 6666 type = clone.ParameterTypeAt(i);
6674 type ^= type.CloneUninstantiated(new_owner); 6667 type ^= type.CloneUninstantiated(new_owner);
6675 clone.SetParameterTypeAt(i, type); 6668 clone.SetParameterTypeAt(i, type);
6676 } 6669 }
6677 } 6670 }
6678 return clone.raw(); 6671 return clone.raw();
6679 } 6672 }
6680 6673
6681 RawFunction* Function::NewClosureFunction(const String& name, 6674 RawFunction* Function::NewClosureFunction(const String& name,
zra 2017/07/21 19:54:16 Can these three methods use a common helper?
alexmarkov 2017/07/21 20:51:41 Done.
6682 const Function& parent, 6675 const Function& parent,
6683 TokenPosition token_pos) { 6676 TokenPosition token_pos) {
6684 ASSERT(!parent.IsNull()); 6677 ASSERT(!parent.IsNull());
6685 // Use the owner defining the parent function and not the class containing it. 6678 // Use the owner defining the parent function and not the class containing it.
6686 const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_); 6679 const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_);
6687 ASSERT(!parent_owner.IsNull()); 6680 ASSERT(!parent_owner.IsNull());
6688 const Function& result = Function::Handle( 6681 const Function& result = Function::Handle(
6689 Function::New(name, RawFunction::kClosureFunction, 6682 Function::New(name, RawFunction::kClosureFunction,
6690 /* is_static = */ parent.is_static(), 6683 /* is_static = */ parent.is_static(),
6691 /* is_const = */ false, 6684 /* is_const = */ false,
6692 /* is_abstract = */ false, 6685 /* is_abstract = */ false,
6693 /* is_external = */ false, 6686 /* is_external = */ false,
6694 /* is_native = */ false, parent_owner, token_pos)); 6687 /* is_native = */ false, parent_owner, token_pos));
6695 result.set_parent_function(parent); 6688 result.set_parent_function(parent);
6696 return result.raw(); 6689 return result.raw();
6697 } 6690 }
6698 6691
6692 RawFunction* Function::NewImplicitClosureFunction(const String& name,
6693 const Function& parent,
6694 TokenPosition token_pos) {
6695 ASSERT(!parent.IsNull());
6696 // Use the owner defining the parent function and not the class containing it.
6697 const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_);
6698 ASSERT(!parent_owner.IsNull());
6699 const Function& result = Function::Handle(
6700 Function::New(name, RawFunction::kImplicitClosureFunction,
6701 /* is_static = */ parent.is_static(),
6702 /* is_const = */ false,
6703 /* is_abstract = */ false,
6704 /* is_external = */ false,
6705 /* is_native = */ false, parent_owner, token_pos));
6706 result.set_parent_function(parent);
6707 return result.raw();
6708 }
6709
6699 RawFunction* Function::NewConvertedClosureFunction(const String& name, 6710 RawFunction* Function::NewConvertedClosureFunction(const String& name,
6700 const Function& parent, 6711 const Function& parent,
6701 TokenPosition token_pos) { 6712 TokenPosition token_pos) {
6702 ASSERT(!parent.IsNull()); 6713 ASSERT(!parent.IsNull());
6703 // Only static top-level functions are allowed to be converted right now. 6714 // Only static top-level functions are allowed to be converted right now.
6704 ASSERT(parent.is_static()); 6715 ASSERT(parent.is_static());
6705 // Use the owner defining the parent function and not the class containing it. 6716 // Use the owner defining the parent function and not the class containing it.
6706 const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_); 6717 const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_);
6707 ASSERT(!parent_owner.IsNull()); 6718 ASSERT(!parent_owner.IsNull());
6708 const Function& result = Function::Handle( 6719 const Function& result = Function::Handle(
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
6760 // Return the existing implicit closure function if any. 6771 // Return the existing implicit closure function if any.
6761 if (implicit_closure_function() != Function::null()) { 6772 if (implicit_closure_function() != Function::null()) {
6762 return implicit_closure_function(); 6773 return implicit_closure_function();
6763 } 6774 }
6764 ASSERT(!IsSignatureFunction() && !IsClosureFunction()); 6775 ASSERT(!IsSignatureFunction() && !IsClosureFunction());
6765 Thread* thread = Thread::Current(); 6776 Thread* thread = Thread::Current();
6766 Zone* zone = thread->zone(); 6777 Zone* zone = thread->zone();
6767 // Create closure function. 6778 // Create closure function.
6768 const String& closure_name = String::Handle(zone, name()); 6779 const String& closure_name = String::Handle(zone, name());
6769 const Function& closure_function = Function::Handle( 6780 const Function& closure_function = Function::Handle(
6770 zone, NewClosureFunction(closure_name, *this, token_pos())); 6781 zone, NewImplicitClosureFunction(closure_name, *this, token_pos()));
6771 6782
6772 // Set closure function's context scope. 6783 // Set closure function's context scope.
6773 if (is_static()) { 6784 if (is_static()) {
6774 closure_function.set_context_scope(Object::empty_context_scope()); 6785 closure_function.set_context_scope(Object::empty_context_scope());
6775 } else { 6786 } else {
6776 const ContextScope& context_scope = ContextScope::Handle( 6787 const ContextScope& context_scope = ContextScope::Handle(
6777 zone, LocalScope::CreateImplicitClosureScope(*this)); 6788 zone, LocalScope::CreateImplicitClosureScope(*this));
6778 closure_function.set_context_scope(context_scope); 6789 closure_function.set_context_scope(context_scope);
6779 } 6790 }
6780 6791
(...skipping 694 matching lines...) Expand 10 before | Expand all | Expand 10 after
7475 if (IsNull()) { 7486 if (IsNull()) {
7476 return "Function: null"; 7487 return "Function: null";
7477 } 7488 }
7478 const char* static_str = is_static() ? " static" : ""; 7489 const char* static_str = is_static() ? " static" : "";
7479 const char* abstract_str = is_abstract() ? " abstract" : ""; 7490 const char* abstract_str = is_abstract() ? " abstract" : "";
7480 const char* kind_str = NULL; 7491 const char* kind_str = NULL;
7481 const char* const_str = is_const() ? " const" : ""; 7492 const char* const_str = is_const() ? " const" : "";
7482 switch (kind()) { 7493 switch (kind()) {
7483 case RawFunction::kRegularFunction: 7494 case RawFunction::kRegularFunction:
7484 case RawFunction::kClosureFunction: 7495 case RawFunction::kClosureFunction:
7496 case RawFunction::kImplicitClosureFunction:
7485 case RawFunction::kConvertedClosureFunction: 7497 case RawFunction::kConvertedClosureFunction:
7486 case RawFunction::kGetterFunction: 7498 case RawFunction::kGetterFunction:
7487 case RawFunction::kSetterFunction: 7499 case RawFunction::kSetterFunction:
7488 kind_str = ""; 7500 kind_str = "";
7489 break; 7501 break;
7490 case RawFunction::kSignatureFunction: 7502 case RawFunction::kSignatureFunction:
7491 kind_str = " signature"; 7503 kind_str = " signature";
7492 break; 7504 break;
7493 case RawFunction::kConstructor: 7505 case RawFunction::kConstructor:
7494 kind_str = is_static() ? " factory" : " constructor"; 7506 kind_str = is_static() ? " factory" : " constructor";
(...skipping 15029 matching lines...) Expand 10 before | Expand all | Expand 10 after
22524 } 22536 }
22525 return UserTag::null(); 22537 return UserTag::null();
22526 } 22538 }
22527 22539
22528 const char* UserTag::ToCString() const { 22540 const char* UserTag::ToCString() const {
22529 const String& tag_label = String::Handle(label()); 22541 const String& tag_label = String::Handle(label());
22530 return tag_label.ToCString(); 22542 return tag_label.ToCString();
22531 } 22543 }
22532 22544
22533 } // namespace dart 22545 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.cc » ('j') | tests/isolate/message4_test.dart » ('J')

Powered by Google App Engine
This is Rietveld 408576698