| 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* Delete(JSObject* obj, | 136 virtual MaybeObject* Delete(JSObject* obj, |
| 138 uint32_t key, | 137 uint32_t key, |
| 139 JSReceiver::DeleteMode mode) = 0; | 138 JSReceiver::DeleteMode mode) = 0; |
| 140 | 139 |
| 141 virtual MaybeObject* AddElementsToFixedArray(FixedArrayBase* from, | 140 virtual MaybeObject* AddElementsToFixedArray(FixedArrayBase* from, |
| 142 FixedArray* to, | 141 FixedArray* to, |
| 143 JSObject* holder, | 142 JSObject* holder, |
| 144 Object* receiver) { | 143 Object* receiver) { |
| 145 int len0 = to->length(); | 144 int len0 = to->length(); |
| 146 #ifdef DEBUG | 145 #ifdef DEBUG |
| 147 if (FLAG_enable_slow_asserts) { | 146 if (FLAG_enable_slow_asserts) { |
| 148 for (int i = 0; i < len0; i++) { | 147 for (int i = 0; i < len0; i++) { |
| 149 ASSERT(!to->get(i)->IsTheHole()); | 148 ASSERT(!to->get(i)->IsTheHole()); |
| 150 } | 149 } |
| 151 } | 150 } |
| 152 #endif | 151 #endif |
| 153 BackingStoreClass* backing_store = BackingStoreClass::cast(from); | 152 BackingStoreClass* backing_store = BackingStoreClass::cast(from); |
| 154 uint32_t len1 = ElementsAccessorSubclass::GetCapacity(backing_store); | 153 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(backing_store); |
| 155 | 154 |
| 156 // Optimize if 'other' is empty. | 155 // Optimize if 'other' is empty. |
| 157 // We cannot optimize if 'this' is empty, as other may have holes. | 156 // We cannot optimize if 'this' is empty, as other may have holes. |
| 158 if (len1 == 0) return to; | 157 if (len1 == 0) return to; |
| 159 | 158 |
| 160 // Compute how many elements are not in other. | 159 // Compute how many elements are not in other. |
| 161 int extra = 0; | 160 int extra = 0; |
| 162 for (uint32_t y = 0; y < len1; y++) { | 161 for (uint32_t y = 0; y < len1; y++) { |
| 163 if (ElementsAccessorSubclass::HasElementAtIndex(backing_store, | 162 if (ElementsAccessorSubclass::HasElementAtIndexImpl( |
| 164 y, | 163 backing_store, y, holder, receiver)) { |
| 165 holder, | |
| 166 receiver)) { | |
| 167 uint32_t key = | 164 uint32_t key = |
| 168 ElementsAccessorSubclass::GetKeyForIndex(backing_store, y); | 165 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); |
| 169 MaybeObject* maybe_value = | 166 MaybeObject* maybe_value = |
| 170 ElementsAccessorSubclass::Get(backing_store, key, holder, receiver); | 167 ElementsAccessorSubclass::GetImpl(backing_store, key, |
| 168 holder, receiver); |
| 171 Object* value; | 169 Object* value; |
| 172 if (!maybe_value->ToObject(&value)) return maybe_value; | 170 if (!maybe_value->ToObject(&value)) return maybe_value; |
| 173 ASSERT(!value->IsTheHole()); | 171 ASSERT(!value->IsTheHole()); |
| 174 if (!HasKey(to, value)) { | 172 if (!HasKey(to, value)) { |
| 175 extra++; | 173 extra++; |
| 176 } | 174 } |
| 177 } | 175 } |
| 178 } | 176 } |
| 179 | 177 |
| 180 if (extra == 0) return to; | 178 if (extra == 0) return to; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 191 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 189 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
| 192 for (int i = 0; i < len0; i++) { | 190 for (int i = 0; i < len0; i++) { |
| 193 Object* e = to->get(i); | 191 Object* e = to->get(i); |
| 194 ASSERT(e->IsString() || e->IsNumber()); | 192 ASSERT(e->IsString() || e->IsNumber()); |
| 195 result->set(i, e, mode); | 193 result->set(i, e, mode); |
| 196 } | 194 } |
| 197 } | 195 } |
| 198 // Fill in the extra values. | 196 // Fill in the extra values. |
| 199 int index = 0; | 197 int index = 0; |
| 200 for (uint32_t y = 0; y < len1; y++) { | 198 for (uint32_t y = 0; y < len1; y++) { |
| 201 if (ElementsAccessorSubclass::HasElementAtIndex(backing_store, | 199 if (ElementsAccessorSubclass::HasElementAtIndexImpl( |
| 202 y, | 200 backing_store, y, holder, receiver)) { |
| 203 holder, | |
| 204 receiver)) { | |
| 205 uint32_t key = | 201 uint32_t key = |
| 206 ElementsAccessorSubclass::GetKeyForIndex(backing_store, y); | 202 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, y); |
| 207 MaybeObject* maybe_value = | 203 MaybeObject* maybe_value = |
| 208 ElementsAccessorSubclass::Get(backing_store, key, holder, receiver); | 204 ElementsAccessorSubclass::GetImpl(backing_store, key, |
| 205 holder, receiver); |
| 209 Object* value; | 206 Object* value; |
| 210 if (!maybe_value->ToObject(&value)) return maybe_value; | 207 if (!maybe_value->ToObject(&value)) return maybe_value; |
| 211 if (!value->IsTheHole() && !HasKey(to, value)) { | 208 if (!value->IsTheHole() && !HasKey(to, value)) { |
| 212 result->set(len0 + index, value); | 209 result->set(len0 + index, value); |
| 213 index++; | 210 index++; |
| 214 } | 211 } |
| 215 } | 212 } |
| 216 } | 213 } |
| 217 ASSERT(extra == index); | 214 ASSERT(extra == index); |
| 218 return result; | 215 return result; |
| 219 } | 216 } |
| 220 | 217 |
| 221 protected: | 218 protected: |
| 222 static uint32_t GetCapacity(BackingStoreClass* backing_store) { | 219 static uint32_t GetCapacityImpl(BackingStoreClass* backing_store) { |
| 223 return backing_store->length(); | 220 return backing_store->length(); |
| 224 } | 221 } |
| 225 | 222 |
| 226 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { | 223 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) { |
| 227 return ElementsAccessorSubclass::GetCapacity( | 224 return ElementsAccessorSubclass::GetCapacityImpl( |
| 228 BackingStoreClass::cast(backing_store)); | 225 BackingStoreClass::cast(backing_store)); |
| 229 } | 226 } |
| 230 | 227 |
| 231 static bool HasElementAtIndex(BackingStoreClass* backing_store, | 228 static bool HasElementAtIndexImpl(BackingStoreClass* backing_store, |
| 232 uint32_t index, | 229 uint32_t index, |
| 233 JSObject* holder, | 230 JSObject* holder, |
| 234 Object* receiver) { | 231 Object* receiver) { |
| 235 uint32_t key = | 232 uint32_t key = |
| 236 ElementsAccessorSubclass::GetKeyForIndex(backing_store, index); | 233 ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index); |
| 237 MaybeObject* element = ElementsAccessorSubclass::Get(backing_store, | 234 MaybeObject* element = |
| 238 key, | 235 ElementsAccessorSubclass::GetImpl(backing_store, key, holder, receiver); |
| 239 holder, | |
| 240 receiver); | |
| 241 return !element->IsTheHole(); | 236 return !element->IsTheHole(); |
| 242 } | 237 } |
| 243 | 238 |
| 244 virtual bool HasElementAtIndex(FixedArrayBase* backing_store, | 239 virtual bool HasElementAtIndex(FixedArrayBase* backing_store, |
| 245 uint32_t index, | 240 uint32_t index, |
| 246 JSObject* holder, | 241 JSObject* holder, |
| 247 Object* receiver) { | 242 Object* receiver) { |
| 248 return ElementsAccessorSubclass::HasElementAtIndex( | 243 return ElementsAccessorSubclass::HasElementAtIndexImpl( |
| 249 BackingStoreClass::cast(backing_store), index, holder, receiver); | 244 BackingStoreClass::cast(backing_store), index, holder, receiver); |
| 250 } | 245 } |
| 251 | 246 |
| 252 static uint32_t GetKeyForIndex(BackingStoreClass* backing_store, | 247 static uint32_t GetKeyForIndexImpl(BackingStoreClass* backing_store, |
| 253 uint32_t index) { | 248 uint32_t index) { |
| 254 return index; | 249 return index; |
| 255 } | 250 } |
| 256 | 251 |
| 257 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, | 252 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, |
| 258 uint32_t index) { | 253 uint32_t index) { |
| 259 return ElementsAccessorSubclass::GetKeyForIndex( | 254 return ElementsAccessorSubclass::GetKeyForIndexImpl( |
| 260 BackingStoreClass::cast(backing_store), index); | 255 BackingStoreClass::cast(backing_store), index); |
| 261 } | 256 } |
| 262 | 257 |
| 263 private: | 258 private: |
| 264 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); | 259 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); |
| 265 }; | 260 }; |
| 266 | 261 |
| 267 | 262 |
| 268 // Super class for all fast element arrays. | 263 // Super class for all fast element arrays. |
| 269 template<typename FastElementsAccessorSubclass, | 264 template<typename FastElementsAccessorSubclass, |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 JSReceiver::DeleteMode mode) { | 418 JSReceiver::DeleteMode mode) { |
| 424 int length = obj->IsJSArray() | 419 int length = obj->IsJSArray() |
| 425 ? Smi::cast(JSArray::cast(obj)->length())->value() | 420 ? Smi::cast(JSArray::cast(obj)->length())->value() |
| 426 : FixedDoubleArray::cast(obj->elements())->length(); | 421 : FixedDoubleArray::cast(obj->elements())->length(); |
| 427 if (key < static_cast<uint32_t>(length)) { | 422 if (key < static_cast<uint32_t>(length)) { |
| 428 FixedDoubleArray::cast(obj->elements())->set_the_hole(key); | 423 FixedDoubleArray::cast(obj->elements())->set_the_hole(key); |
| 429 } | 424 } |
| 430 return obj->GetHeap()->true_value(); | 425 return obj->GetHeap()->true_value(); |
| 431 } | 426 } |
| 432 | 427 |
| 433 static bool HasElementAtIndex(FixedDoubleArray* backing_store, | 428 static bool HasElementAtIndexImpl(FixedDoubleArray* backing_store, |
| 434 uint32_t index, | 429 uint32_t index, |
| 435 JSObject* holder, | 430 JSObject* holder, |
| 436 Object* receiver) { | 431 Object* receiver) { |
| 437 return !backing_store->is_the_hole(index); | 432 return !backing_store->is_the_hole(index); |
| 438 } | 433 } |
| 439 }; | 434 }; |
| 440 | 435 |
| 441 | 436 |
| 442 // Super class for all external element arrays. | 437 // Super class for all external element arrays. |
| 443 template<typename ExternalElementsAccessorSubclass, | 438 template<typename ExternalElementsAccessorSubclass, |
| 444 typename ExternalArray> | 439 typename ExternalArray> |
| 445 class ExternalElementsAccessor | 440 class ExternalElementsAccessor |
| 446 : public ElementsAccessorBase<ExternalElementsAccessorSubclass, | 441 : public ElementsAccessorBase<ExternalElementsAccessorSubclass, |
| 447 ExternalArray> { | 442 ExternalArray> { |
| 448 protected: | 443 protected: |
| 449 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass, | 444 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass, |
| 450 ExternalArray>; | 445 ExternalArray>; |
| 451 | 446 |
| 452 static MaybeObject* Get(ExternalArray* backing_store, | 447 static MaybeObject* GetImpl(ExternalArray* backing_store, |
| 453 uint32_t key, | 448 uint32_t key, |
| 454 JSObject* obj, | 449 JSObject* obj, |
| 455 Object* receiver) { | 450 Object* receiver) { |
| 456 if (key < ExternalElementsAccessorSubclass::GetCapacity(backing_store)) { | 451 return |
| 457 return backing_store->get(key); | 452 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) |
| 458 } else { | 453 ? backing_store->get(key) |
| 459 return backing_store->GetHeap()->undefined_value(); | 454 : backing_store->GetHeap()->undefined_value(); |
| 460 } | |
| 461 } | 455 } |
| 462 | 456 |
| 463 static MaybeObject* SetLength(ExternalArray* backing_store, | 457 static MaybeObject* SetLengthImpl(ExternalArray* backing_store, |
| 464 JSObject* obj, | 458 JSObject* obj, |
| 465 Object* length) { | 459 Object* length) { |
| 466 // External arrays do not support changing their length. | 460 // External arrays do not support changing their length. |
| 467 UNREACHABLE(); | 461 UNREACHABLE(); |
| 468 return obj; | 462 return obj; |
| 469 } | 463 } |
| 470 | 464 |
| 471 virtual MaybeObject* Delete(JSObject* obj, | 465 virtual MaybeObject* Delete(JSObject* obj, |
| 472 uint32_t key, | 466 uint32_t key, |
| 473 JSReceiver::DeleteMode mode) { | 467 JSReceiver::DeleteMode mode) { |
| 474 // External arrays always ignore deletes. | 468 // External arrays always ignore deletes. |
| 475 return obj->GetHeap()->true_value(); | 469 return obj->GetHeap()->true_value(); |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 639 protected: | 633 protected: |
| 640 friend class ElementsAccessorBase<DictionaryElementsAccessor, | 634 friend class ElementsAccessorBase<DictionaryElementsAccessor, |
| 641 NumberDictionary>; | 635 NumberDictionary>; |
| 642 | 636 |
| 643 virtual MaybeObject* Delete(JSObject* obj, | 637 virtual MaybeObject* Delete(JSObject* obj, |
| 644 uint32_t key, | 638 uint32_t key, |
| 645 JSReceiver::DeleteMode mode) { | 639 JSReceiver::DeleteMode mode) { |
| 646 return DeleteCommon(obj, key, mode); | 640 return DeleteCommon(obj, key, mode); |
| 647 } | 641 } |
| 648 | 642 |
| 649 static MaybeObject* Get(NumberDictionary* backing_store, | 643 static MaybeObject* GetImpl(NumberDictionary* backing_store, |
| 650 uint32_t key, | 644 uint32_t key, |
| 651 JSObject* obj, | 645 JSObject* obj, |
| 652 Object* receiver) { | 646 Object* receiver) { |
| 653 int entry = backing_store->FindEntry(key); | 647 int entry = backing_store->FindEntry(key); |
| 654 if (entry != NumberDictionary::kNotFound) { | 648 if (entry != NumberDictionary::kNotFound) { |
| 655 Object* element = backing_store->ValueAt(entry); | 649 Object* element = backing_store->ValueAt(entry); |
| 656 PropertyDetails details = backing_store->DetailsAt(entry); | 650 PropertyDetails details = backing_store->DetailsAt(entry); |
| 657 if (details.type() == CALLBACKS) { | 651 if (details.type() == CALLBACKS) { |
| 658 return obj->GetElementWithCallback(receiver, | 652 return obj->GetElementWithCallback(receiver, |
| 659 element, | 653 element, |
| 660 key, | 654 key, |
| 661 obj); | 655 obj); |
| 662 } else { | 656 } else { |
| 663 return element; | 657 return element; |
| 664 } | 658 } |
| 665 } | 659 } |
| 666 return obj->GetHeap()->the_hole_value(); | 660 return obj->GetHeap()->the_hole_value(); |
| 667 } | 661 } |
| 668 | 662 |
| 669 static uint32_t GetKeyForIndex(NumberDictionary* dict, | 663 static uint32_t GetKeyForIndexImpl(NumberDictionary* dict, |
| 670 uint32_t index) { | 664 uint32_t index) { |
| 671 Object* key = dict->KeyAt(index); | 665 Object* key = dict->KeyAt(index); |
| 672 return Smi::cast(key)->value(); | 666 return Smi::cast(key)->value(); |
| 673 } | 667 } |
| 674 }; | 668 }; |
| 675 | 669 |
| 676 | 670 |
| 677 class NonStrictArgumentsElementsAccessor | 671 class NonStrictArgumentsElementsAccessor |
| 678 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor, | 672 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor, |
| 679 FixedArray> { | 673 FixedArray> { |
| 680 protected: | 674 protected: |
| 681 friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor, | 675 friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor, |
| 682 FixedArray>; | 676 FixedArray>; |
| 683 | 677 |
| 684 static MaybeObject* Get(FixedArray* parameter_map, | 678 static MaybeObject* GetImpl(FixedArray* parameter_map, |
| 685 uint32_t key, | 679 uint32_t key, |
| 686 JSObject* obj, | 680 JSObject* obj, |
| 687 Object* receiver) { | 681 Object* receiver) { |
| 688 Object* probe = GetParameterMapArg(parameter_map, key); | 682 Object* probe = GetParameterMapArg(parameter_map, key); |
| 689 if (!probe->IsTheHole()) { | 683 if (!probe->IsTheHole()) { |
| 690 Context* context = Context::cast(parameter_map->get(0)); | 684 Context* context = Context::cast(parameter_map->get(0)); |
| 691 int context_index = Smi::cast(probe)->value(); | 685 int context_index = Smi::cast(probe)->value(); |
| 692 ASSERT(!context->get(context_index)->IsTheHole()); | 686 ASSERT(!context->get(context_index)->IsTheHole()); |
| 693 return context->get(context_index); | 687 return context->get(context_index); |
| 694 } else { | 688 } else { |
| 695 // Object is not mapped, defer to the arguments. | 689 // Object is not mapped, defer to the arguments. |
| 696 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 690 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 697 return ElementsAccessor::ForArray(arguments)->Get(arguments, | 691 return ElementsAccessor::ForArray(arguments)->Get(arguments, |
| 698 key, | 692 key, |
| 699 obj, | 693 obj, |
| 700 receiver); | 694 receiver); |
| 701 } | 695 } |
| 702 } | 696 } |
| 703 | 697 |
| 704 static MaybeObject* SetLength(FixedArray* parameter_map, | 698 static MaybeObject* SetLengthImpl(FixedArray* parameter_map, |
| 705 JSObject* obj, | 699 JSObject* obj, |
| 706 Object* length) { | 700 Object* length) { |
| 707 // TODO(mstarzinger): This was never implemented but will be used once we | 701 // TODO(mstarzinger): This was never implemented but will be used once we |
| 708 // correctly implement [[DefineOwnProperty]] on arrays. | 702 // correctly implement [[DefineOwnProperty]] on arrays. |
| 709 UNIMPLEMENTED(); | 703 UNIMPLEMENTED(); |
| 710 return obj; | 704 return obj; |
| 711 } | 705 } |
| 712 | 706 |
| 713 virtual MaybeObject* Delete(JSObject* obj, | 707 virtual MaybeObject* Delete(JSObject* obj, |
| 714 uint32_t key, | 708 uint32_t key, |
| 715 JSReceiver::DeleteMode mode) { | 709 JSReceiver::DeleteMode mode) { |
| 716 FixedArray* parameter_map = FixedArray::cast(obj->elements()); | 710 FixedArray* parameter_map = FixedArray::cast(obj->elements()); |
| 717 Object* probe = GetParameterMapArg(parameter_map, key); | 711 Object* probe = GetParameterMapArg(parameter_map, key); |
| 718 if (!probe->IsTheHole()) { | 712 if (!probe->IsTheHole()) { |
| 719 // TODO(kmillikin): We could check if this was the last aliased | 713 // TODO(kmillikin): We could check if this was the last aliased |
| 720 // parameter, and revert to normal elements in that case. That | 714 // parameter, and revert to normal elements in that case. That |
| 721 // would enable GC of the context. | 715 // would enable GC of the context. |
| 722 parameter_map->set_the_hole(key + 2); | 716 parameter_map->set_the_hole(key + 2); |
| 723 } else { | 717 } else { |
| 724 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 718 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 725 if (arguments->IsDictionary()) { | 719 if (arguments->IsDictionary()) { |
| 726 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); | 720 return DictionaryElementsAccessor::DeleteCommon(obj, key, mode); |
| 727 } else { | 721 } else { |
| 728 return FastObjectElementsAccessor::DeleteCommon(obj, key); | 722 return FastObjectElementsAccessor::DeleteCommon(obj, key); |
| 729 } | 723 } |
| 730 } | 724 } |
| 731 return obj->GetHeap()->true_value(); | 725 return obj->GetHeap()->true_value(); |
| 732 } | 726 } |
| 733 | 727 |
| 734 static uint32_t GetCapacity(FixedArray* parameter_map) { | 728 static uint32_t GetCapacityImpl(FixedArray* parameter_map) { |
| 735 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 729 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
| 736 return Max(static_cast<uint32_t>(parameter_map->length() - 2), | 730 return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
| 737 ForArray(arguments)->GetCapacity(arguments)); | 731 ForArray(arguments)->GetCapacity(arguments)); |
| 738 } | 732 } |
| 739 | 733 |
| 740 static uint32_t GetKeyForIndex(FixedArray* dict, | 734 static uint32_t GetKeyForIndexImpl(FixedArray* dict, |
| 741 uint32_t index) { | 735 uint32_t index) { |
| 742 return index; | 736 return index; |
| 743 } | 737 } |
| 744 | 738 |
| 745 static bool HasElementAtIndex(FixedArray* parameter_map, | 739 static bool HasElementAtIndexImpl(FixedArray* parameter_map, |
| 746 uint32_t index, | 740 uint32_t index, |
| 747 JSObject* holder, | 741 JSObject* holder, |
| 748 Object* receiver) { | 742 Object* receiver) { |
| 749 Object* probe = GetParameterMapArg(parameter_map, index); | 743 Object* probe = GetParameterMapArg(parameter_map, index); |
| 750 if (!probe->IsTheHole()) { | 744 if (!probe->IsTheHole()) { |
| 751 return true; | 745 return true; |
| 752 } else { | 746 } else { |
| 753 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 747 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
| 754 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); | 748 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); |
| 755 return !accessor->Get(arguments, index, holder, receiver)->IsTheHole(); | 749 return !accessor->Get(arguments, index, holder, receiver)->IsTheHole(); |
| 756 } | 750 } |
| 757 } | 751 } |
| 758 | 752 |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 842 | 836 |
| 843 STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) == | 837 STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) == |
| 844 kElementsKindCount); | 838 kElementsKindCount); |
| 845 | 839 |
| 846 elements_accessors_ = accessor_array; | 840 elements_accessors_ = accessor_array; |
| 847 } | 841 } |
| 848 | 842 |
| 849 | 843 |
| 850 template <typename ElementsAccessorSubclass, typename BackingStoreClass> | 844 template <typename ElementsAccessorSubclass, typename BackingStoreClass> |
| 851 MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, BackingStoreClass>:: | 845 MaybeObject* ElementsAccessorBase<ElementsAccessorSubclass, BackingStoreClass>:: |
| 852 SetLength(BackingStoreClass* backing_store, | 846 SetLengthImpl(BackingStoreClass* backing_store, |
| 853 JSObject* obj, | 847 JSObject* obj, |
| 854 Object* length) { | 848 Object* length) { |
| 855 JSArray* array = JSArray::cast(obj); | 849 JSArray* array = JSArray::cast(obj); |
| 856 | 850 |
| 857 // Fast case: The new length fits into a Smi. | 851 // Fast case: The new length fits into a Smi. |
| 858 MaybeObject* maybe_smi_length = length->ToSmi(); | 852 MaybeObject* maybe_smi_length = length->ToSmi(); |
| 859 Object* smi_length = Smi::FromInt(0); | 853 Object* smi_length = Smi::FromInt(0); |
| 860 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { | 854 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { |
| 861 const int value = Smi::cast(smi_length)->value(); | 855 const int value = Smi::cast(smi_length)->value(); |
| 862 if (value >= 0) { | 856 if (value >= 0) { |
| 863 Object* new_length; | 857 Object* new_length; |
| 864 MaybeObject* result = ElementsAccessorSubclass:: | 858 MaybeObject* result = ElementsAccessorSubclass:: |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 899 FixedArray* new_backing_store; | 893 FixedArray* new_backing_store; |
| 900 MaybeObject* maybe_obj = array->GetHeap()->AllocateFixedArray(1); | 894 MaybeObject* maybe_obj = array->GetHeap()->AllocateFixedArray(1); |
| 901 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; | 895 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; |
| 902 new_backing_store->set(0, length); | 896 new_backing_store->set(0, length); |
| 903 array->SetContent(new_backing_store); | 897 array->SetContent(new_backing_store); |
| 904 return array; | 898 return array; |
| 905 } | 899 } |
| 906 | 900 |
| 907 | 901 |
| 908 } } // namespace v8::internal | 902 } } // namespace v8::internal |
| OLD | NEW |