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 #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/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 4381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4392 const Array& new_canonical_list = | 4392 const Array& new_canonical_list = |
| 4393 Array::Handle(Array::Grow(canonical_list, new_length, Heap::kOld)); | 4393 Array::Handle(Array::Grow(canonical_list, new_length, Heap::kOld)); |
| 4394 set_constants(new_canonical_list); | 4394 set_constants(new_canonical_list); |
| 4395 new_canonical_list.SetAt(index, constant); | 4395 new_canonical_list.SetAt(index, constant); |
| 4396 } else { | 4396 } else { |
| 4397 canonical_list.SetAt(index, constant); | 4397 canonical_list.SetAt(index, constant); |
| 4398 } | 4398 } |
| 4399 } | 4399 } |
| 4400 | 4400 |
| 4401 | 4401 |
| 4402 void Class::InsertCanonicalNumber(Zone* zone, | |
| 4403 intptr_t index, | |
| 4404 const Number& constant) const { | |
| 4405 // The constant needs to be added to the list. Grow the list if it is full. | |
| 4406 Array& canonical_list = Array::Handle(zone, constants()); | |
| 4407 const intptr_t list_len = canonical_list.Length(); | |
| 4408 if (index >= list_len) { | |
| 4409 const intptr_t new_length = (list_len == 0) ? 4 : list_len + 4; | |
| 4410 canonical_list ^= Array::Grow(canonical_list, new_length, Heap::kOld); | |
| 4411 set_constants(canonical_list); | |
| 4412 } | |
| 4413 canonical_list.SetAt(index, constant); | |
| 4414 } | |
| 4415 | |
| 4416 | |
| 4402 RawUnresolvedClass* UnresolvedClass::New(const LibraryPrefix& library_prefix, | 4417 RawUnresolvedClass* UnresolvedClass::New(const LibraryPrefix& library_prefix, |
| 4403 const String& ident, | 4418 const String& ident, |
| 4404 TokenPosition token_pos) { | 4419 TokenPosition token_pos) { |
| 4405 const UnresolvedClass& type = UnresolvedClass::Handle(UnresolvedClass::New()); | 4420 const UnresolvedClass& type = UnresolvedClass::Handle(UnresolvedClass::New()); |
| 4406 type.set_library_prefix(library_prefix); | 4421 type.set_library_prefix(library_prefix); |
| 4407 type.set_ident(ident); | 4422 type.set_ident(ident); |
| 4408 type.set_token_pos(token_pos); | 4423 type.set_token_pos(token_pos); |
| 4409 return type.raw(); | 4424 return type.raw(); |
| 4410 } | 4425 } |
| 4411 | 4426 |
| (...skipping 10216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 14628 } | 14643 } |
| 14629 | 14644 |
| 14630 private: | 14645 private: |
| 14631 bool has_pointers_; | 14646 bool has_pointers_; |
| 14632 | 14647 |
| 14633 DISALLOW_COPY_AND_ASSIGN(CheckForPointers); | 14648 DISALLOW_COPY_AND_ASSIGN(CheckForPointers); |
| 14634 }; | 14649 }; |
| 14635 #endif // DEBUG | 14650 #endif // DEBUG |
| 14636 | 14651 |
| 14637 | 14652 |
| 14638 bool Instance::CheckAndCanonicalizeFields(const char** error_str) const { | 14653 bool Instance::CheckAndCanonicalizeFields(Zone* zone, |
| 14639 const Class& cls = Class::Handle(this->clazz()); | 14654 const char** error_str) const { |
| 14655 const Class& cls = Class::Handle(zone, this->clazz()); | |
| 14640 if (cls.id() >= kNumPredefinedCids) { | 14656 if (cls.id() >= kNumPredefinedCids) { |
| 14641 // Iterate over all fields, canonicalize numbers and strings, expect all | 14657 // Iterate over all fields, canonicalize numbers and strings, expect all |
| 14642 // other instances to be canonical otherwise report error (return false). | 14658 // other instances to be canonical otherwise report error (return false). |
| 14643 Object& obj = Object::Handle(); | 14659 Object& obj = Object::Handle(zone); |
| 14644 intptr_t end_field_offset = cls.instance_size() - kWordSize; | 14660 intptr_t end_field_offset = cls.instance_size() - kWordSize; |
| 14645 for (intptr_t field_offset = 0; | 14661 for (intptr_t field_offset = 0; |
| 14646 field_offset <= end_field_offset; | 14662 field_offset <= end_field_offset; |
| 14647 field_offset += kWordSize) { | 14663 field_offset += kWordSize) { |
| 14648 obj = *this->FieldAddrAtOffset(field_offset); | 14664 obj = *this->FieldAddrAtOffset(field_offset); |
| 14649 if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) { | 14665 if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) { |
| 14650 if (obj.IsNumber() || obj.IsString()) { | 14666 if (obj.IsNumber() || obj.IsString()) { |
| 14651 obj = Instance::Cast(obj).CheckAndCanonicalize(NULL); | 14667 obj = Instance::Cast(obj).CheckAndCanonicalize(NULL); |
| 14652 ASSERT(!obj.IsNull()); | 14668 ASSERT(!obj.IsNull()); |
| 14653 this->SetFieldAtOffset(field_offset, obj); | 14669 this->SetFieldAtOffset(field_offset, obj); |
| 14654 } else { | 14670 } else { |
| 14655 ASSERT(error_str != NULL); | 14671 ASSERT(error_str != NULL); |
| 14656 char* chars = OS::SCreate(Thread::Current()->zone(), | 14672 char* chars = OS::SCreate(Thread::Current()->zone(), |
|
srdjan
2016/04/06 22:32:44
zone
siva
2016/04/06 22:35:33
Done.
| |
| 14657 "field: %s\n", obj.ToCString()); | 14673 "field: %s\n", obj.ToCString()); |
| 14658 *error_str = chars; | 14674 *error_str = chars; |
| 14659 return false; | 14675 return false; |
| 14660 } | 14676 } |
| 14661 } | 14677 } |
| 14662 } | 14678 } |
| 14663 } else { | 14679 } else { |
| 14664 #if defined(DEBUG) | 14680 #if defined(DEBUG) |
| 14665 // Make sure that we are not missing any fields. | 14681 // Make sure that we are not missing any fields. |
| 14666 CheckForPointers has_pointers(Isolate::Current()); | 14682 CheckForPointers has_pointers(Isolate::Current()); |
| 14667 this->raw()->VisitPointers(&has_pointers); | 14683 this->raw()->VisitPointers(&has_pointers); |
| 14668 ASSERT(!has_pointers.has_pointers()); | 14684 ASSERT(!has_pointers.has_pointers()); |
| 14669 #endif // DEBUG | 14685 #endif // DEBUG |
| 14670 } | 14686 } |
| 14671 return true; | 14687 return true; |
| 14672 } | 14688 } |
| 14673 | 14689 |
| 14674 | 14690 |
| 14675 RawInstance* Instance::CheckAndCanonicalize(const char** error_str) const { | 14691 RawInstance* Instance::CheckAndCanonicalize(const char** error_str) const { |
| 14676 ASSERT(!IsNull()); | 14692 ASSERT(!IsNull()); |
| 14677 if (this->IsCanonical()) { | 14693 if (this->IsCanonical()) { |
| 14678 return this->raw(); | 14694 return this->raw(); |
| 14679 } | 14695 } |
| 14680 if (!CheckAndCanonicalizeFields(error_str)) { | 14696 Thread* thread = Thread::Current(); |
| 14697 Zone* zone = thread->zone(); | |
| 14698 if (!CheckAndCanonicalizeFields(zone, error_str)) { | |
| 14681 return Instance::null(); | 14699 return Instance::null(); |
| 14682 } | 14700 } |
| 14683 Thread* thread = Thread::Current(); | |
| 14684 Zone* zone = thread->zone(); | |
| 14685 Isolate* isolate = thread->isolate(); | 14701 Isolate* isolate = thread->isolate(); |
| 14686 Instance& result = Instance::Handle(zone); | 14702 Instance& result = Instance::Handle(zone); |
| 14687 const Class& cls = Class::Handle(zone, this->clazz()); | 14703 const Class& cls = Class::Handle(zone, this->clazz()); |
| 14688 intptr_t index = 0; | 14704 intptr_t index = 0; |
| 14689 result ^= cls.LookupCanonicalInstance(zone, *this, &index); | 14705 result ^= cls.LookupCanonicalInstance(zone, *this, &index); |
| 14690 if (!result.IsNull()) { | 14706 if (!result.IsNull()) { |
| 14691 return result.raw(); | 14707 return result.raw(); |
| 14692 } | 14708 } |
| 14693 { | 14709 { |
| 14694 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); | 14710 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); |
| 14695 // Retry lookup. | 14711 // Retry lookup. |
| 14696 { | 14712 { |
| 14697 Instance& temp_result = Instance::Handle(zone, | 14713 result ^= cls.LookupCanonicalInstance(zone, *this, &index); |
| 14698 cls.LookupCanonicalInstance(zone, *this, &index)); | 14714 if (!result.IsNull()) { |
| 14699 if (!temp_result.IsNull()) { | 14715 return result.raw(); |
| 14700 return temp_result.raw(); | |
| 14701 } | 14716 } |
| 14702 } | 14717 } |
| 14703 | 14718 |
| 14704 // The value needs to be added to the list. Grow the list if | 14719 // The value needs to be added to the list. Grow the list if |
| 14705 // it is full. | 14720 // it is full. |
| 14706 result ^= this->raw(); | 14721 result ^= this->raw(); |
| 14707 if (result.IsNew() || | 14722 ASSERT((isolate == Dart::vm_isolate()) || !result.InVMHeap()); |
| 14708 (result.InVMHeap() && (isolate != Dart::vm_isolate()))) { | 14723 if (result.IsNew()) { |
| 14709 /** | |
| 14710 * When a snapshot is generated on a 64 bit architecture and then read | |
| 14711 * into a 32 bit architecture, values which are Smi on the 64 bit | |
| 14712 * architecture could potentially be converted to Mint objects, however | |
| 14713 * since Smi values do not have any notion of canonical bits we lose | |
| 14714 * that information when the object becomes a Mint. | |
| 14715 * Some of these values could be literal values and end up in the | |
| 14716 * VM isolate heap. Later when these values are referenced in a | |
| 14717 * constant list we try to ensure that all the objects in the list | |
| 14718 * are canonical and try to canonicalize them. When these Mint objects | |
| 14719 * are encountered they do not have the canonical bit set and | |
| 14720 * canonicalizing them won't work as the VM heap is read only now. | |
| 14721 * In these cases we clone the object into the isolate and then | |
| 14722 * canonicalize it. | |
| 14723 */ | |
| 14724 // Create a canonical object in old space. | 14724 // Create a canonical object in old space. |
| 14725 result ^= Object::Clone(result, Heap::kOld); | 14725 result ^= Object::Clone(result, Heap::kOld); |
| 14726 } | 14726 } |
| 14727 ASSERT(result.IsOld()); | 14727 ASSERT(result.IsOld()); |
| 14728 | |
| 14729 result.SetCanonical(); | 14728 result.SetCanonical(); |
| 14730 cls.InsertCanonicalConstant(index, result); | 14729 cls.InsertCanonicalConstant(index, result); |
| 14731 return result.raw(); | 14730 return result.raw(); |
| 14732 } | 14731 } |
| 14733 } | 14732 } |
| 14734 | 14733 |
| 14735 | 14734 |
| 14736 RawAbstractType* Instance::GetType() const { | 14735 RawAbstractType* Instance::GetType() const { |
| 14737 if (IsNull()) { | 14736 if (IsNull()) { |
| 14738 return Type::NullType(); | 14737 return Type::NullType(); |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 14930 return DartLibraryCalls::Equals(*this, other) == Object::bool_true().raw(); | 14929 return DartLibraryCalls::Equals(*this, other) == Object::bool_true().raw(); |
| 14931 } | 14930 } |
| 14932 | 14931 |
| 14933 | 14932 |
| 14934 bool Instance::IsIdenticalTo(const Instance& other) const { | 14933 bool Instance::IsIdenticalTo(const Instance& other) const { |
| 14935 if (raw() == other.raw()) return true; | 14934 if (raw() == other.raw()) return true; |
| 14936 if (IsInteger() && other.IsInteger()) { | 14935 if (IsInteger() && other.IsInteger()) { |
| 14937 return Integer::Cast(*this).Equals(other); | 14936 return Integer::Cast(*this).Equals(other); |
| 14938 } | 14937 } |
| 14939 if (IsDouble() && other.IsDouble()) { | 14938 if (IsDouble() && other.IsDouble()) { |
| 14940 return Double::Cast(*this).CanonicalizeEquals(other); | 14939 double other_value = Double::Cast(other).value(); |
| 14940 return Double::Cast(*this).BitwiseEqualsToDouble(other_value); | |
| 14941 } | 14941 } |
| 14942 return false; | 14942 return false; |
| 14943 } | 14943 } |
| 14944 | 14944 |
| 14945 | 14945 |
| 14946 intptr_t* Instance::NativeFieldsDataAddr() const { | 14946 intptr_t* Instance::NativeFieldsDataAddr() const { |
| 14947 ASSERT(Thread::Current()->no_safepoint_scope_depth() > 0); | 14947 ASSERT(Thread::Current()->no_safepoint_scope_depth() > 0); |
| 14948 RawTypedData* native_fields = | 14948 RawTypedData* native_fields = |
| 14949 reinterpret_cast<RawTypedData*>(*NativeFieldsAddr()); | 14949 reinterpret_cast<RawTypedData*>(*NativeFieldsAddr()); |
| 14950 if (native_fields == TypedData::null()) { | 14950 if (native_fields == TypedData::null()) { |
| (...skipping 2383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 17334 | 17334 |
| 17335 RawMixinAppType* MixinAppType::New(const AbstractType& super_type, | 17335 RawMixinAppType* MixinAppType::New(const AbstractType& super_type, |
| 17336 const Array& mixin_types) { | 17336 const Array& mixin_types) { |
| 17337 const MixinAppType& result = MixinAppType::Handle(MixinAppType::New()); | 17337 const MixinAppType& result = MixinAppType::Handle(MixinAppType::New()); |
| 17338 result.set_super_type(super_type); | 17338 result.set_super_type(super_type); |
| 17339 result.set_mixin_types(mixin_types); | 17339 result.set_mixin_types(mixin_types); |
| 17340 return result.raw(); | 17340 return result.raw(); |
| 17341 } | 17341 } |
| 17342 | 17342 |
| 17343 | 17343 |
| 17344 RawInstance* Number::CheckAndCanonicalize(const char** error_str) const { | |
| 17345 intptr_t cid = GetClassId(); | |
| 17346 switch (cid) { | |
| 17347 case kSmiCid: | |
| 17348 return reinterpret_cast<RawSmi*>(raw_value()); | |
| 17349 case kMintCid: | |
| 17350 return Mint::NewCanonical(Mint::Cast(*this).value()); | |
| 17351 case kDoubleCid: | |
| 17352 return Double::NewCanonical(Double::Cast(*this).value()); | |
| 17353 case kBigintCid: { | |
|
regis
2016/04/06 22:02:39
Why are you not calling the existing Bigint::NewCa
siva
2016/04/06 22:26:36
Bigint::NewCanonical requires a String object whic
regis
2016/04/06 22:42:44
I missed the fact that the argument is a String.
| |
| 17354 Thread* thread = Thread::Current(); | |
| 17355 Zone* zone = thread->zone(); | |
| 17356 Isolate* isolate = thread->isolate(); | |
| 17357 if (!CheckAndCanonicalizeFields(zone, error_str)) { | |
| 17358 return Instance::null(); | |
| 17359 } | |
| 17360 Bigint& result = Bigint::Handle(zone); | |
| 17361 const Class& cls = Class::Handle(zone, this->clazz()); | |
| 17362 intptr_t index = 0; | |
| 17363 result ^= cls.LookupCanonicalBigint(zone, Bigint::Cast(*this), &index); | |
| 17364 if (!result.IsNull()) { | |
| 17365 return result.raw(); | |
| 17366 } | |
| 17367 { | |
| 17368 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); | |
| 17369 // Retry lookup. | |
| 17370 { | |
| 17371 result ^= cls.LookupCanonicalBigint( | |
| 17372 zone, Bigint::Cast(*this), &index); | |
| 17373 if (!result.IsNull()) { | |
| 17374 return result.raw(); | |
| 17375 } | |
| 17376 } | |
| 17377 | |
| 17378 // The value needs to be added to the list. Grow the list if | |
| 17379 // it is full. | |
| 17380 result ^= this->raw(); | |
| 17381 ASSERT((isolate == Dart::vm_isolate()) || !result.InVMHeap()); | |
| 17382 if (result.IsNew()) { | |
| 17383 // Create a canonical object in old space. | |
| 17384 result ^= Object::Clone(result, Heap::kOld); | |
| 17385 } | |
| 17386 ASSERT(result.IsOld()); | |
| 17387 result.SetCanonical(); | |
| 17388 cls.InsertCanonicalNumber(zone, index, result); | |
| 17389 return result.raw(); | |
| 17390 } | |
| 17391 } | |
| 17392 default: | |
| 17393 UNREACHABLE(); | |
| 17394 } | |
| 17395 return Instance::null(); | |
| 17396 } | |
| 17397 | |
| 17398 | |
| 17344 const char* Number::ToCString() const { | 17399 const char* Number::ToCString() const { |
| 17345 // Number is an interface. No instances of Number should exist. | 17400 // Number is an interface. No instances of Number should exist. |
| 17346 UNREACHABLE(); | 17401 UNREACHABLE(); |
| 17347 return "Number"; | 17402 return "Number"; |
| 17348 } | 17403 } |
| 17349 | 17404 |
| 17350 | 17405 |
| 17351 const char* Integer::ToCString() const { | 17406 const char* Integer::ToCString() const { |
| 17352 // Integer is an interface. No instances of Integer should exist except null. | 17407 // Integer is an interface. No instances of Integer should exist except null. |
| 17353 ASSERT(IsNull()); | 17408 ASSERT(IsNull()); |
| (...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 17757 Mint& canonical_value = Mint::Handle(zone); | 17812 Mint& canonical_value = Mint::Handle(zone); |
| 17758 intptr_t index = 0; | 17813 intptr_t index = 0; |
| 17759 canonical_value ^= cls.LookupCanonicalMint(zone, value, &index); | 17814 canonical_value ^= cls.LookupCanonicalMint(zone, value, &index); |
| 17760 if (!canonical_value.IsNull()) { | 17815 if (!canonical_value.IsNull()) { |
| 17761 return canonical_value.raw(); | 17816 return canonical_value.raw(); |
| 17762 } | 17817 } |
| 17763 { | 17818 { |
| 17764 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); | 17819 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); |
| 17765 // Retry lookup. | 17820 // Retry lookup. |
| 17766 { | 17821 { |
| 17767 const Mint& result = | 17822 canonical_value ^= cls.LookupCanonicalMint(zone, value, &index); |
| 17768 Mint::Handle(zone, cls.LookupCanonicalMint(zone, value, &index)); | 17823 if (!canonical_value.IsNull()) { |
| 17769 if (!result.IsNull()) { | 17824 return canonical_value.raw(); |
| 17770 return result.raw(); | |
| 17771 } | 17825 } |
| 17772 } | 17826 } |
| 17773 canonical_value = Mint::New(value, Heap::kOld); | 17827 canonical_value = Mint::New(value, Heap::kOld); |
| 17774 canonical_value.SetCanonical(); | 17828 canonical_value.SetCanonical(); |
| 17775 // The value needs to be added to the constants list. Grow the list if | 17829 // The value needs to be added to the constants list. Grow the list if |
| 17776 // it is full. | 17830 // it is full. |
| 17777 cls.InsertCanonicalConstant(index, canonical_value); | 17831 cls.InsertCanonicalNumber(zone, index, canonical_value); |
| 17778 return canonical_value.raw(); | 17832 return canonical_value.raw(); |
| 17779 } | 17833 } |
| 17780 } | 17834 } |
| 17781 | 17835 |
| 17782 | 17836 |
| 17783 bool Mint::Equals(const Instance& other) const { | 17837 bool Mint::Equals(const Instance& other) const { |
| 17784 if (this->raw() == other.raw()) { | 17838 if (this->raw() == other.raw()) { |
| 17785 // Both handles point to the same raw instance. | 17839 // Both handles point to the same raw instance. |
| 17786 return true; | 17840 return true; |
| 17787 } | 17841 } |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 17910 intptr_t index = 0; | 17964 intptr_t index = 0; |
| 17911 | 17965 |
| 17912 canonical_value ^= cls.LookupCanonicalDouble(zone, value, &index); | 17966 canonical_value ^= cls.LookupCanonicalDouble(zone, value, &index); |
| 17913 if (!canonical_value.IsNull()) { | 17967 if (!canonical_value.IsNull()) { |
| 17914 return canonical_value.raw(); | 17968 return canonical_value.raw(); |
| 17915 } | 17969 } |
| 17916 { | 17970 { |
| 17917 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); | 17971 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); |
| 17918 // Retry lookup. | 17972 // Retry lookup. |
| 17919 { | 17973 { |
| 17920 const Double& result = | 17974 canonical_value ^= cls.LookupCanonicalDouble(zone, value, &index); |
| 17921 Double::Handle(zone, cls.LookupCanonicalDouble(zone, value, &index)); | 17975 if (!canonical_value.IsNull()) { |
| 17922 if (!result.IsNull()) { | 17976 return canonical_value.raw(); |
| 17923 return result.raw(); | |
| 17924 } | 17977 } |
| 17925 } | 17978 } |
| 17926 canonical_value = Double::New(value, Heap::kOld); | 17979 canonical_value = Double::New(value, Heap::kOld); |
| 17927 canonical_value.SetCanonical(); | 17980 canonical_value.SetCanonical(); |
| 17928 // The value needs to be added to the constants list. Grow the list if | 17981 // The value needs to be added to the constants list. Grow the list if |
| 17929 // it is full. | 17982 // it is full. |
| 17930 cls.InsertCanonicalConstant(index, canonical_value); | 17983 cls.InsertCanonicalNumber(zone, index, canonical_value); |
| 17931 return canonical_value.raw(); | 17984 return canonical_value.raw(); |
| 17932 } | 17985 } |
| 17933 } | 17986 } |
| 17934 | 17987 |
| 17935 | 17988 |
| 17936 RawDouble* Double::NewCanonical(const String& str) { | 17989 RawDouble* Double::NewCanonical(const String& str) { |
| 17937 double double_value; | 17990 double double_value; |
| 17938 if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) { | 17991 if (!CStringToDouble(str.ToCString(), str.Length(), &double_value)) { |
| 17939 return Double::Handle().raw(); | 17992 return Double::Handle().raw(); |
| 17940 } | 17993 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 18047 | 18100 |
| 18048 for (intptr_t i = 0; i < used; i++) { | 18101 for (intptr_t i = 0; i < used; i++) { |
| 18049 if (this->DigitAt(i) != other_bgi.DigitAt(i)) { | 18102 if (this->DigitAt(i) != other_bgi.DigitAt(i)) { |
| 18050 return false; | 18103 return false; |
| 18051 } | 18104 } |
| 18052 } | 18105 } |
| 18053 return true; | 18106 return true; |
| 18054 } | 18107 } |
| 18055 | 18108 |
| 18056 | 18109 |
| 18057 bool Bigint::CheckAndCanonicalizeFields(const char** error_str) const { | 18110 bool Bigint::CheckAndCanonicalizeFields(Zone* zone, |
| 18111 const char** error_str) const { | |
| 18058 // Bool field neg should always be canonical. | 18112 // Bool field neg should always be canonical. |
| 18059 ASSERT(Bool::Handle(neg()).IsCanonical()); | 18113 ASSERT(Bool::Handle(zone, neg()).IsCanonical()); |
| 18060 // Smi field used is canonical by definition. | 18114 // Smi field used is canonical by definition. |
| 18061 if (Used() > 0) { | 18115 if (Used() > 0) { |
| 18062 // Canonicalize TypedData field digits. | 18116 // Canonicalize TypedData field digits. |
| 18063 TypedData& digits_ = TypedData::Handle(digits()); | 18117 TypedData& digits_ = TypedData::Handle(zone, digits()); |
| 18064 digits_ ^= digits_.CheckAndCanonicalize(NULL); | 18118 digits_ ^= digits_.CheckAndCanonicalize(NULL); |
| 18065 ASSERT(!digits_.IsNull()); | 18119 ASSERT(!digits_.IsNull()); |
| 18066 set_digits(digits_); | 18120 set_digits(digits_); |
| 18067 } else { | 18121 } else { |
| 18068 ASSERT(digits() == TypedData::EmptyUint32Array(Thread::Current())); | 18122 ASSERT(digits() == TypedData::EmptyUint32Array(Thread::Current())); |
| 18069 } | 18123 } |
| 18070 return true; | 18124 return true; |
| 18071 } | 18125 } |
| 18072 | 18126 |
| 18073 | 18127 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 18211 | 18265 |
| 18212 RawBigint* Bigint::NewCanonical(const String& str) { | 18266 RawBigint* Bigint::NewCanonical(const String& str) { |
| 18213 Thread* thread = Thread::Current(); | 18267 Thread* thread = Thread::Current(); |
| 18214 Zone* zone = thread->zone(); | 18268 Zone* zone = thread->zone(); |
| 18215 Isolate* isolate = thread->isolate(); | 18269 Isolate* isolate = thread->isolate(); |
| 18216 const Bigint& value = Bigint::Handle( | 18270 const Bigint& value = Bigint::Handle( |
| 18217 zone, Bigint::NewFromCString(str.ToCString(), Heap::kOld)); | 18271 zone, Bigint::NewFromCString(str.ToCString(), Heap::kOld)); |
| 18218 const Class& cls = | 18272 const Class& cls = |
| 18219 Class::Handle(zone, isolate->object_store()->bigint_class()); | 18273 Class::Handle(zone, isolate->object_store()->bigint_class()); |
| 18220 intptr_t index = 0; | 18274 intptr_t index = 0; |
| 18221 const Bigint& canonical_value = | 18275 Bigint& canonical_value = Bigint::Handle(zone); |
| 18222 Bigint::Handle(zone, cls.LookupCanonicalBigint(zone, value, &index)); | 18276 canonical_value ^= cls.LookupCanonicalBigint(zone, value, &index); |
| 18223 if (!canonical_value.IsNull()) { | 18277 if (!canonical_value.IsNull()) { |
| 18224 return canonical_value.raw(); | 18278 return canonical_value.raw(); |
| 18225 } | 18279 } |
| 18226 { | 18280 { |
| 18227 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); | 18281 SafepointMutexLocker ml(isolate->constant_canonicalization_mutex()); |
| 18228 // Retry lookup. | 18282 // Retry lookup. |
| 18229 { | 18283 { |
| 18230 const Bigint& result = | 18284 canonical_value ^= cls.LookupCanonicalBigint(zone, value, &index); |
| 18231 Bigint::Handle(zone, cls.LookupCanonicalBigint(zone, value, &index)); | 18285 if (!canonical_value.IsNull()) { |
| 18232 if (!result.IsNull()) { | 18286 return canonical_value.raw(); |
| 18233 return result.raw(); | |
| 18234 } | 18287 } |
| 18235 } | 18288 } |
| 18236 value.SetCanonical(); | 18289 value.SetCanonical(); |
| 18237 // The value needs to be added to the constants list. Grow the list if | 18290 // The value needs to be added to the constants list. Grow the list if |
| 18238 // it is full. | 18291 // it is full. |
| 18239 cls.InsertCanonicalConstant(index, value); | 18292 cls.InsertCanonicalNumber(zone, index, value); |
| 18240 return value.raw(); | 18293 return value.raw(); |
| 18241 } | 18294 } |
| 18242 } | 18295 } |
| 18243 | 18296 |
| 18244 | 18297 |
| 18245 RawTypedData* Bigint::NewDigitsFromHexCString(const char* str, intptr_t* used, | 18298 RawTypedData* Bigint::NewDigitsFromHexCString(const char* str, intptr_t* used, |
| 18246 Heap::Space space) { | 18299 Heap::Space space) { |
| 18247 const int kBitsPerHexDigit = 4; | 18300 const int kBitsPerHexDigit = 4; |
| 18248 const int kHexDigitsPerDigit = 8; | 18301 const int kHexDigitsPerDigit = 8; |
| 18249 const int kBitsPerDigit = kBitsPerHexDigit * kHexDigitsPerDigit; | 18302 const int kBitsPerDigit = kBitsPerHexDigit * kHexDigitsPerDigit; |
| (...skipping 2218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 20468 if (this->raw() == other.raw()) { | 20521 if (this->raw() == other.raw()) { |
| 20469 // Both handles point to the same raw instance. | 20522 // Both handles point to the same raw instance. |
| 20470 return true; | 20523 return true; |
| 20471 } | 20524 } |
| 20472 | 20525 |
| 20473 // An Array may be compared to an ImmutableArray. | 20526 // An Array may be compared to an ImmutableArray. |
| 20474 if (!other.IsArray() || other.IsNull()) { | 20527 if (!other.IsArray() || other.IsNull()) { |
| 20475 return false; | 20528 return false; |
| 20476 } | 20529 } |
| 20477 | 20530 |
| 20478 // Both arrays must have the same type arguments. | 20531 // First check if both arrays have the same length and elements. |
| 20479 const TypeArguments& type_args = TypeArguments::Handle(GetTypeArguments()); | |
| 20480 const TypeArguments& other_type_args = TypeArguments::Handle( | |
| 20481 other.GetTypeArguments()); | |
| 20482 if (!type_args.Equals(other_type_args)) { | |
| 20483 return false; | |
| 20484 } | |
| 20485 | |
| 20486 const Array& other_arr = Array::Cast(other); | 20532 const Array& other_arr = Array::Cast(other); |
| 20487 | 20533 |
| 20488 intptr_t len = this->Length(); | 20534 intptr_t len = this->Length(); |
| 20489 if (len != other_arr.Length()) { | 20535 if (len != other_arr.Length()) { |
| 20490 return false; | 20536 return false; |
| 20491 } | 20537 } |
| 20492 | 20538 |
| 20493 for (intptr_t i = 0; i < len; i++) { | 20539 for (intptr_t i = 0; i < len; i++) { |
|
regis
2016/04/06 22:02:39
Depending on len, this loop could be much more exp
siva
2016/04/06 22:26:36
How many times do you think we will have a case wh
regis
2016/04/06 22:42:44
True, checking the (identical) type first would no
| |
| 20494 if (this->At(i) != other_arr.At(i)) { | 20540 if (this->At(i) != other_arr.At(i)) { |
| 20495 return false; | 20541 return false; |
| 20496 } | 20542 } |
| 20497 } | 20543 } |
| 20544 | |
| 20545 // Now check if both arrays have the same type arguments. | |
| 20546 const TypeArguments& type_args = TypeArguments::Handle(GetTypeArguments()); | |
| 20547 const TypeArguments& other_type_args = TypeArguments::Handle( | |
| 20548 other.GetTypeArguments()); | |
| 20549 if (!type_args.Equals(other_type_args)) { | |
| 20550 return false; | |
| 20551 } | |
| 20498 return true; | 20552 return true; |
| 20499 } | 20553 } |
| 20500 | 20554 |
| 20501 | 20555 |
| 20502 RawArray* Array::New(intptr_t len, Heap::Space space) { | 20556 RawArray* Array::New(intptr_t len, Heap::Space space) { |
| 20503 ASSERT(Isolate::Current()->object_store()->array_class() != Class::null()); | 20557 ASSERT(Isolate::Current()->object_store()->array_class() != Class::null()); |
| 20504 return New(kClassId, len, space); | 20558 return New(kClassId, len, space); |
| 20505 } | 20559 } |
| 20506 | 20560 |
| 20507 | 20561 |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 20633 array.SetLength(used_len); | 20687 array.SetLength(used_len); |
| 20634 | 20688 |
| 20635 // Null the GrowableObjectArray, we are removing its backing array. | 20689 // Null the GrowableObjectArray, we are removing its backing array. |
| 20636 growable_array.SetLength(0); | 20690 growable_array.SetLength(0); |
| 20637 growable_array.SetData(Object::empty_array()); | 20691 growable_array.SetData(Object::empty_array()); |
| 20638 | 20692 |
| 20639 return array.raw(); | 20693 return array.raw(); |
| 20640 } | 20694 } |
| 20641 | 20695 |
| 20642 | 20696 |
| 20643 bool Array::CheckAndCanonicalizeFields(const char** error_str) const { | 20697 bool Array::CheckAndCanonicalizeFields(Zone* zone, |
| 20644 Object& obj = Object::Handle(); | 20698 const char** error_str) const { |
| 20699 Object& obj = Object::Handle(zone); | |
| 20645 // Iterate over all elements, canonicalize numbers and strings, expect all | 20700 // Iterate over all elements, canonicalize numbers and strings, expect all |
| 20646 // other instances to be canonical otherwise report error (return false). | 20701 // other instances to be canonical otherwise report error (return false). |
| 20647 for (intptr_t i = 0; i < Length(); i++) { | 20702 for (intptr_t i = 0; i < Length(); i++) { |
| 20648 obj = At(i); | 20703 obj = At(i); |
| 20649 if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) { | 20704 if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) { |
| 20650 if (obj.IsNumber() || obj.IsString()) { | 20705 if (obj.IsNumber() || obj.IsString()) { |
| 20651 obj = Instance::Cast(obj).CheckAndCanonicalize(NULL); | 20706 obj = Instance::Cast(obj).CheckAndCanonicalize(NULL); |
| 20652 ASSERT(!obj.IsNull()); | 20707 ASSERT(!obj.IsNull()); |
| 20653 this->SetAt(i, obj); | 20708 this->SetAt(i, obj); |
| 20654 } else { | 20709 } else { |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 20704 ASSERT(Length() > 0); | 20759 ASSERT(Length() > 0); |
| 20705 intptr_t index = Length() - 1; | 20760 intptr_t index = Length() - 1; |
| 20706 const Array& contents = Array::Handle(data()); | 20761 const Array& contents = Array::Handle(data()); |
| 20707 const PassiveObject& obj = PassiveObject::Handle(contents.At(index)); | 20762 const PassiveObject& obj = PassiveObject::Handle(contents.At(index)); |
| 20708 contents.SetAt(index, Object::null_object()); | 20763 contents.SetAt(index, Object::null_object()); |
| 20709 SetLength(index); | 20764 SetLength(index); |
| 20710 return obj.raw(); | 20765 return obj.raw(); |
| 20711 } | 20766 } |
| 20712 | 20767 |
| 20713 | 20768 |
| 20714 bool GrowableObjectArray::CanonicalizeEquals(const Instance& other) const { | |
| 20715 // If both handles point to the same raw instance they are equal. | |
| 20716 if (this->raw() == other.raw()) { | |
| 20717 return true; | |
| 20718 } | |
| 20719 | |
| 20720 // Other instance must be non null and a GrowableObjectArray. | |
| 20721 if (!other.IsGrowableObjectArray() || other.IsNull()) { | |
| 20722 return false; | |
| 20723 } | |
| 20724 | |
| 20725 const GrowableObjectArray& other_arr = GrowableObjectArray::Cast(other); | |
| 20726 | |
| 20727 // The capacity and length of both objects must be equal. | |
| 20728 if (Capacity() != other_arr.Capacity() || Length() != other_arr.Length()) { | |
| 20729 return false; | |
| 20730 } | |
| 20731 | |
| 20732 // Both arrays must have the same type arguments. | |
| 20733 const TypeArguments& type_args = TypeArguments::Handle(GetTypeArguments()); | |
| 20734 const TypeArguments& other_type_args = TypeArguments::Handle( | |
| 20735 other.GetTypeArguments()); | |
| 20736 if (!type_args.Equals(other_type_args)) { | |
| 20737 return false; | |
| 20738 } | |
| 20739 | |
| 20740 // The data part in both arrays must be identical. | |
| 20741 const Array& contents = Array::Handle(data()); | |
| 20742 const Array& other_contents = Array::Handle(other_arr.data()); | |
| 20743 for (intptr_t i = 0; i < Length(); i++) { | |
| 20744 if (contents.At(i) != other_contents.At(i)) { | |
| 20745 return false; | |
| 20746 } | |
| 20747 } | |
| 20748 return true; | |
| 20749 } | |
| 20750 | |
| 20751 | |
| 20752 RawGrowableObjectArray* GrowableObjectArray::New(intptr_t capacity, | 20769 RawGrowableObjectArray* GrowableObjectArray::New(intptr_t capacity, |
| 20753 Heap::Space space) { | 20770 Heap::Space space) { |
| 20754 const Array& data = Array::Handle(Array::New(capacity, space)); | 20771 const Array& data = Array::Handle(Array::New(capacity, space)); |
| 20755 return New(data, space); | 20772 return New(data, space); |
| 20756 } | 20773 } |
| 20757 | 20774 |
| 20758 | 20775 |
| 20759 RawGrowableObjectArray* GrowableObjectArray::New(const Array& array, | 20776 RawGrowableObjectArray* GrowableObjectArray::New(const Array& array, |
| 20760 Heap::Space space) { | 20777 Heap::Space space) { |
| 20761 ASSERT(Isolate::Current()->object_store()->growable_object_array_class() | 20778 ASSERT(Isolate::Current()->object_store()->growable_object_array_class() |
| (...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 21862 return UserTag::null(); | 21879 return UserTag::null(); |
| 21863 } | 21880 } |
| 21864 | 21881 |
| 21865 | 21882 |
| 21866 const char* UserTag::ToCString() const { | 21883 const char* UserTag::ToCString() const { |
| 21867 const String& tag_label = String::Handle(label()); | 21884 const String& tag_label = String::Handle(label()); |
| 21868 return tag_label.ToCString(); | 21885 return tag_label.ToCString(); |
| 21869 } | 21886 } |
| 21870 | 21887 |
| 21871 } // namespace dart | 21888 } // namespace dart |
| OLD | NEW |