| 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 #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 5545 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5556 } | 5556 } |
| 5557 return type.raw(); | 5557 return type.raw(); |
| 5558 } | 5558 } |
| 5559 | 5559 |
| 5560 | 5560 |
| 5561 void Function::SetSignatureType(const Type& value) const { | 5561 void Function::SetSignatureType(const Type& value) const { |
| 5562 const Object& obj = Object::Handle(raw_ptr()->data_); | 5562 const Object& obj = Object::Handle(raw_ptr()->data_); |
| 5563 ASSERT(!obj.IsNull()); | 5563 ASSERT(!obj.IsNull()); |
| 5564 if (IsSignatureFunction()) { | 5564 if (IsSignatureFunction()) { |
| 5565 SignatureData::Cast(obj).set_signature_type(value); | 5565 SignatureData::Cast(obj).set_signature_type(value); |
| 5566 ASSERT(!value.IsCanonical() || (value.signature() == this->raw())); | |
| 5567 } else { | 5566 } else { |
| 5568 ASSERT(IsClosureFunction()); | 5567 ASSERT(IsClosureFunction()); |
| 5569 ClosureData::Cast(obj).set_signature_type(value); | 5568 ClosureData::Cast(obj).set_signature_type(value); |
| 5570 } | 5569 } |
| 5571 } | 5570 } |
| 5572 | 5571 |
| 5573 | 5572 |
| 5574 bool Function::IsRedirectingFactory() const { | 5573 bool Function::IsRedirectingFactory() const { |
| 5575 if (!IsFactory() || !is_redirecting()) { | 5574 if (!IsFactory() || !is_redirecting()) { |
| 5576 return false; | 5575 return false; |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5716 } | 5715 } |
| 5717 | 5716 |
| 5718 | 5717 |
| 5719 void Function::set_name(const String& value) const { | 5718 void Function::set_name(const String& value) const { |
| 5720 ASSERT(value.IsSymbol()); | 5719 ASSERT(value.IsSymbol()); |
| 5721 StorePointer(&raw_ptr()->name_, value.raw()); | 5720 StorePointer(&raw_ptr()->name_, value.raw()); |
| 5722 } | 5721 } |
| 5723 | 5722 |
| 5724 | 5723 |
| 5725 void Function::set_owner(const Object& value) const { | 5724 void Function::set_owner(const Object& value) const { |
| 5726 ASSERT(!value.IsNull() || IsSignatureFunction()); | 5725 ASSERT(!value.IsNull()); |
| 5727 StorePointer(&raw_ptr()->owner_, value.raw()); | 5726 StorePointer(&raw_ptr()->owner_, value.raw()); |
| 5728 } | 5727 } |
| 5729 | 5728 |
| 5730 | 5729 |
| 5731 RawRegExp* Function::regexp() const { | 5730 RawRegExp* Function::regexp() const { |
| 5732 ASSERT(kind() == RawFunction::kIrregexpFunction); | 5731 ASSERT(kind() == RawFunction::kIrregexpFunction); |
| 5733 const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_)); | 5732 const Array& pair = Array::Cast(Object::Handle(raw_ptr()->data_)); |
| 5734 return RegExp::RawCast(pair.At(0)); | 5733 return RegExp::RawCast(pair.At(0)); |
| 5735 } | 5734 } |
| 5736 | 5735 |
| (...skipping 1205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6942 type = ParameterTypeAt(i); | 6941 type = ParameterTypeAt(i); |
| 6943 if (!type.IsInstantiated()) { | 6942 if (!type.IsInstantiated()) { |
| 6944 return false; | 6943 return false; |
| 6945 } | 6944 } |
| 6946 } | 6945 } |
| 6947 return true; | 6946 return true; |
| 6948 } | 6947 } |
| 6949 | 6948 |
| 6950 | 6949 |
| 6951 RawClass* Function::Owner() const { | 6950 RawClass* Function::Owner() const { |
| 6952 if (raw_ptr()->owner_ == Object::null()) { | |
| 6953 ASSERT(IsSignatureFunction()); | |
| 6954 return Class::null(); | |
| 6955 } | |
| 6956 if (raw_ptr()->owner_->IsClass()) { | 6951 if (raw_ptr()->owner_->IsClass()) { |
| 6957 return Class::RawCast(raw_ptr()->owner_); | 6952 return Class::RawCast(raw_ptr()->owner_); |
| 6958 } | 6953 } |
| 6959 const Object& obj = Object::Handle(raw_ptr()->owner_); | 6954 const Object& obj = Object::Handle(raw_ptr()->owner_); |
| 6960 ASSERT(obj.IsPatchClass()); | 6955 ASSERT(obj.IsPatchClass()); |
| 6961 return PatchClass::Cast(obj).patched_class(); | 6956 return PatchClass::Cast(obj).patched_class(); |
| 6962 } | 6957 } |
| 6963 | 6958 |
| 6964 | 6959 |
| 6965 RawClass* Function::origin() const { | 6960 RawClass* Function::origin() const { |
| 6966 if (raw_ptr()->owner_ == Object::null()) { | |
| 6967 ASSERT(IsSignatureFunction()); | |
| 6968 return Class::null(); | |
| 6969 } | |
| 6970 if (raw_ptr()->owner_->IsClass()) { | 6961 if (raw_ptr()->owner_->IsClass()) { |
| 6971 return Class::RawCast(raw_ptr()->owner_); | 6962 return Class::RawCast(raw_ptr()->owner_); |
| 6972 } | 6963 } |
| 6973 const Object& obj = Object::Handle(raw_ptr()->owner_); | 6964 const Object& obj = Object::Handle(raw_ptr()->owner_); |
| 6974 ASSERT(obj.IsPatchClass()); | 6965 ASSERT(obj.IsPatchClass()); |
| 6975 return PatchClass::Cast(obj).origin_class(); | 6966 return PatchClass::Cast(obj).origin_class(); |
| 6976 } | 6967 } |
| 6977 | 6968 |
| 6978 | 6969 |
| 6979 RawScript* Function::script() const { | 6970 RawScript* Function::script() const { |
| 6980 // NOTE(turnidge): If you update this function, you probably want to | 6971 // NOTE(turnidge): If you update this function, you probably want to |
| 6981 // update Class::PatchFieldsAndFunctions() at the same time. | 6972 // update Class::PatchFieldsAndFunctions() at the same time. |
| 6982 if (token_pos() == TokenPosition::kMinSource) { | 6973 if (token_pos() == TokenPosition::kMinSource) { |
| 6983 // Testing for position 0 is an optimization that relies on temporary | 6974 // Testing for position 0 is an optimization that relies on temporary |
| 6984 // eval functions having token position 0. | 6975 // eval functions having token position 0. |
| 6985 const Script& script = Script::Handle(eval_script()); | 6976 const Script& script = Script::Handle(eval_script()); |
| 6986 if (!script.IsNull()) { | 6977 if (!script.IsNull()) { |
| 6987 return script.raw(); | 6978 return script.raw(); |
| 6988 } | 6979 } |
| 6989 } | 6980 } |
| 6990 if (IsClosureFunction()) { | 6981 if (IsClosureFunction()) { |
| 6991 return Function::Handle(parent_function()).script(); | 6982 return Function::Handle(parent_function()).script(); |
| 6992 } | 6983 } |
| 6993 const Object& obj = Object::Handle(raw_ptr()->owner_); | 6984 const Object& obj = Object::Handle(raw_ptr()->owner_); |
| 6994 if (obj.IsNull()) { | |
| 6995 ASSERT(IsSignatureFunction()); | |
| 6996 return Script::null(); | |
| 6997 } | |
| 6998 if (obj.IsClass()) { | 6985 if (obj.IsClass()) { |
| 6999 return Class::Cast(obj).script(); | 6986 return Class::Cast(obj).script(); |
| 7000 } | 6987 } |
| 7001 ASSERT(obj.IsPatchClass()); | 6988 ASSERT(obj.IsPatchClass()); |
| 7002 return PatchClass::Cast(obj).script(); | 6989 return PatchClass::Cast(obj).script(); |
| 7003 } | 6990 } |
| 7004 | 6991 |
| 7005 | 6992 |
| 7006 bool Function::HasOptimizedCode() const { | 6993 bool Function::HasOptimizedCode() const { |
| 7007 return HasCode() && Code::Handle(CurrentCode()).is_optimized(); | 6994 return HasCode() && Code::Handle(CurrentCode()).is_optimized(); |
| (...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7305 } | 7292 } |
| 7306 | 7293 |
| 7307 | 7294 |
| 7308 void SignatureData::set_parent_function(const Function& value) const { | 7295 void SignatureData::set_parent_function(const Function& value) const { |
| 7309 StorePointer(&raw_ptr()->parent_function_, value.raw()); | 7296 StorePointer(&raw_ptr()->parent_function_, value.raw()); |
| 7310 } | 7297 } |
| 7311 | 7298 |
| 7312 | 7299 |
| 7313 void SignatureData::set_signature_type(const Type& value) const { | 7300 void SignatureData::set_signature_type(const Type& value) const { |
| 7314 StorePointer(&raw_ptr()->signature_type_, value.raw()); | 7301 StorePointer(&raw_ptr()->signature_type_, value.raw()); |
| 7302 // If the signature type is resolved, the parent function is not needed |
| 7303 // anymore (type parameters may be declared by generic parent functions). |
| 7304 // Keeping the parent function can unnecessarily pull more objects into a |
| 7305 // snapshot. Also, the parent function is meaningless once the signature type |
| 7306 // is canonicalized. |
| 7307 |
| 7308 // TODO(rmacnak): Keeping the parent function for unresolved signature types |
| 7309 // is causing a tree shaking issue in AOT. Please, investigate. |
| 7310 #if 0 |
| 7311 if (value.IsResolved()) { |
| 7312 set_parent_function(Function::Handle()); |
| 7313 } |
| 7314 #else |
| 7315 set_parent_function(Function::Handle()); |
| 7316 #endif |
| 7315 } | 7317 } |
| 7316 | 7318 |
| 7317 | 7319 |
| 7318 RawSignatureData* SignatureData::New() { | 7320 RawSignatureData* SignatureData::New() { |
| 7319 ASSERT(Object::signature_data_class() != Class::null()); | 7321 ASSERT(Object::signature_data_class() != Class::null()); |
| 7320 RawObject* raw = Object::Allocate(SignatureData::kClassId, | 7322 RawObject* raw = Object::Allocate(SignatureData::kClassId, |
| 7321 SignatureData::InstanceSize(), Heap::kOld); | 7323 SignatureData::InstanceSize(), Heap::kOld); |
| 7322 return reinterpret_cast<RawSignatureData*>(raw); | 7324 return reinterpret_cast<RawSignatureData*>(raw); |
| 7323 } | 7325 } |
| 7324 | 7326 |
| (...skipping 9795 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17120 if (IsMalbounded()) { | 17122 if (IsMalbounded()) { |
| 17121 const LanguageError& bound_error = LanguageError::Handle(zone, error()); | 17123 const LanguageError& bound_error = LanguageError::Handle(zone, error()); |
| 17122 clone.set_error(bound_error); | 17124 clone.set_error(bound_error); |
| 17123 } | 17125 } |
| 17124 // Clone the signature if this type represents a function type. | 17126 // Clone the signature if this type represents a function type. |
| 17125 Function& fun = Function::Handle(zone, signature()); | 17127 Function& fun = Function::Handle(zone, signature()); |
| 17126 if (!fun.IsNull()) { | 17128 if (!fun.IsNull()) { |
| 17127 const Class& owner = Class::Handle(zone, fun.Owner()); | 17129 const Class& owner = Class::Handle(zone, fun.Owner()); |
| 17128 Function& fun_clone = Function::Handle( | 17130 Function& fun_clone = Function::Handle( |
| 17129 zone, Function::NewSignatureFunction(owner, TokenPosition::kNoSource)); | 17131 zone, Function::NewSignatureFunction(owner, TokenPosition::kNoSource)); |
| 17130 // TODO(regis): Handle cloning of a generic function type. | |
| 17131 AbstractType& type = AbstractType::Handle(zone, fun.result_type()); | 17132 AbstractType& type = AbstractType::Handle(zone, fun.result_type()); |
| 17132 type = type.CloneUnfinalized(); | 17133 type = type.CloneUnfinalized(); |
| 17133 fun_clone.set_result_type(type); | 17134 fun_clone.set_result_type(type); |
| 17134 const intptr_t num_params = fun.NumParameters(); | 17135 const intptr_t num_params = fun.NumParameters(); |
| 17135 fun_clone.set_num_fixed_parameters(fun.num_fixed_parameters()); | 17136 fun_clone.set_num_fixed_parameters(fun.num_fixed_parameters()); |
| 17136 fun_clone.SetNumOptionalParameters(fun.NumOptionalParameters(), | 17137 fun_clone.SetNumOptionalParameters(fun.NumOptionalParameters(), |
| 17137 fun.HasOptionalPositionalParameters()); | 17138 fun.HasOptionalPositionalParameters()); |
| 17138 fun_clone.set_parameter_types( | 17139 fun_clone.set_parameter_types( |
| 17139 Array::Handle(Array::New(num_params, Heap::kOld))); | 17140 Array::Handle(Array::New(num_params, Heap::kOld))); |
| 17140 for (intptr_t i = 0; i < num_params; i++) { | 17141 for (intptr_t i = 0; i < num_params; i++) { |
| 17141 type = fun.ParameterTypeAt(i); | 17142 type = fun.ParameterTypeAt(i); |
| 17142 type = type.CloneUnfinalized(); | 17143 type = type.CloneUnfinalized(); |
| 17143 fun_clone.SetParameterTypeAt(i, type); | 17144 fun_clone.SetParameterTypeAt(i, type); |
| 17144 } | 17145 } |
| 17145 fun_clone.set_parameter_names(Array::Handle(zone, fun.parameter_names())); | 17146 fun_clone.set_parameter_names(Array::Handle(zone, fun.parameter_names())); |
| 17146 clone.set_signature(fun_clone); | 17147 clone.set_signature(fun_clone); |
| 17147 fun_clone.SetSignatureType(clone); | |
| 17148 } | 17148 } |
| 17149 clone.SetIsResolved(); | 17149 clone.SetIsResolved(); |
| 17150 return clone.raw(); | 17150 return clone.raw(); |
| 17151 } | 17151 } |
| 17152 | 17152 |
| 17153 | 17153 |
| 17154 RawAbstractType* Type::CloneUninstantiated(const Class& new_owner, | 17154 RawAbstractType* Type::CloneUninstantiated(const Class& new_owner, |
| 17155 TrailPtr trail) const { | 17155 TrailPtr trail) const { |
| 17156 ASSERT(IsFinalized()); | 17156 ASSERT(IsFinalized()); |
| 17157 ASSERT(IsCanonical()); | 17157 ASSERT(IsCanonical()); |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 17334 fun.HasOptionalPositionalParameters()); | 17334 fun.HasOptionalPositionalParameters()); |
| 17335 sig_fun.set_parameter_types( | 17335 sig_fun.set_parameter_types( |
| 17336 Array::Handle(Array::New(num_params, Heap::kOld))); | 17336 Array::Handle(Array::New(num_params, Heap::kOld))); |
| 17337 for (intptr_t i = 0; i < num_params; i++) { | 17337 for (intptr_t i = 0; i < num_params; i++) { |
| 17338 type = fun.ParameterTypeAt(i); | 17338 type = fun.ParameterTypeAt(i); |
| 17339 type = type.Canonicalize(trail); | 17339 type = type.Canonicalize(trail); |
| 17340 sig_fun.SetParameterTypeAt(i, type); | 17340 sig_fun.SetParameterTypeAt(i, type); |
| 17341 } | 17341 } |
| 17342 sig_fun.set_parameter_names(Array::Handle(zone, fun.parameter_names())); | 17342 sig_fun.set_parameter_names(Array::Handle(zone, fun.parameter_names())); |
| 17343 set_signature(sig_fun); | 17343 set_signature(sig_fun); |
| 17344 // Note that the signature type of the signature function may be | |
| 17345 // different than the type being canonicalized. | |
| 17346 // Consider F<int> being canonicalized, with F being a typedef and F<T> | |
| 17347 // being its signature type. | |
| 17348 } | 17344 } |
| 17349 } | 17345 } |
| 17350 | 17346 |
| 17351 // Check to see if the type got added to canonical list as part of the | 17347 // Check to see if the type got added to canonical list as part of the |
| 17352 // type arguments canonicalization. | 17348 // type arguments canonicalization. |
| 17353 SafepointMutexLocker ml(isolate->type_canonicalization_mutex()); | 17349 SafepointMutexLocker ml(isolate->type_canonicalization_mutex()); |
| 17354 CanonicalTypeSet table(zone, object_store->canonical_types()); | 17350 CanonicalTypeSet table(zone, object_store->canonical_types()); |
| 17355 type ^= table.GetOrNull(CanonicalTypeKey(*this)); | 17351 type ^= table.GetOrNull(CanonicalTypeKey(*this)); |
| 17356 if (type.IsNull()) { | 17352 if (type.IsNull()) { |
| 17357 // Add this Type into the canonical list of types. | 17353 // Add this Type into the canonical list of types. |
| (...skipping 5557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 22915 return UserTag::null(); | 22911 return UserTag::null(); |
| 22916 } | 22912 } |
| 22917 | 22913 |
| 22918 | 22914 |
| 22919 const char* UserTag::ToCString() const { | 22915 const char* UserTag::ToCString() const { |
| 22920 const String& tag_label = String::Handle(label()); | 22916 const String& tag_label = String::Handle(label()); |
| 22921 return tag_label.ToCString(); | 22917 return tag_label.ToCString(); |
| 22922 } | 22918 } |
| 22923 | 22919 |
| 22924 } // namespace dart | 22920 } // namespace dart |
| OLD | NEW |