| 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 |