Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/object.h" | 5 #include "vm/object.h" |
| 6 | 6 |
| 7 #include "vm/assembler.h" | 7 #include "vm/assembler.h" |
| 8 #include "vm/assert.h" | 8 #include "vm/assert.h" |
| 9 #include "vm/bigint_operations.h" | 9 #include "vm/bigint_operations.h" |
| 10 #include "vm/bootstrap.h" | 10 #include "vm/bootstrap.h" |
| (...skipping 2118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2129 AbstractTypeArguments::Handle(other.arguments())); | 2129 AbstractTypeArguments::Handle(other.arguments())); |
| 2130 } | 2130 } |
| 2131 | 2131 |
| 2132 | 2132 |
| 2133 RawAbstractType* Type::Canonicalize() const { | 2133 RawAbstractType* Type::Canonicalize() const { |
| 2134 ASSERT(IsFinalized()); | 2134 ASSERT(IsFinalized()); |
| 2135 const Class& cls = Class::Handle(type_class()); | 2135 const Class& cls = Class::Handle(type_class()); |
| 2136 Array& canonical_types = Array::Handle(cls.canonical_types()); | 2136 Array& canonical_types = Array::Handle(cls.canonical_types()); |
| 2137 if (canonical_types.IsNull()) { | 2137 if (canonical_types.IsNull()) { |
| 2138 // Types defined in the VM isolate are canonicalized via the object store. | 2138 // Types defined in the VM isolate are canonicalized via the object store. |
| 2139 // TODO(regis): Should we add null_class_, void_class_, dynamic_class_ to | 2139 // TODO(regis): Should we add null_class_, void_class_, dynamic_class_ to |
|
regis
2011/12/14 02:53:36
Feel free to remove this TODO, as discussed.
siva
2011/12/14 18:04:39
Done.
| |
| 2140 // the object store, remove all types from the object store, and replace | 2140 // the object store, remove all types from the object store, and replace |
| 2141 // the test above by an assert? | 2141 // the test above by an assert? |
| 2142 return this->raw(); | 2142 return this->raw(); |
| 2143 } | 2143 } |
| 2144 const intptr_t canonical_types_len = canonical_types.Length(); | 2144 if (!IsCanonical()) { |
| 2145 // Linear search to see whether this type is already present in the | 2145 const intptr_t canonical_types_len = canonical_types.Length(); |
| 2146 // list of canonicalized types. | 2146 // Linear search to see whether this type is already present in the |
| 2147 Type& type = Type::Handle(); | 2147 // list of canonicalized types. |
| 2148 intptr_t index = 0; | 2148 Type& type = Type::Handle(); |
| 2149 while (index < canonical_types_len) { | 2149 intptr_t index = 0; |
| 2150 type ^= canonical_types.At(index); | 2150 while (index < canonical_types_len) { |
| 2151 if (type.IsNull()) { | 2151 type ^= canonical_types.At(index); |
| 2152 break; | 2152 if (type.IsNull()) { |
| 2153 break; | |
| 2154 } | |
| 2155 if (!type.IsFinalized()) { | |
| 2156 ASSERT((index == 0) && cls.IsSignatureClass()); | |
| 2157 index++; | |
| 2158 continue; | |
| 2159 } | |
| 2160 if (this->Equals(type)) { | |
| 2161 return type.raw(); | |
| 2162 } | |
| 2163 index++; | |
| 2153 } | 2164 } |
| 2154 if (!type.IsFinalized()) { | 2165 // The type needs to be added to the list. Grow the list if it is full. |
| 2155 ASSERT((index == 0) && cls.IsSignatureClass()); | 2166 if (index == canonical_types_len) { |
| 2156 index++; | 2167 const intptr_t kLengthIncrement = 2; // Raw and parameterized. |
| 2157 continue; | 2168 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; |
| 2169 const Array& new_canonical_types = | |
| 2170 Array::Handle(Array::Grow(canonical_types, new_length, Heap::kOld)); | |
| 2171 cls.set_canonical_types(new_canonical_types); | |
| 2172 new_canonical_types.SetAt(index, *this); | |
| 2173 } else { | |
| 2174 canonical_types.SetAt(index, *this); | |
| 2158 } | 2175 } |
| 2159 if (this->Equals(type)) { | 2176 SetCanonical(); |
| 2160 return type.raw(); | |
| 2161 } | |
| 2162 index++; | |
| 2163 } | |
| 2164 // The type needs to be added to the list. Grow the list if it is full. | |
| 2165 if (index == canonical_types_len) { | |
| 2166 const intptr_t kLengthIncrement = 2; // Raw and parameterized. | |
| 2167 const intptr_t new_length = canonical_types.Length() + kLengthIncrement; | |
| 2168 const Array& new_canonical_types = | |
| 2169 Array::Handle(Array::Grow(canonical_types, new_length, Heap::kOld)); | |
| 2170 cls.set_canonical_types(new_canonical_types); | |
| 2171 new_canonical_types.SetAt(index, *this); | |
| 2172 } else { | |
| 2173 canonical_types.SetAt(index, *this); | |
| 2174 } | 2177 } |
| 2175 return this->raw(); | 2178 return this->raw(); |
| 2176 } | 2179 } |
| 2177 | 2180 |
| 2178 | 2181 |
| 2179 void Type::set_type_class(const Object& value) const { | 2182 void Type::set_type_class(const Object& value) const { |
| 2180 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); | 2183 ASSERT(!value.IsNull() && (value.IsClass() || value.IsUnresolvedClass())); |
| 2181 StorePointer(&raw_ptr()->type_class_, value.raw()); | 2184 StorePointer(&raw_ptr()->type_class_, value.raw()); |
| 2182 } | 2185 } |
| 2183 | 2186 |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2515 return Smi::Value(raw_ptr()->length_); | 2518 return Smi::Value(raw_ptr()->length_); |
| 2516 } | 2519 } |
| 2517 | 2520 |
| 2518 | 2521 |
| 2519 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const { | 2522 RawAbstractType* TypeArguments::TypeAt(intptr_t index) const { |
| 2520 return *TypeAddr(index); | 2523 return *TypeAddr(index); |
| 2521 } | 2524 } |
| 2522 | 2525 |
| 2523 | 2526 |
| 2524 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const { | 2527 void TypeArguments::SetTypeAt(intptr_t index, const AbstractType& value) const { |
| 2525 ASSERT(!is_canonical()); | 2528 ASSERT(!IsCanonical()); |
| 2526 // TODO(iposva): Add storing NoGCScope. | 2529 // TODO(iposva): Add storing NoGCScope. |
| 2527 *TypeAddr(index) = value.raw(); | 2530 *TypeAddr(index) = value.raw(); |
| 2528 } | 2531 } |
| 2529 | 2532 |
| 2530 | 2533 |
| 2531 bool TypeArguments::IsResolved() const { | 2534 bool TypeArguments::IsResolved() const { |
| 2532 AbstractType& type = AbstractType::Handle(); | 2535 AbstractType& type = AbstractType::Handle(); |
| 2533 intptr_t num_types = Length(); | 2536 intptr_t num_types = Length(); |
| 2534 for (intptr_t i = 0; i < num_types; i++) { | 2537 for (intptr_t i = 0; i < num_types; i++) { |
| 2535 type = TypeAt(i); | 2538 type = TypeAt(i); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2601 | 2604 |
| 2602 const Class& type_arguments_class = | 2605 const Class& type_arguments_class = |
| 2603 Class::Handle(Object::type_arguments_class()); | 2606 Class::Handle(Object::type_arguments_class()); |
| 2604 TypeArguments& result = TypeArguments::Handle(); | 2607 TypeArguments& result = TypeArguments::Handle(); |
| 2605 { | 2608 { |
| 2606 RawObject* raw = Object::Allocate(type_arguments_class, | 2609 RawObject* raw = Object::Allocate(type_arguments_class, |
| 2607 TypeArguments::InstanceSize(len), | 2610 TypeArguments::InstanceSize(len), |
| 2608 Heap::kOld); | 2611 Heap::kOld); |
| 2609 NoGCScope no_gc; | 2612 NoGCScope no_gc; |
| 2610 result ^= raw; | 2613 result ^= raw; |
| 2611 result.set_is_canonical(false); | |
| 2612 // Length must be set before we start storing into the array. | 2614 // Length must be set before we start storing into the array. |
| 2613 result.SetLength(len); | 2615 result.SetLength(len); |
| 2614 for (intptr_t i = 0; i < len; i++) { | 2616 for (intptr_t i = 0; i < len; i++) { |
| 2615 *result.TypeAddr(i) = Type::null(); | 2617 *result.TypeAddr(i) = Type::null(); |
| 2616 } | 2618 } |
| 2617 } | 2619 } |
| 2618 return result.raw(); | 2620 return result.raw(); |
| 2619 } | 2621 } |
| 2620 | 2622 |
| 2621 | 2623 |
| 2622 | 2624 |
| 2623 RawAbstractType** TypeArguments::TypeAddr(intptr_t index) const { | 2625 RawAbstractType** TypeArguments::TypeAddr(intptr_t index) const { |
| 2624 // TODO(iposva): Determine if we should throw an exception here. | 2626 // TODO(iposva): Determine if we should throw an exception here. |
| 2625 ASSERT((index >= 0) && (index < Length())); | 2627 ASSERT((index >= 0) && (index < Length())); |
| 2626 return &raw_ptr()->types_[index]; | 2628 return &raw_ptr()->types_[index]; |
| 2627 } | 2629 } |
| 2628 | 2630 |
| 2629 | 2631 |
| 2630 void TypeArguments::SetLength(intptr_t value) { | 2632 void TypeArguments::SetLength(intptr_t value) { |
| 2631 ASSERT(!is_canonical()); | 2633 ASSERT(!IsCanonical()); |
| 2632 // This is only safe because we create a new Smi, which does not cause | 2634 // This is only safe because we create a new Smi, which does not cause |
| 2633 // heap allocation. | 2635 // heap allocation. |
| 2634 raw_ptr()->length_ = Smi::New(value); | 2636 raw_ptr()->length_ = Smi::New(value); |
| 2635 } | 2637 } |
| 2636 | 2638 |
| 2637 | 2639 |
| 2638 RawAbstractTypeArguments* TypeArguments::Canonicalize() const { | 2640 RawAbstractTypeArguments* TypeArguments::Canonicalize() const { |
| 2639 if (IsNull() || is_canonical() || !IsInstantiated()) { | 2641 if (IsNull() || IsCanonical() || !IsInstantiated()) { |
| 2640 return this->raw(); | 2642 return this->raw(); |
| 2641 } | 2643 } |
| 2642 ObjectStore* object_store = Isolate::Current()->object_store(); | 2644 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 2643 // 'table' must be null terminated. | 2645 // 'table' must be null terminated. |
| 2644 Array& table = Array::Handle(object_store->canonical_type_arguments()); | 2646 Array& table = Array::Handle(object_store->canonical_type_arguments()); |
| 2645 ASSERT(table.Length() > 0); | 2647 ASSERT(table.Length() > 0); |
| 2646 intptr_t index = 0; | 2648 intptr_t index = 0; |
| 2647 TypeArguments& other = TypeArguments::Handle(); | 2649 TypeArguments& other = TypeArguments::Handle(); |
| 2648 other ^= table.At(index); | 2650 other ^= table.At(index); |
| 2649 while (!other.IsNull()) { | 2651 while (!other.IsNull()) { |
| 2650 if (this->Equals(other)) { | 2652 if (this->Equals(other)) { |
| 2651 return other.raw(); | 2653 return other.raw(); |
| 2652 } | 2654 } |
| 2653 other ^= table.At(++index); | 2655 other ^= table.At(++index); |
| 2654 } | 2656 } |
| 2655 // Not found. Add 'this' to table. | 2657 // Not found. Add 'this' to table. |
| 2656 if (index == table.Length() - 1) { | 2658 if (index == table.Length() - 1) { |
| 2657 table = Array::Grow(table, table.Length() + 4, Heap::kOld); | 2659 table = Array::Grow(table, table.Length() + 4, Heap::kOld); |
| 2658 object_store->set_canonical_type_arguments(table); | 2660 object_store->set_canonical_type_arguments(table); |
| 2659 } | 2661 } |
| 2660 table.SetAt(index, *this); | 2662 table.SetAt(index, *this); |
| 2661 this->set_is_canonical(true); | 2663 SetCanonical(); |
| 2662 return this->raw(); | 2664 return this->raw(); |
| 2663 } | 2665 } |
| 2664 | 2666 |
| 2665 | 2667 |
| 2666 bool TypeArguments::is_canonical() const { | |
| 2667 return raw_ptr()->is_canonical_; | |
| 2668 } | |
| 2669 | |
| 2670 | |
| 2671 void TypeArguments::set_is_canonical(bool value) const { | |
| 2672 raw_ptr()->is_canonical_ = value; | |
| 2673 } | |
| 2674 | |
| 2675 | |
| 2676 const char* TypeArguments::ToCString() const { | 2668 const char* TypeArguments::ToCString() const { |
| 2677 if (IsNull()) { | 2669 if (IsNull()) { |
| 2678 return "NULL TypeArguments"; | 2670 return "NULL TypeArguments"; |
| 2679 } | 2671 } |
| 2680 const char* format = "%s [%s]"; | 2672 const char* format = "%s [%s]"; |
| 2681 const char* prev_cstr = "TypeArguments:"; | 2673 const char* prev_cstr = "TypeArguments:"; |
| 2682 for (int i = 0; i < Length(); i++) { | 2674 for (int i = 0; i < Length(); i++) { |
| 2683 const AbstractType& type_at = AbstractType::Handle(TypeAt(i)); | 2675 const AbstractType& type_at = AbstractType::Handle(TypeAt(i)); |
| 2684 const char* type_cstr = type_at.IsNull() ? "null" : type_at.ToCString(); | 2676 const char* type_cstr = type_at.IsNull() ? "null" : type_at.ToCString(); |
| 2685 intptr_t len = OS::SNPrint(NULL, 0, format, prev_cstr, type_cstr) + 1; | 2677 intptr_t len = OS::SNPrint(NULL, 0, format, prev_cstr, type_cstr) + 1; |
| (...skipping 2316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5002 return false; | 4994 return false; |
| 5003 } | 4995 } |
| 5004 | 4996 |
| 5005 { | 4997 { |
| 5006 NoGCScope no_gc; | 4998 NoGCScope no_gc; |
| 5007 // Raw bits compare. | 4999 // Raw bits compare. |
| 5008 const intptr_t instance_size = Class::Handle(this->clazz()).instance_size(); | 5000 const intptr_t instance_size = Class::Handle(this->clazz()).instance_size(); |
| 5009 ASSERT(instance_size != 0); | 5001 ASSERT(instance_size != 0); |
| 5010 uword this_addr = reinterpret_cast<uword>(this->raw_ptr()); | 5002 uword this_addr = reinterpret_cast<uword>(this->raw_ptr()); |
| 5011 uword other_addr = reinterpret_cast<uword>(other.raw_ptr()); | 5003 uword other_addr = reinterpret_cast<uword>(other.raw_ptr()); |
| 5012 for (intptr_t offset = 0; offset < instance_size; offset += kWordSize) { | 5004 for (intptr_t offset = sizeof(RawObject); |
| 5005 offset < instance_size; | |
| 5006 offset += kWordSize) { | |
| 5013 if ((*reinterpret_cast<RawObject**>(this_addr + offset)) != | 5007 if ((*reinterpret_cast<RawObject**>(this_addr + offset)) != |
| 5014 (*reinterpret_cast<RawObject**>(other_addr + offset))) { | 5008 (*reinterpret_cast<RawObject**>(other_addr + offset))) { |
| 5015 return false; | 5009 return false; |
| 5016 } | 5010 } |
| 5017 } | 5011 } |
| 5018 } | 5012 } |
| 5019 return true; | 5013 return true; |
| 5020 } | 5014 } |
| 5021 | 5015 |
| 5022 | 5016 |
| 5023 RawInstance* Instance::Canonicalize() const { | 5017 RawInstance* Instance::Canonicalize() const { |
| 5024 ASSERT(!IsNull()); | 5018 ASSERT(!IsNull()); |
| 5025 const Class& cls = Class::Handle(this->clazz()); | 5019 if (!IsCanonical()) { |
| 5026 Array& constants = Array::Handle(cls.constants()); | 5020 const Class& cls = Class::Handle(this->clazz()); |
| 5027 const intptr_t constants_len = constants.Length(); | 5021 Array& constants = Array::Handle(cls.constants()); |
| 5028 // Linear search to see whether this value is already present in the | 5022 const intptr_t constants_len = constants.Length(); |
| 5029 // list of canonicalized constants. | 5023 // Linear search to see whether this value is already present in the |
| 5030 Instance& norm_value = Instance::Handle(); | 5024 // list of canonicalized constants. |
| 5031 intptr_t index = 0; | 5025 Instance& norm_value = Instance::Handle(); |
| 5032 while (index < constants_len) { | 5026 intptr_t index = 0; |
| 5033 norm_value ^= constants.At(index); | 5027 while (index < constants_len) { |
| 5034 if (norm_value.IsNull()) { | 5028 norm_value ^= constants.At(index); |
| 5035 break; | 5029 if (norm_value.IsNull()) { |
| 5030 break; | |
| 5031 } | |
| 5032 if (this->Equals(norm_value)) { | |
| 5033 return norm_value.raw(); | |
| 5034 } | |
| 5035 index++; | |
| 5036 } | 5036 } |
| 5037 if (this->Equals(norm_value)) { | 5037 // The value needs to be added to the list. Grow the list if |
| 5038 return norm_value.raw(); | 5038 // it is full. |
| 5039 // TODO(srdjan): Copy instance into old space if canonicalized? | |
| 5040 if (index == constants_len) { | |
| 5041 const intptr_t kInitialConstLength = 4; | |
| 5042 const intptr_t old_length = constants.Length(); | |
| 5043 const intptr_t new_length = | |
| 5044 (old_length == 0) ? kInitialConstLength : old_length * 2; | |
| 5045 const Array& new_constants = | |
| 5046 Array::Handle(Array::Grow(constants, new_length, Heap::kOld)); | |
| 5047 cls.set_constants(new_constants); | |
| 5048 new_constants.SetAt(index, *this); | |
| 5049 } else { | |
| 5050 constants.SetAt(index, *this); | |
| 5039 } | 5051 } |
| 5040 index++; | 5052 SetCanonical(); |
| 5041 } | |
| 5042 // The value needs to be added to the list. Grow the list if | |
| 5043 // it is full. | |
| 5044 // TODO(srdjan): Copy instance into old space if canonicalized? | |
| 5045 if (index == constants_len) { | |
| 5046 const intptr_t kInitialConstLength = 4; | |
| 5047 const intptr_t old_length = constants.Length(); | |
| 5048 const intptr_t new_length = | |
| 5049 (old_length == 0) ? kInitialConstLength : old_length * 2; | |
| 5050 const Array& new_constants = | |
| 5051 Array::Handle(Array::Grow(constants, new_length, Heap::kOld)); | |
| 5052 cls.set_constants(new_constants); | |
| 5053 new_constants.SetAt(index, *this); | |
| 5054 } else { | |
| 5055 constants.SetAt(index, *this); | |
| 5056 } | 5053 } |
| 5057 return this->raw(); | 5054 return this->raw(); |
| 5058 } | 5055 } |
| 5059 | 5056 |
| 5060 | 5057 |
| 5061 RawType* Instance::GetType() const { | 5058 RawType* Instance::GetType() const { |
| 5062 if (IsNull()) { | 5059 if (IsNull()) { |
| 5063 return Type::NullType(); | 5060 return Type::NullType(); |
| 5064 } | 5061 } |
| 5065 const Class& cls = Class::Handle(clazz()); | 5062 const Class& cls = Class::Handle(clazz()); |
| (...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5841 for (int i = 0; i < slen; i++) { | 5838 for (int i = 0; i < slen; i++) { |
| 5842 if (this->CharAt(i) != other.CharAt(i)) { | 5839 if (this->CharAt(i) != other.CharAt(i)) { |
| 5843 return false; | 5840 return false; |
| 5844 } | 5841 } |
| 5845 } | 5842 } |
| 5846 return true; | 5843 return true; |
| 5847 } | 5844 } |
| 5848 | 5845 |
| 5849 | 5846 |
| 5850 RawInstance* String::Canonicalize() const { | 5847 RawInstance* String::Canonicalize() const { |
| 5848 if (IsCanonical()) { | |
| 5849 return this->raw(); | |
| 5850 } | |
| 5851 return NewSymbol(*this); | 5851 return NewSymbol(*this); |
| 5852 } | 5852 } |
| 5853 | 5853 |
| 5854 | 5854 |
| 5855 bool String::IsSymbol() const { | |
| 5856 if (!HasHash()) { | |
| 5857 // All symbols have had their hash calculated. | |
| 5858 return false; | |
| 5859 } | |
| 5860 | |
| 5861 // Get the hash for this string. | |
| 5862 intptr_t hash = Hash(); | |
| 5863 | |
| 5864 ObjectStore* object_store = Isolate::Current()->object_store(); | |
| 5865 const Array& symbol_table = Array::Handle(object_store->symbol_table()); | |
| 5866 // Last element of the array is the number of used elements. | |
| 5867 intptr_t table_size = symbol_table.Length() - 1; | |
| 5868 intptr_t index = hash % table_size; | |
| 5869 | |
| 5870 // Try to find this string object in the symbol table. The symbol table is | |
| 5871 // never entirely full so this loop will terminate. | |
| 5872 String& symbol = String::Handle(); | |
| 5873 symbol ^= symbol_table.At(index); | |
| 5874 while (!symbol.IsNull() && (raw_ptr() != symbol.raw_ptr())) { | |
| 5875 index = (index + 1) % table_size; // Move to next element. | |
| 5876 symbol ^= symbol_table.At(index); | |
| 5877 } | |
| 5878 | |
| 5879 // This string is a symbol if we found a matching entry. | |
| 5880 return !symbol.IsNull(); | |
| 5881 } | |
| 5882 | |
| 5883 | |
| 5884 RawString* String::New(const char* str, Heap::Space space) { | 5855 RawString* String::New(const char* str, Heap::Space space) { |
| 5885 intptr_t width = 0; | 5856 intptr_t width = 0; |
| 5886 intptr_t len = Utf8::CodePointCount(str, &width); | 5857 intptr_t len = Utf8::CodePointCount(str, &width); |
| 5887 if (width == 1) { | 5858 if (width == 1) { |
| 5888 const OneByteString& onestr | 5859 const OneByteString& onestr |
| 5889 = OneByteString::Handle(OneByteString::New(len, space)); | 5860 = OneByteString::Handle(OneByteString::New(len, space)); |
| 5890 if (len > 0) { | 5861 if (len > 0) { |
| 5891 NoGCScope no_gc; | 5862 NoGCScope no_gc; |
| 5892 Utf8::Decode(str, onestr.CharAddr(0), len); | 5863 Utf8::Decode(str, onestr.CharAddr(0), len); |
| 5893 } | 5864 } |
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6183 new_symbol_table.SetAt(new_table_size, new_element); | 6154 new_symbol_table.SetAt(new_table_size, new_element); |
| 6184 // Remember the new symbol table now. | 6155 // Remember the new symbol table now. |
| 6185 Isolate::Current()->object_store()->set_symbol_table(new_symbol_table); | 6156 Isolate::Current()->object_store()->set_symbol_table(new_symbol_table); |
| 6186 } | 6157 } |
| 6187 | 6158 |
| 6188 | 6159 |
| 6189 static void InsertIntoSymbolTable(const Array& symbol_table, | 6160 static void InsertIntoSymbolTable(const Array& symbol_table, |
| 6190 const String& symbol, | 6161 const String& symbol, |
| 6191 intptr_t index, | 6162 intptr_t index, |
| 6192 intptr_t table_size) { | 6163 intptr_t table_size) { |
| 6164 symbol.SetCanonical(); // Mark object as being canonical. | |
| 6193 symbol_table.SetAt(index, symbol); // Remember the new symbol. | 6165 symbol_table.SetAt(index, symbol); // Remember the new symbol. |
| 6194 Smi& used = Smi::Handle(); | 6166 Smi& used = Smi::Handle(); |
| 6195 used ^= symbol_table.At(table_size); | 6167 used ^= symbol_table.At(table_size); |
| 6196 intptr_t used_elements = used.Value() + 1; // One more element added. | 6168 intptr_t used_elements = used.Value() + 1; // One more element added. |
| 6197 used = Smi::New(used_elements); | 6169 used = Smi::New(used_elements); |
| 6198 symbol_table.SetAt(table_size, used); // Update used count. | 6170 symbol_table.SetAt(table_size, used); // Update used count. |
| 6199 | 6171 |
| 6200 // Rehash if symbol_table is 75% full. | 6172 // Rehash if symbol_table is 75% full. |
| 6201 if (used_elements > ((table_size / 4) * 3)) { | 6173 if (used_elements > ((table_size / 4) * 3)) { |
| 6202 GrowSymbolTable(symbol_table, table_size); | 6174 GrowSymbolTable(symbol_table, table_size); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6257 ASSERT(symbol.IsSymbol()); | 6229 ASSERT(symbol.IsSymbol()); |
| 6258 return symbol.raw(); | 6230 return symbol.raw(); |
| 6259 } | 6231 } |
| 6260 | 6232 |
| 6261 template RawString* String::NewSymbol(const uint8_t* characters, intptr_t len); | 6233 template RawString* String::NewSymbol(const uint8_t* characters, intptr_t len); |
| 6262 template RawString* String::NewSymbol(const uint16_t* characters, intptr_t len); | 6234 template RawString* String::NewSymbol(const uint16_t* characters, intptr_t len); |
| 6263 template RawString* String::NewSymbol(const uint32_t* characters, intptr_t len); | 6235 template RawString* String::NewSymbol(const uint32_t* characters, intptr_t len); |
| 6264 | 6236 |
| 6265 | 6237 |
| 6266 RawString* String::NewSymbol(const String& str) { | 6238 RawString* String::NewSymbol(const String& str) { |
| 6239 if (str.IsSymbol()) { | |
| 6240 return str.raw(); | |
| 6241 } | |
| 6267 return NewSymbol(str, 0, str.Length()); | 6242 return NewSymbol(str, 0, str.Length()); |
| 6268 } | 6243 } |
| 6269 | 6244 |
| 6270 | 6245 |
| 6271 RawString* String::NewSymbol(const String& str, | 6246 RawString* String::NewSymbol(const String& str, |
| 6272 intptr_t begin_index, | 6247 intptr_t begin_index, |
| 6273 intptr_t len) { | 6248 intptr_t len) { |
| 6274 ASSERT(begin_index >= 0); | 6249 ASSERT(begin_index >= 0); |
| 6275 ASSERT(len >= 0); | 6250 ASSERT(len >= 0); |
| 6276 ASSERT((begin_index + len) <= str.Length()); | 6251 ASSERT((begin_index + len) <= str.Length()); |
| (...skipping 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 7333 const String& str = String::Handle(pattern()); | 7308 const String& str = String::Handle(pattern()); |
| 7334 const char* format = "JSRegExp: pattern=%s flags=%s"; | 7309 const char* format = "JSRegExp: pattern=%s flags=%s"; |
| 7335 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); | 7310 intptr_t len = OS::SNPrint(NULL, 0, format, str.ToCString(), Flags()); |
| 7336 char* chars = reinterpret_cast<char*>( | 7311 char* chars = reinterpret_cast<char*>( |
| 7337 Isolate::Current()->current_zone()->Allocate(len + 1)); | 7312 Isolate::Current()->current_zone()->Allocate(len + 1)); |
| 7338 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); | 7313 OS::SNPrint(chars, (len + 1), format, str.ToCString(), Flags()); |
| 7339 return chars; | 7314 return chars; |
| 7340 } | 7315 } |
| 7341 | 7316 |
| 7342 } // namespace dart | 7317 } // namespace dart |
| OLD | NEW |