| 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 "platform/assert.h" | 7 #include "platform/assert.h" |
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" |
| 9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 2710 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2721 } | 2721 } |
| 2722 return AbstractTypeArguments::AreIdentical( | 2722 return AbstractTypeArguments::AreIdentical( |
| 2723 AbstractTypeArguments::Handle(arguments()), | 2723 AbstractTypeArguments::Handle(arguments()), |
| 2724 AbstractTypeArguments::Handle(other.arguments()), | 2724 AbstractTypeArguments::Handle(other.arguments()), |
| 2725 false); // Bounds are only checked at the top level. | 2725 false); // Bounds are only checked at the top level. |
| 2726 } | 2726 } |
| 2727 | 2727 |
| 2728 | 2728 |
| 2729 RawAbstractType* Type::Canonicalize() const { | 2729 RawAbstractType* Type::Canonicalize() const { |
| 2730 ASSERT(IsFinalized()); | 2730 ASSERT(IsFinalized()); |
| 2731 if (IsCanonical() || IsMalformed()) { |
| 2732 return this->raw(); |
| 2733 } |
| 2731 const Class& cls = Class::Handle(type_class()); | 2734 const Class& cls = Class::Handle(type_class()); |
| 2732 Array& canonical_types = Array::Handle(cls.canonical_types()); | 2735 Array& canonical_types = Array::Handle(cls.canonical_types()); |
| 2733 if (canonical_types.IsNull()) { | 2736 if (canonical_types.IsNull()) { |
| 2734 // Types defined in the VM isolate are canonicalized via the object store. | 2737 // Types defined in the VM isolate are canonicalized via the object store. |
| 2735 return this->raw(); | 2738 return this->raw(); |
| 2736 } | 2739 } |
| 2737 if (!IsCanonical()) { | 2740 const intptr_t canonical_types_len = canonical_types.Length(); |
| 2738 const intptr_t canonical_types_len = canonical_types.Length(); | 2741 // Linear search to see whether this type is already present in the |
| 2739 // Linear search to see whether this type is already present in the | 2742 // list of canonicalized types. |
| 2740 // list of canonicalized types. | 2743 // TODO(asiva): Try to re-factor this lookup code to make sharing |
| 2741 // TODO(asiva): Try to re-factor this lookup code to make sharing | 2744 // easy between the 4 versions of this loop. |
| 2742 // easy between the 4 versions of this loop. | 2745 Type& type = Type::Handle(); |
| 2743 Type& type = Type::Handle(); | 2746 intptr_t index = 0; |
| 2744 intptr_t index = 0; | 2747 while (index < canonical_types_len) { |
| 2745 while (index < canonical_types_len) { | 2748 type ^= canonical_types.At(index); |
| 2746 type ^= canonical_types.At(index); | 2749 if (type.IsNull()) { |
| 2747 if (type.IsNull()) { | 2750 break; |
| 2748 break; | 2751 } |
| 2749 } | 2752 if (!type.IsFinalized()) { |
| 2750 if (!type.IsFinalized()) { | 2753 ASSERT((index == 0) && cls.IsSignatureClass()); |
| 2751 ASSERT((index == 0) && cls.IsSignatureClass()); | |
| 2752 index++; | |
| 2753 continue; | |
| 2754 } | |
| 2755 if (this->Equals(type)) { | |
| 2756 return type.raw(); | |
| 2757 } | |
| 2758 index++; | 2754 index++; |
| 2755 continue; |
| 2759 } | 2756 } |
| 2760 // The type needs to be added to the list. Grow the list if it is full. | 2757 if (this->Equals(type)) { |
| 2761 if (index == canonical_types_len) { | 2758 return type.raw(); |
| 2762 const intptr_t kLengthIncrement = 2; // Raw and parameterized. | |
| 2763 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; | |
| 2764 const Array& new_canonical_types = | |
| 2765 Array::Handle(Array::Grow(canonical_types, new_length, Heap::kOld)); | |
| 2766 cls.set_canonical_types(new_canonical_types); | |
| 2767 new_canonical_types.SetAt(index, *this); | |
| 2768 } else { | |
| 2769 canonical_types.SetAt(index, *this); | |
| 2770 } | 2759 } |
| 2771 SetCanonical(); | 2760 index++; |
| 2772 } | 2761 } |
| 2762 // The type needs to be added to the list. Grow the list if it is full. |
| 2763 // TODO(srdjan): Copy type into old space if canonicalized? |
| 2764 if (index == canonical_types_len) { |
| 2765 const intptr_t kLengthIncrement = 2; // Raw and parameterized. |
| 2766 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; |
| 2767 const Array& new_canonical_types = |
| 2768 Array::Handle(Array::Grow(canonical_types, new_length, Heap::kOld)); |
| 2769 cls.set_canonical_types(new_canonical_types); |
| 2770 new_canonical_types.SetAt(index, *this); |
| 2771 } else { |
| 2772 canonical_types.SetAt(index, *this); |
| 2773 } |
| 2774 SetCanonical(); |
| 2773 return this->raw(); | 2775 return this->raw(); |
| 2774 } | 2776 } |
| 2775 | 2777 |
| 2776 | 2778 |
| 2777 void Type::set_type_class(const Object& value) const { | 2779 void Type::set_type_class(const Object& value) const { |
| 2778 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); | 2780 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); |
| 2779 StorePointer(&raw_ptr()->type_class_, value.raw()); | 2781 StorePointer(&raw_ptr()->type_class_, value.raw()); |
| 2780 } | 2782 } |
| 2781 | 2783 |
| 2782 | 2784 |
| 2783 void Type::set_arguments(const AbstractTypeArguments& value) const { | 2785 void Type::set_arguments(const AbstractTypeArguments& value) const { |
| 2784 StorePointer(&raw_ptr()->arguments_, value.raw()); | 2786 StorePointer(&raw_ptr()->arguments_, value.raw()); |
| 2785 } | 2787 } |
| 2786 | 2788 |
| 2787 | 2789 |
| 2788 RawType* Type::New() { | 2790 RawType* Type::New(Heap::Space space) { |
| 2789 const Class& type_class = Class::Handle(Object::type_class()); | 2791 const Class& type_class = Class::Handle(Object::type_class()); |
| 2790 RawObject* raw = Object::Allocate(type_class, | 2792 RawObject* raw = Object::Allocate(type_class, |
| 2791 Type::InstanceSize(), | 2793 Type::InstanceSize(), |
| 2792 Heap::kOld); | 2794 space); |
| 2793 return reinterpret_cast<RawType*>(raw); | 2795 return reinterpret_cast<RawType*>(raw); |
| 2794 } | 2796 } |
| 2795 | 2797 |
| 2796 | 2798 |
| 2797 RawType* Type::New(const Object& clazz, | 2799 RawType* Type::New(const Object& clazz, |
| 2798 const AbstractTypeArguments& arguments, | 2800 const AbstractTypeArguments& arguments, |
| 2799 intptr_t token_pos) { | 2801 intptr_t token_pos, |
| 2800 const Type& result = Type::Handle(Type::New()); | 2802 Heap::Space space) { |
| 2803 const Type& result = Type::Handle(Type::New(space)); |
| 2801 result.set_type_class(clazz); | 2804 result.set_type_class(clazz); |
| 2802 result.set_arguments(arguments); | 2805 result.set_arguments(arguments); |
| 2803 result.set_token_pos(token_pos); | 2806 result.set_token_pos(token_pos); |
| 2804 result.raw_ptr()->type_state_ = RawType::kAllocated; | 2807 result.raw_ptr()->type_state_ = RawType::kAllocated; |
| 2805 return result.raw(); | 2808 return result.raw(); |
| 2806 } | 2809 } |
| 2807 | 2810 |
| 2808 | 2811 |
| 2809 void Type::set_token_pos(intptr_t token_pos) const { | 2812 void Type::set_token_pos(intptr_t token_pos) const { |
| 2810 ASSERT(token_pos >= 0); | 2813 ASSERT(token_pos >= 0); |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3342 RawAbstractTypeArguments* TypeArguments::InstantiateFrom( | 3345 RawAbstractTypeArguments* TypeArguments::InstantiateFrom( |
| 3343 const AbstractTypeArguments& instantiator_type_arguments) const { | 3346 const AbstractTypeArguments& instantiator_type_arguments) const { |
| 3344 ASSERT(!IsInstantiated()); | 3347 ASSERT(!IsInstantiated()); |
| 3345 if (!instantiator_type_arguments.IsNull() && | 3348 if (!instantiator_type_arguments.IsNull() && |
| 3346 IsUninstantiatedIdentity() && | 3349 IsUninstantiatedIdentity() && |
| 3347 (instantiator_type_arguments.Length() == Length())) { | 3350 (instantiator_type_arguments.Length() == Length())) { |
| 3348 return instantiator_type_arguments.raw(); | 3351 return instantiator_type_arguments.raw(); |
| 3349 } | 3352 } |
| 3350 const intptr_t num_types = Length(); | 3353 const intptr_t num_types = Length(); |
| 3351 TypeArguments& instantiated_array = | 3354 TypeArguments& instantiated_array = |
| 3352 TypeArguments::Handle(TypeArguments::New(num_types)); | 3355 TypeArguments::Handle(TypeArguments::New(num_types, Heap::kNew)); |
| 3353 AbstractType& type = AbstractType::Handle(); | 3356 AbstractType& type = AbstractType::Handle(); |
| 3354 for (intptr_t i = 0; i < num_types; i++) { | 3357 for (intptr_t i = 0; i < num_types; i++) { |
| 3355 type = TypeAt(i); | 3358 type = TypeAt(i); |
| 3356 if (!type.IsInstantiated()) { | 3359 if (!type.IsInstantiated()) { |
| 3357 type = type.InstantiateFrom(instantiator_type_arguments); | 3360 type = type.InstantiateFrom(instantiator_type_arguments); |
| 3358 } | 3361 } |
| 3359 instantiated_array.SetTypeAt(i, type); | 3362 instantiated_array.SetTypeAt(i, type); |
| 3360 } | 3363 } |
| 3361 return instantiated_array.raw(); | 3364 return instantiated_array.raw(); |
| 3362 } | 3365 } |
| 3363 | 3366 |
| 3364 | 3367 |
| 3365 RawTypeArguments* TypeArguments::New(intptr_t len) { | 3368 RawTypeArguments* TypeArguments::New(intptr_t len, Heap::Space space) { |
| 3366 if ((len < 0) || (len > kMaxTypes)) { | 3369 if ((len < 0) || (len > kMaxTypes)) { |
| 3367 // TODO(iposva): Should we throw an illegal parameter exception? | 3370 // TODO(iposva): Should we throw an illegal parameter exception? |
| 3368 UNIMPLEMENTED(); | 3371 UNIMPLEMENTED(); |
| 3369 return null(); | 3372 return null(); |
| 3370 } | 3373 } |
| 3371 | 3374 |
| 3372 const Class& type_arguments_class = | 3375 const Class& type_arguments_class = |
| 3373 Class::Handle(Object::type_arguments_class()); | 3376 Class::Handle(Object::type_arguments_class()); |
| 3374 TypeArguments& result = TypeArguments::Handle(); | 3377 TypeArguments& result = TypeArguments::Handle(); |
| 3375 { | 3378 { |
| 3376 RawObject* raw = Object::Allocate(type_arguments_class, | 3379 RawObject* raw = Object::Allocate(type_arguments_class, |
| 3377 TypeArguments::InstanceSize(len), | 3380 TypeArguments::InstanceSize(len), |
| 3378 Heap::kOld); | 3381 space); |
| 3379 NoGCScope no_gc; | 3382 NoGCScope no_gc; |
| 3380 result ^= raw; | 3383 result ^= raw; |
| 3381 // Length must be set before we start storing into the array. | 3384 // Length must be set before we start storing into the array. |
| 3382 result.SetLength(len); | 3385 result.SetLength(len); |
| 3383 } | 3386 } |
| 3384 return result.raw(); | 3387 return result.raw(); |
| 3385 } | 3388 } |
| 3386 | 3389 |
| 3387 | 3390 |
| 3388 | 3391 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 3412 intptr_t index = 0; | 3415 intptr_t index = 0; |
| 3413 TypeArguments& other = TypeArguments::Handle(); | 3416 TypeArguments& other = TypeArguments::Handle(); |
| 3414 other ^= table.At(index); | 3417 other ^= table.At(index); |
| 3415 while (!other.IsNull()) { | 3418 while (!other.IsNull()) { |
| 3416 if (this->Equals(other)) { | 3419 if (this->Equals(other)) { |
| 3417 return other.raw(); | 3420 return other.raw(); |
| 3418 } | 3421 } |
| 3419 other ^= table.At(++index); | 3422 other ^= table.At(++index); |
| 3420 } | 3423 } |
| 3421 // Not found. Add 'this' to table. | 3424 // Not found. Add 'this' to table. |
| 3425 // TODO(srdjan): Copy 'this' into old space if canonicalized? |
| 3422 if (index == table.Length() - 1) { | 3426 if (index == table.Length() - 1) { |
| 3423 table = Array::Grow(table, table.Length() + 4, Heap::kOld); | 3427 table = Array::Grow(table, table.Length() + 4, Heap::kOld); |
| 3424 object_store->set_canonical_type_arguments(table); | 3428 object_store->set_canonical_type_arguments(table); |
| 3425 } | 3429 } |
| 3426 table.SetAt(index, *this); | 3430 table.SetAt(index, *this); |
| 3427 SetCanonical(); | 3431 SetCanonical(); |
| 3428 return this->raw(); | 3432 return this->raw(); |
| 3429 } | 3433 } |
| 3430 | 3434 |
| 3431 | 3435 |
| (...skipping 614 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4046 signature_class = Class::NewSignatureClass(signature, | 4050 signature_class = Class::NewSignatureClass(signature, |
| 4047 closure_function, | 4051 closure_function, |
| 4048 script); | 4052 script); |
| 4049 library.AddClass(signature_class); | 4053 library.AddClass(signature_class); |
| 4050 } else { | 4054 } else { |
| 4051 closure_function.set_signature_class(signature_class); | 4055 closure_function.set_signature_class(signature_class); |
| 4052 } | 4056 } |
| 4053 const Type& signature_type = Type::Handle(signature_class.SignatureType()); | 4057 const Type& signature_type = Type::Handle(signature_class.SignatureType()); |
| 4054 if (!signature_type.IsFinalized()) { | 4058 if (!signature_type.IsFinalized()) { |
| 4055 ClassFinalizer::FinalizeType( | 4059 ClassFinalizer::FinalizeType( |
| 4056 signature_class, signature_type, ClassFinalizer::kFinalize); | 4060 signature_class, signature_type, ClassFinalizer::kCanonicalize); |
| 4057 } | 4061 } |
| 4058 ASSERT(closure_function.signature_class() == signature_class.raw()); | 4062 ASSERT(closure_function.signature_class() == signature_class.raw()); |
| 4059 set_implicit_closure_function(closure_function); | 4063 set_implicit_closure_function(closure_function); |
| 4060 ASSERT(closure_function.IsImplicitClosureFunction()); | 4064 ASSERT(closure_function.IsImplicitClosureFunction()); |
| 4061 return closure_function.raw(); | 4065 return closure_function.raw(); |
| 4062 } | 4066 } |
| 4063 | 4067 |
| 4064 | 4068 |
| 4065 RawString* Function::BuildSignature( | 4069 RawString* Function::BuildSignature( |
| 4066 bool instantiate, | 4070 bool instantiate, |
| (...skipping 6175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10242 const String& str = String::Handle(pattern()); | 10246 const String& str = String::Handle(pattern()); |
| 10243 const char* format = "JSRegExp: pattern=%s flags=%s"; | 10247 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 10244 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 10248 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 10245 char* chars = reinterpret_cast<char*>( | 10249 char* chars = reinterpret_cast<char*>( |
| 10246 Isolate::Current()->current_zone()->Allocate(len + 1)); | 10250 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 10247 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 10251 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 10248 return chars; | 10252 return chars; |
| 10249 } | 10253 } |
| 10250 | 10254 |
| 10251 } // namespace dart | 10255 } // namespace dart |
| OLD | NEW |