OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and | 102 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and |
103 // specialization of SomeElementsAccessor methods). | 103 // specialization of SomeElementsAccessor methods). |
104 template <typename ElementsAccessorSubclass, typename BackingStoreClass> | 104 template <typename ElementsAccessorSubclass, typename BackingStoreClass> |
105 class ElementsAccessorBase : public ElementsAccessor { | 105 class ElementsAccessorBase : public ElementsAccessor { |
106 protected: | 106 protected: |
107 ElementsAccessorBase() { } | 107 ElementsAccessorBase() { } |
108 virtual MaybeObject* Get(FixedArrayBase* backing_store, | 108 virtual MaybeObject* Get(FixedArrayBase* backing_store, |
109 uint32_t key, | 109 uint32_t key, |
110 JSObject* obj, | 110 JSObject* obj, |
111 Object* receiver) { | 111 Object* receiver) { |
112 return ElementsAccessorSubclass::Get( | 112 return ElementsAccessorSubclass::GetImpl( |
113 BackingStoreClass::cast(backing_store), key, obj, receiver); | 113 BackingStoreClass::cast(backing_store), key, obj, receiver); |
114 } | 114 } |
115 | 115 |
116 static MaybeObject* Get(BackingStoreClass* backing_store, | 116 static MaybeObject* GetImpl(BackingStoreClass* backing_store, |
117 uint32_t key, | 117 uint32_t key, |
118 JSObject* obj, | 118 JSObject* obj, |
119 Object* receiver) { | 119 Object* receiver) { |
120 if (key < ElementsAccessorSubclass::GetCapacity(backing_store)) { | 120 return (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) |
121 return backing_store->get(key); | 121 ? backing_store->get(key) |
122 } | 122 : backing_store->GetHeap()->the_hole_value(); |
123 return backing_store->GetHeap()->the_hole_value(); | |
124 } | 123 } |
125 | 124 |
126 virtual MaybeObject* SetLength(JSObject* obj, | 125 virtual MaybeObject* SetLength(JSObject* obj, |
127 Object* length) { | 126 Object* length) { |
128 ASSERT(obj->IsJSArray()); | 127 ASSERT(obj->IsJSArray()); |
129 return ElementsAccessorSubclass::SetLength( | 128 return ElementsAccessorSubclass::SetLengthImpl( |
130 BackingStoreClass::cast(obj->elements()), obj, length); | 129 BackingStoreClass::cast(obj->elements()), obj, length); |
131 } | 130 } |
132 | 131 |
133 static MaybeObject* SetLength(BackingStoreClass* backing_store, | 132 static MaybeObject* SetLengthImpl(BackingStoreClass* backing_store, |
134 JSObject* obj, | 133 JSObject* obj, |
135 Object* length); | 134 Object* length); |
136 | 135 |
137 virtual MaybeObject* SetCapacityAndLength(JSArray* array, | 136 virtual MaybeObject* SetCapacityAndLength(JSArray* array, |
138 int capacity, | 137 int capacity, |
139 int length) { | 138 int length) { |
140 return ElementsAccessorSubclass::SetFastElementsCapacityAndLength( | 139 return ElementsAccessorSubclass::SetFastElementsCapacityAndLength( |
141 array, | 140 array, |
142 capacity, | 141 capacity, |
143 length); | 142 length); |
144 } | 143 } |
145 | 144 |
(...skipping 14 matching lines...) Expand all Loading... |
160 Object* receiver) { | 159 Object* receiver) { |
161 int len0 = to->length(); | 160 int len0 = to->length(); |
162 #ifdef DEBUG | 161 #ifdef DEBUG |
163 if (FLAG_enable_slow_asserts) { | 162 if (FLAG_enable_slow_asserts) { |
164 for (int i = 0; i < len0; i++) { | 163 for (int i = 0; i < len0; i++) { |
165 ASSERT(!to->get(i)->IsTheHole()); | 164 ASSERT(!to->get(i)->IsTheHole()); |
166 } | 165 } |
167 } | 166 } |
168 #endif | 167 #endif |
169 BackingStoreClass* backing_store = BackingStoreClass::cast(from); | 168 BackingStoreClass* backing_store = BackingStoreClass::cast(from); |
170 uint32_t len1 = ElementsAccessorSubclass::GetCapacity(backing_store); | 169 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store); |
171 | 170 |
172 // Optimize if 'other' is empty. | 171 // Optimize if 'other' is empty. |
173 // We cannot optimize if 'this' is empty, as other may have holes. | 172 // We cannot optimize if 'this' is empty, as other may have holes. |
174 if (len1 == 0) return to; | 173 if (len1 == 0) return to; |
175 | 174 |
176 // Compute how many elements are not in other. | 175 // Compute how many elements are not in other. |
177 int extra = 0; | 176 int extra = 0; |
178 for (uint32_t y = 0; y < len1; y++) { | 177 for (uint32_t y = 0; y < len1; y++) { |
179 if (ElementsAccessorSubclass::HasElementAtIndex(backing_store, | 178 if (ElementsAccessorSubclass::HasElementAtIndexImpl( |
180 y, | 179 backing_store, y, holder, receiver)) { |
181 holder, | |
182 receiver)) { | |
183 uint32_t key = | 180 uint32_t key = |
184 ElementsAccessorSubclass::GetKeyForIndex(backing_store, y); | 181 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); |
185 MaybeObject* maybe_value = | 182 MaybeObject* maybe_value = |
186 ElementsAccessorSubclass::Get(backing_store, key, holder, receiver); | 183 ElementsAccessorSubclass::GetImpl(backing_store, key, |
| 184 holder, receiver); |
187 Object* value; | 185 Object* value; |
188 if (!maybe_value->ToObject(&value)) return maybe_value; | 186 if (!maybe_value->ToObject(&value)) return maybe_value; |
189 ASSERT(!value->IsTheHole()); | 187 ASSERT(!value->IsTheHole()); |
190 if (!HasKey(to, value)) { | 188 if (!HasKey(to, value)) { |
191 extra++; | 189 extra++; |
192 } | 190 } |
193 } | 191 } |
194 } | 192 } |
195 | 193 |
196 if (extra == 0) return to; | 194 if (extra == 0) return to; |
(...skipping 10 matching lines...) Expand all Loading... |
207 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 205 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
208 for (int i = 0; i < len0; i++) { | 206 for (int i = 0; i < len0; i++) { |
209 Object* e = to->get(i); | 207 Object* e = to->get(i); |
210 ASSERT(e->IsString() || e->IsNumber()); | 208 ASSERT(e->IsString() || e->IsNumber()); |
211 result->set(i, e, mode); | 209 result->set(i, e, mode); |
212 } | 210 } |
213 } | 211 } |
214 // Fill in the extra values. | 212 // Fill in the extra values. |
215 int index = 0; | 213 int index = 0; |
216 for (uint32_t y = 0; y < len1; y++) { | 214 for (uint32_t y = 0; y < len1; y++) { |
217 if (ElementsAccessorSubclass::HasElementAtIndex(backing_store, | 215 if (ElementsAccessorSubclass::HasElementAtIndexImpl( |
218 y, | 216 backing_store, y, holder, receiver)) { |
219 holder, | |
220 receiver)) { | |
221 uint32_t key = | 217 uint32_t key = |
222 ElementsAccessorSubclass::GetKeyForIndex(backing_store, y); | 218 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); |
223 MaybeObject* maybe_value = | 219 MaybeObject* maybe_value = |
224 ElementsAccessorSubclass::Get(backing_store, key, holder, receiver); | 220 ElementsAccessorSubclass::GetImpl(backing_store, key, |
| 221 holder, receiver); |
225 Object* value; | 222 Object* value; |
226 if (!maybe_value->ToObject(&value)) return maybe_value; | 223 if (!maybe_value->ToObject(&value)) return maybe_value; |
227 if (!value->IsTheHole() && !HasKey(to, value)) { | 224 if (!value->IsTheHole() && !HasKey(to, value)) { |
228 result->set(len0 + index, value); | 225 result->set(len0 + index, value); |
229 index++; | 226 index++; |
230 } | 227 } |
231 } | 228 } |
232 } | 229 } |
233 ASSERT(extra == index); | 230 ASSERT(extra == index); |
234 return result; | 231 return result; |
235 } | 232 } |
236 | 233 |
237 protected: | 234 protected: |
238 static uint32_t GetCapacity(BackingStoreClass* backing_store) { | 235 static uint32_t GetCapacityImpl(BackingStoreClass* backing_store) { |
239 return backing_store->length(); | 236 return backing_store->length(); |
240 } | 237 } |
241 | 238 |
242 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { | 239 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { |
243 return ElementsAccessorSubclass::GetCapacity( | 240 return ElementsAccessorSubclass::GetCapacityImpl( |
244 BackingStoreClass::cast(backing_store)); | 241 BackingStoreClass::cast(backing_store)); |
245 } | 242 } |
246 | 243 |
247 static bool HasElementAtIndex(BackingStoreClass* backing_store, | 244 static bool HasElementAtIndexImpl(BackingStoreClass* backing_store, |
248 uint32_t index, | 245 uint32_t index, |
249 JSObject* holder, | 246 JSObject* holder, |
250 Object* receiver) { | 247 Object* receiver) { |
251 uint32_t key = | 248 uint32_t key = |
252 ElementsAccessorSubclass::GetKeyForIndex(backing_store, index); | 249 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index); |
253 MaybeObject* element = ElementsAccessorSubclass::Get(backing_store, | 250 MaybeObject* element = |
254 key, | 251 ElementsAccessorSubclass::GetImpl(backing_store, key, holder, receiver); |
255 holder, | |
256 receiver); | |
257 return !element->IsTheHole(); | 252 return !element->IsTheHole(); |
258 } | 253 } |
259 | 254 |
260 virtual bool HasElementAtIndex(FixedArrayBase* backing_store, | 255 virtual bool HasElementAtIndex(FixedArrayBase* backing_store, |
261 uint32_t index, | 256 uint32_t index, |
262 JSObject* holder, | 257 JSObject* holder, |
263 Object* receiver) { | 258 Object* receiver) { |
264 return ElementsAccessorSubclass::HasElementAtIndex( | 259 return ElementsAccessorSubclass::HasElementAtIndexImpl( |
265 BackingStoreClass::cast(backing_store), index, holder, receiver); | 260 BackingStoreClass::cast(backing_store), index, holder, receiver); |
266 } | 261 } |
267 | 262 |
268 static uint32_t GetKeyForIndex(BackingStoreClass* backing_store, | 263 static uint32_t GetKeyForIndexImpl(BackingStoreClass* backing_store, |
269 uint32_t index) { | 264 uint32_t index) { |
270 return index; | 265 return index; |
271 } | 266 } |
272 | 267 |
273 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, | 268 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, |
274 uint32_t index) { | 269 uint32_t index) { |
275 return ElementsAccessorSubclass::GetKeyForIndex( | 270 return ElementsAccessorSubclass::GetKeyForIndexImpl( |
276 BackingStoreClass::cast(backing_store), index); | 271 BackingStoreClass::cast(backing_store), index); |
277 } | 272 } |
278 | 273 |
279 private: | 274 private: |
280 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); | 275 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); |
281 }; | 276 }; |
282 | 277 |
283 | 278 |
284 // Super class for all fast element arrays. | 279 // Super class for all fast element arrays. |
285 template<typename FastElementsAccessorSubclass, | 280 template<typename FastElementsAccessorSubclass, |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 JSReceiver::DeleteMode mode) { | 434 JSReceiver::DeleteMode mode) { |
440 int length = obj->IsJSArray() | 435 int length = obj->IsJSArray() |
441 ? Smi::cast(JSArray::cast(obj)->length())->value() | 436 ? Smi::cast(JSArray::cast(obj)->length())->value() |
442 : FixedDoubleArray::cast(obj->elements())->length(); | 437 : FixedDoubleArray::cast(obj->elements())->length(); |
443 if (key < static_cast<uint32_t>(length)) { | 438 if (key < static_cast<uint32_t>(length)) { |
444 FixedDoubleArray::cast(obj->elements())->set_the_hole(key); | 439 FixedDoubleArray::cast(obj->elements())->set_the_hole(key); |
445 } | 440 } |
446 return obj->GetHeap()->true_value(); | 441 return obj->GetHeap()->true_value(); |
447 } | 442 } |
448 | 443 |
449 static bool HasElementAtIndex(FixedDoubleArray* backing_store, | 444 static bool HasElementAtIndexImpl(FixedDoubleArray* backing_store, |
450 uint32_t index, | 445 uint32_t index, |
451 JSObject* holder, | 446 JSObject* holder, |
452 Object* receiver) { | 447 Object* receiver) { |
453 return !backing_store->is_the_hole(index); | 448 return !backing_store->is_the_hole(index); |
454 } | 449 } |
455 }; | 450 }; |
456 | 451 |
457 | 452 |
458 // Super class for all external element arrays. | 453 // Super class for all external element arrays. |
459 template<typename ExternalElementsAccessorSubclass, | 454 template<typename ExternalElementsAccessorSubclass, |
460 typename ExternalArray> | 455 typename ExternalArray> |
461 class ExternalElementsAccessor | 456 class ExternalElementsAccessor |
462 : public ElementsAccessorBase<ExternalElementsAccessorSubclass, | 457 : public ElementsAccessorBase<ExternalElementsAccessorSubclass, |
463 ExternalArray> { | 458 ExternalArray> { |
464 protected: | 459 protected: |
465 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass, | 460 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass, |
466 ExternalArray>; | 461 ExternalArray>; |
467 | 462 |
468 static MaybeObject* Get(ExternalArray* backing_store, | 463 static MaybeObject* GetImpl(ExternalArray* backing_store, |
469 uint32_t key, | 464 uint32_t key, |
470 JSObject* obj, | 465 JSObject* obj, |
471 Object* receiver) { | 466 Object* receiver) { |
472 if (key < ExternalElementsAccessorSubclass::GetCapacity(backing_store)) { | 467 return |
473 return backing_store->get(key); | 468 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) |
474 } else { | 469 ? backing_store->get(key) |
475 return backing_store->GetHeap()->undefined_value(); | 470 : backing_store->GetHeap()->undefined_value(); |
476 } | |
477 } | 471 } |
478 | 472 |
479 static MaybeObject* SetLength(ExternalArray* backing_store, | 473 static MaybeObject* SetLengthImpl(ExternalArray* backing_store, |
480 JSObject* obj, | 474 JSObject* obj, |
481 Object* length) { | 475 Object* length) { |
482 // External arrays do not support changing their length. | 476 // External arrays do not support changing their length. |
483 UNREACHABLE(); | 477 UNREACHABLE(); |
484 return obj; | 478 return obj; |
485 } | 479 } |
486 | 480 |
487 virtual MaybeObject* Delete(JSObject* obj, | 481 virtual MaybeObject* Delete(JSObject* obj, |
488 uint32_t key, | 482 uint32_t key, |
489 JSReceiver::DeleteMode mode) { | 483 JSReceiver::DeleteMode mode) { |
490 // External arrays always ignore deletes. | 484 // External arrays always ignore deletes. |
491 return obj->GetHeap()->true_value(); | 485 return obj->GetHeap()->true_value(); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 protected: | 650 protected: |
657 friend class ElementsAccessorBase<DictionaryElementsAccessor, | 651 friend class ElementsAccessorBase<DictionaryElementsAccessor, |
658 SeededNumberDictionary>; | 652 SeededNumberDictionary>; |
659 | 653 |
660 virtual MaybeObject* Delete(JSObject* obj, | 654 virtual MaybeObject* Delete(JSObject* obj, |
661 uint32_t key, | 655 uint32_t key, |
662 JSReceiver::DeleteMode mode) { | 656 JSReceiver::DeleteMode mode) { |
663 return DeleteCommon(obj, key, mode); | 657 return DeleteCommon(obj, key, mode); |
664 } | 658 } |
665 | 659 |
666 static MaybeObject* Get(SeededNumberDictionary* backing_store, | 660 static MaybeObject* GetImpl(SeededNumberDictionary* backing_store, |
667 uint32_t key, | 661 uint32_t key, |
668 JSObject* obj, | 662 JSObject* obj, |
669 Object* receiver) { | 663 Object* receiver) { |
670 int entry = backing_store->FindEntry(key); | 664 int entry = backing_store->FindEntry(key); |
671 if (entry != SeededNumberDictionary::kNotFound) { | 665 if (entry != SeededNumberDictionary::kNotFound) { |
672 Object* element = backing_store->ValueAt(entry); | 666 Object* element = backing_store->ValueAt(entry); |
673 PropertyDetails details = backing_store->DetailsAt(entry); | 667 PropertyDetails details = backing_store->DetailsAt(entry); |
674 if (details.type() == CALLBACKS) { | 668 if (details.type() == CALLBACKS) { |
675 return obj->GetElementWithCallback(receiver, | 669 return obj->GetElementWithCallback(receiver, |
676 element, | 670 element, |
677 key, | 671 key, |
678 obj); | 672 obj); |
679 } else { | 673 } else { |
680 return element; | 674 return element; |
681 } | 675 } |
682 } | 676 } |
683 return obj->GetHeap()->the_hole_value(); | 677 return obj->GetHeap()->the_hole_value(); |
684 } | 678 } |
685 | 679 |
686 static uint32_t GetKeyForIndex(SeededNumberDictionary* dict, | 680 static uint32_t GetKeyForIndexImpl(SeededNumberDictionary* dict, |
687 uint32_t index) { | 681 uint32_t index) { |
688 Object* key = dict->KeyAt(index); | 682 Object* key = dict->KeyAt(index); |
689 return Smi::cast(key)->value(); | 683 return Smi::cast(key)->value(); |
690 } | 684 } |
691 }; | 685 }; |
692 | 686 |
693 | 687 |
694 class NonStrictArgumentsElementsAccessor | 688 class NonStrictArgumentsElementsAccessor |
695 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor, | 689 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor, |
696 FixedArray> { | 690 FixedArray> { |
697 protected: | 691 protected: |
698 friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor, | 692 friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor, |
699 FixedArray>; | 693 FixedArray>; |
700 | 694 |
701 static MaybeObject* Get(FixedArray* parameter_map, | 695 static MaybeObject* GetImpl(FixedArray* parameter_map, |
702 uint32_t key, | 696 uint32_t key, |
703 JSObject* obj, | 697 JSObject* obj, |
704 Object* receiver) { | 698 Object* receiver) { |
705 Object* probe = GetParameterMapArg(parameter_map, key); | 699 Object* probe = GetParameterMapArg(parameter_map, key); |
706 if (!probe->IsTheHole()) { | 700 if (!probe->IsTheHole()) { |
707 Context* context = Context::cast(parameter_map->get(0)); | 701 Context* context = Context::cast(parameter_map->get(0)); |
708 int context_index = Smi::cast(probe)->value(); | 702 int context_index = Smi::cast(probe)->value(); |
709 ASSERT(!context->get(context_index)->IsTheHole()); | 703 ASSERT(!context->get(context_index)->IsTheHole()); |
710 return context->get(context_index); | 704 return context->get(context_index); |
711 } else { | 705 } else { |
712 // Object is not mapped, defer to the arguments. | 706 // Object is not mapped, defer to the arguments. |
713 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 707 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
714 return ElementsAccessor::ForArray(arguments)->Get(arguments, | 708 return ElementsAccessor::ForArray(arguments)->Get(arguments, |
715 key, | 709 key, |
716 obj, | 710 obj, |
717 receiver); | 711 receiver); |
718 } | 712 } |
719 } | 713 } |
720 | 714 |
721 static MaybeObject* SetLength(FixedArray* parameter_map, | 715 static MaybeObject* SetLengthImpl(FixedArray* parameter_map, |
722 JSObject* obj, | 716 JSObject* obj, |
723 Object* length) { | 717 Object* length) { |
724 // TODO(mstarzinger): This was never implemented but will be used once we | 718 // TODO(mstarzinger): This was never implemented but will be used once we |
725 // correctly implement [[DefineOwnProperty]] on arrays. | 719 // correctly implement [[DefineOwnProperty]] on arrays. |
726 UNIMPLEMENTED(); | 720 UNIMPLEMENTED(); |
727 return obj; | 721 return obj; |
728 } | 722 } |
729 | 723 |
730 virtual MaybeObject* Delete(JSObject* obj, | 724 virtual MaybeObject* Delete(JSObject* obj, |
731 uint32_t key, | 725 uint32_t key, |
732 JSReceiver::DeleteMode mode) { | 726 JSReceiver::DeleteMode mode) { |
733 FixedArray* parameter_map = FixedArray::cast(obj->elements()); | 727 FixedArray* parameter_map = FixedArray::cast(obj->elements()); |
734 Object* probe = GetParameterMapArg(parameter_map, key); | 728 Object* probe = GetParameterMapArg(parameter_map, key); |
735 if (!probe->IsTheHole()) { | 729 if (!probe->IsTheHole()) { |
736 // TODO(kmillikin): We could check if this was the last aliased | 730 // TODO(kmillikin): We could check if this was the last aliased |
737 // parameter, and revert to normal elements in that case. That | 731 // parameter, and revert to normal elements in that case. That |
738 // would enable GC of the context. | 732 // would enable GC of the context. |
739 parameter_map->set_the_hole(key + 2); | 733 parameter_map->set_the_hole(key + 2); |
740 } else { | 734 } else { |
741 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 735 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
742 if (arguments->IsDictionary()) { | 736 if (arguments->IsDictionary()) { |
743 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); | 737 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); |
744 } else { | 738 } else { |
745 return FastObjectElementsAccessor::DeleteCommon(obj, key); | 739 return FastObjectElementsAccessor::DeleteCommon(obj, key); |
746 } | 740 } |
747 } | 741 } |
748 return obj->GetHeap()->true_value(); | 742 return obj->GetHeap()->true_value(); |
749 } | 743 } |
750 | 744 |
751 static uint32_t GetCapacity(FixedArray* parameter_map) { | 745 static uint32_t GetCapacityImpl(FixedArray* parameter_map) { |
752 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 746 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
753 return Max(static_cast<uint32_t>(parameter_map->length() - 2), | 747 return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
754 ForArray(arguments)->GetCapacity(arguments)); | 748 ForArray(arguments)->GetCapacity(arguments)); |
755 } | 749 } |
756 | 750 |
757 static uint32_t GetKeyForIndex(FixedArray* dict, | 751 static uint32_t GetKeyForIndexImpl(FixedArray* dict, |
758 uint32_t index) { | 752 uint32_t index) { |
759 return index; | 753 return index; |
760 } | 754 } |
761 | 755 |
762 static bool HasElementAtIndex(FixedArray* parameter_map, | 756 static bool HasElementAtIndexImpl(FixedArray* parameter_map, |
763 uint32_t index, | 757 uint32_t index, |
764 JSObject* holder, | 758 JSObject* holder, |
765 Object* receiver) { | 759 Object* receiver) { |
766 Object* probe = GetParameterMapArg(parameter_map, index); | 760 Object* probe = GetParameterMapArg(parameter_map, index); |
767 if (!probe->IsTheHole()) { | 761 if (!probe->IsTheHole()) { |
768 return true; | 762 return true; |
769 } else { | 763 } else { |
770 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 764 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
771 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); | 765 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); |
772 return !accessor->Get(arguments, index, holder, receiver)->IsTheHole(); | 766 return !accessor->Get(arguments, index, holder, receiver)->IsTheHole(); |
773 } | 767 } |
774 } | 768 } |
775 | 769 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
859 | 853 |
860 STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) == | 854 STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) == |
861 kElementsKindCount); | 855 kElementsKindCount); |
862 | 856 |
863 elements_accessors_ = accessor_array; | 857 elements_accessors_ = accessor_array; |
864 } | 858 } |
865 | 859 |
866 | 860 |
867 template <typename ElementsAccessorSubclass, typename BackingStoreClass> | 861 template <typename ElementsAccessorSubclass, typename BackingStoreClass> |
868 MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, BackingStoreClass>:: | 862 MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, BackingStoreClass>:: |
869 SetLength(BackingStoreClass* backing_store, | 863 SetLengthImpl(BackingStoreClass* backing_store, |
870 JSObject* obj, | 864 JSObject* obj, |
871 Object* length) { | 865 Object* length) { |
872 JSArray* array = JSArray::cast(obj); | 866 JSArray* array = JSArray::cast(obj); |
873 | 867 |
874 // Fast case: The new length fits into a Smi. | 868 // Fast case: The new length fits into a Smi. |
875 MaybeObject* maybe_smi_length = length->ToSmi(); | 869 MaybeObject* maybe_smi_length = length->ToSmi(); |
876 Object* smi_length = Smi::FromInt(0); | 870 Object* smi_length = Smi::FromInt(0); |
877 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { | 871 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { |
878 const int value = Smi::cast(smi_length)->value(); | 872 const int value = Smi::cast(smi_length)->value(); |
879 if (value >= 0) { | 873 if (value >= 0) { |
880 Object* new_length; | 874 Object* new_length; |
881 MaybeObject* result = ElementsAccessorSubclass:: | 875 MaybeObject* result = ElementsAccessorSubclass:: |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
916 FixedArray* new_backing_store; | 910 FixedArray* new_backing_store; |
917 MaybeObject* maybe_obj = array->GetHeap()->AllocateFixedArray(1); | 911 MaybeObject* maybe_obj = array->GetHeap()->AllocateFixedArray(1); |
918 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; | 912 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; |
919 new_backing_store->set(0, length); | 913 new_backing_store->set(0, length); |
920 array->SetContent(new_backing_store); | 914 array->SetContent(new_backing_store); |
921 return array; | 915 return array; |
922 } | 916 } |
923 | 917 |
924 | 918 |
925 } } // namespace v8::internal | 919 } } // namespace v8::internal |
OLD | NEW |