| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 // ... | 97 // ... |
| 98 // } | 98 // } |
| 99 // | 99 // |
| 100 // This is an example of the Curiously Recurring Template Pattern (see | 100 // This is an example of the Curiously Recurring Template Pattern (see |
| 101 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use | 101 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use |
| 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 explicit ElementsAccessorBase(const char* name) : ElementsAccessor(name) { } |
| 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::GetImpl( | 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* GetImpl(BackingStoreClass* backing_store, | 116 static MaybeObject* GetImpl(BackingStoreClass* backing_store, |
| 117 uint32_t key, | 117 uint32_t key, |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); | 273 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); |
| 274 }; | 274 }; |
| 275 | 275 |
| 276 | 276 |
| 277 // Super class for all fast element arrays. | 277 // Super class for all fast element arrays. |
| 278 template<typename FastElementsAccessorSubclass, | 278 template<typename FastElementsAccessorSubclass, |
| 279 typename BackingStore, | 279 typename BackingStore, |
| 280 int ElementSize> | 280 int ElementSize> |
| 281 class FastElementsAccessor | 281 class FastElementsAccessor |
| 282 : public ElementsAccessorBase<FastElementsAccessorSubclass, BackingStore> { | 282 : public ElementsAccessorBase<FastElementsAccessorSubclass, BackingStore> { |
| 283 public: |
| 284 explicit FastElementsAccessor(const char* name) |
| 285 : ElementsAccessorBase<FastElementsAccessorSubclass, |
| 286 BackingStore>(name) {} |
| 283 protected: | 287 protected: |
| 284 friend class ElementsAccessorBase<FastElementsAccessorSubclass, BackingStore>; | 288 friend class ElementsAccessorBase<FastElementsAccessorSubclass, BackingStore>; |
| 285 | 289 |
| 286 // Adjusts the length of the fast backing store or returns the new length or | 290 // Adjusts the length of the fast backing store or returns the new length or |
| 287 // undefined in case conversion to a slow backing store should be performed. | 291 // undefined in case conversion to a slow backing store should be performed. |
| 288 static MaybeObject* SetLengthWithoutNormalize(BackingStore* backing_store, | 292 static MaybeObject* SetLengthWithoutNormalize(BackingStore* backing_store, |
| 289 JSArray* array, | 293 JSArray* array, |
| 290 Object* length_object, | 294 Object* length_object, |
| 291 uint32_t length) { | 295 uint32_t length) { |
| 292 uint32_t old_capacity = backing_store->length(); | 296 uint32_t old_capacity = backing_store->length(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 332 return array->GetHeap()->undefined_value(); | 336 return array->GetHeap()->undefined_value(); |
| 333 } | 337 } |
| 334 }; | 338 }; |
| 335 | 339 |
| 336 | 340 |
| 337 class FastObjectElementsAccessor | 341 class FastObjectElementsAccessor |
| 338 : public FastElementsAccessor<FastObjectElementsAccessor, | 342 : public FastElementsAccessor<FastObjectElementsAccessor, |
| 339 FixedArray, | 343 FixedArray, |
| 340 kPointerSize> { | 344 kPointerSize> { |
| 341 public: | 345 public: |
| 346 explicit FastObjectElementsAccessor(const char* name) |
| 347 : FastElementsAccessor<FastObjectElementsAccessor, |
| 348 FixedArray, |
| 349 kPointerSize>(name) {} |
| 350 |
| 342 static MaybeObject* DeleteCommon(JSObject* obj, | 351 static MaybeObject* DeleteCommon(JSObject* obj, |
| 343 uint32_t key) { | 352 uint32_t key) { |
| 344 ASSERT(obj->HasFastElements() || | 353 ASSERT(obj->HasFastElements() || |
| 345 obj->HasFastSmiOnlyElements() || | 354 obj->HasFastSmiOnlyElements() || |
| 346 obj->HasFastArgumentsElements()); | 355 obj->HasFastArgumentsElements()); |
| 347 Heap* heap = obj->GetHeap(); | 356 Heap* heap = obj->GetHeap(); |
| 348 FixedArray* backing_store = FixedArray::cast(obj->elements()); | 357 FixedArray* backing_store = FixedArray::cast(obj->elements()); |
| 349 if (backing_store->map() == heap->non_strict_arguments_elements_map()) { | 358 if (backing_store->map() == heap->non_strict_arguments_elements_map()) { |
| 350 backing_store = FixedArray::cast(backing_store->get(1)); | 359 backing_store = FixedArray::cast(backing_store->get(1)); |
| 351 } else { | 360 } else { |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 407 JSReceiver::DeleteMode mode) { | 416 JSReceiver::DeleteMode mode) { |
| 408 return DeleteCommon(obj, key); | 417 return DeleteCommon(obj, key); |
| 409 } | 418 } |
| 410 }; | 419 }; |
| 411 | 420 |
| 412 | 421 |
| 413 class FastDoubleElementsAccessor | 422 class FastDoubleElementsAccessor |
| 414 : public FastElementsAccessor<FastDoubleElementsAccessor, | 423 : public FastElementsAccessor<FastDoubleElementsAccessor, |
| 415 FixedDoubleArray, | 424 FixedDoubleArray, |
| 416 kDoubleSize> { | 425 kDoubleSize> { |
| 426 public: |
| 427 explicit FastDoubleElementsAccessor(const char* name) |
| 428 : FastElementsAccessor<FastDoubleElementsAccessor, |
| 429 FixedDoubleArray, |
| 430 kDoubleSize>(name) {} |
| 431 |
| 417 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, | 432 static MaybeObject* SetFastElementsCapacityAndLength(JSObject* obj, |
| 418 uint32_t capacity, | 433 uint32_t capacity, |
| 419 uint32_t length) { | 434 uint32_t length) { |
| 420 return obj->SetFastDoubleElementsCapacityAndLength(capacity, length); | 435 return obj->SetFastDoubleElementsCapacityAndLength(capacity, length); |
| 421 } | 436 } |
| 422 | 437 |
| 423 protected: | 438 protected: |
| 424 friend class ElementsAccessorBase<FastDoubleElementsAccessor, | 439 friend class ElementsAccessorBase<FastDoubleElementsAccessor, |
| 425 FixedDoubleArray>; | 440 FixedDoubleArray>; |
| 426 friend class FastElementsAccessor<FastDoubleElementsAccessor, | 441 friend class FastElementsAccessor<FastDoubleElementsAccessor, |
| (...skipping 20 matching lines...) Expand all Loading... |
| 447 } | 462 } |
| 448 }; | 463 }; |
| 449 | 464 |
| 450 | 465 |
| 451 // Super class for all external element arrays. | 466 // Super class for all external element arrays. |
| 452 template<typename ExternalElementsAccessorSubclass, | 467 template<typename ExternalElementsAccessorSubclass, |
| 453 typename ExternalArray> | 468 typename ExternalArray> |
| 454 class ExternalElementsAccessor | 469 class ExternalElementsAccessor |
| 455 : public ElementsAccessorBase<ExternalElementsAccessorSubclass, | 470 : public ElementsAccessorBase<ExternalElementsAccessorSubclass, |
| 456 ExternalArray> { | 471 ExternalArray> { |
| 472 public: |
| 473 explicit ExternalElementsAccessor(const char* name) |
| 474 : ElementsAccessorBase<ExternalElementsAccessorSubclass, |
| 475 ExternalArray>(name) {} |
| 476 |
| 457 protected: | 477 protected: |
| 458 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass, | 478 friend class ElementsAccessorBase<ExternalElementsAccessorSubclass, |
| 459 ExternalArray>; | 479 ExternalArray>; |
| 460 | 480 |
| 461 static MaybeObject* GetImpl(ExternalArray* backing_store, | 481 static MaybeObject* GetImpl(ExternalArray* backing_store, |
| 462 uint32_t key, | 482 uint32_t key, |
| 463 JSObject* obj, | 483 JSObject* obj, |
| 464 Object* receiver) { | 484 Object* receiver) { |
| 465 return | 485 return |
| 466 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) | 486 key < ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store) |
| (...skipping 23 matching lines...) Expand all Loading... |
| 490 uint32_t capacity = | 510 uint32_t capacity = |
| 491 ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store); | 511 ExternalElementsAccessorSubclass::GetCapacityImpl(backing_store); |
| 492 return key < capacity; | 512 return key < capacity; |
| 493 } | 513 } |
| 494 }; | 514 }; |
| 495 | 515 |
| 496 | 516 |
| 497 class ExternalByteElementsAccessor | 517 class ExternalByteElementsAccessor |
| 498 : public ExternalElementsAccessor<ExternalByteElementsAccessor, | 518 : public ExternalElementsAccessor<ExternalByteElementsAccessor, |
| 499 ExternalByteArray> { | 519 ExternalByteArray> { |
| 520 public: |
| 521 explicit ExternalByteElementsAccessor(const char* name) |
| 522 : ExternalElementsAccessor<ExternalByteElementsAccessor, |
| 523 ExternalByteArray>(name) {} |
| 500 }; | 524 }; |
| 501 | 525 |
| 502 | 526 |
| 503 class ExternalUnsignedByteElementsAccessor | 527 class ExternalUnsignedByteElementsAccessor |
| 504 : public ExternalElementsAccessor<ExternalUnsignedByteElementsAccessor, | 528 : public ExternalElementsAccessor<ExternalUnsignedByteElementsAccessor, |
| 505 ExternalUnsignedByteArray> { | 529 ExternalUnsignedByteArray> { |
| 530 public: |
| 531 explicit ExternalUnsignedByteElementsAccessor(const char* name) |
| 532 : ExternalElementsAccessor<ExternalUnsignedByteElementsAccessor, |
| 533 ExternalUnsignedByteArray>(name) {} |
| 506 }; | 534 }; |
| 507 | 535 |
| 508 | 536 |
| 509 class ExternalShortElementsAccessor | 537 class ExternalShortElementsAccessor |
| 510 : public ExternalElementsAccessor<ExternalShortElementsAccessor, | 538 : public ExternalElementsAccessor<ExternalShortElementsAccessor, |
| 511 ExternalShortArray> { | 539 ExternalShortArray> { |
| 540 public: |
| 541 explicit ExternalShortElementsAccessor(const char* name) |
| 542 : ExternalElementsAccessor<ExternalShortElementsAccessor, |
| 543 ExternalShortArray>(name) {} |
| 512 }; | 544 }; |
| 513 | 545 |
| 514 | 546 |
| 515 class ExternalUnsignedShortElementsAccessor | 547 class ExternalUnsignedShortElementsAccessor |
| 516 : public ExternalElementsAccessor<ExternalUnsignedShortElementsAccessor, | 548 : public ExternalElementsAccessor<ExternalUnsignedShortElementsAccessor, |
| 517 ExternalUnsignedShortArray> { | 549 ExternalUnsignedShortArray> { |
| 550 public: |
| 551 explicit ExternalUnsignedShortElementsAccessor(const char* name) |
| 552 : ExternalElementsAccessor<ExternalUnsignedShortElementsAccessor, |
| 553 ExternalUnsignedShortArray>(name) {} |
| 518 }; | 554 }; |
| 519 | 555 |
| 520 | 556 |
| 521 class ExternalIntElementsAccessor | 557 class ExternalIntElementsAccessor |
| 522 : public ExternalElementsAccessor<ExternalIntElementsAccessor, | 558 : public ExternalElementsAccessor<ExternalIntElementsAccessor, |
| 523 ExternalIntArray> { | 559 ExternalIntArray> { |
| 560 public: |
| 561 explicit ExternalIntElementsAccessor(const char* name) |
| 562 : ExternalElementsAccessor<ExternalIntElementsAccessor, |
| 563 ExternalIntArray>(name) {} |
| 524 }; | 564 }; |
| 525 | 565 |
| 526 | 566 |
| 527 class ExternalUnsignedIntElementsAccessor | 567 class ExternalUnsignedIntElementsAccessor |
| 528 : public ExternalElementsAccessor<ExternalUnsignedIntElementsAccessor, | 568 : public ExternalElementsAccessor<ExternalUnsignedIntElementsAccessor, |
| 529 ExternalUnsignedIntArray> { | 569 ExternalUnsignedIntArray> { |
| 570 public: |
| 571 explicit ExternalUnsignedIntElementsAccessor(const char* name) |
| 572 : ExternalElementsAccessor<ExternalUnsignedIntElementsAccessor, |
| 573 ExternalUnsignedIntArray>(name) {} |
| 530 }; | 574 }; |
| 531 | 575 |
| 532 | 576 |
| 533 class ExternalFloatElementsAccessor | 577 class ExternalFloatElementsAccessor |
| 534 : public ExternalElementsAccessor<ExternalFloatElementsAccessor, | 578 : public ExternalElementsAccessor<ExternalFloatElementsAccessor, |
| 535 ExternalFloatArray> { | 579 ExternalFloatArray> { |
| 580 public: |
| 581 explicit ExternalFloatElementsAccessor(const char* name) |
| 582 : ExternalElementsAccessor<ExternalFloatElementsAccessor, |
| 583 ExternalFloatArray>(name) {} |
| 536 }; | 584 }; |
| 537 | 585 |
| 538 | 586 |
| 539 class ExternalDoubleElementsAccessor | 587 class ExternalDoubleElementsAccessor |
| 540 : public ExternalElementsAccessor<ExternalDoubleElementsAccessor, | 588 : public ExternalElementsAccessor<ExternalDoubleElementsAccessor, |
| 541 ExternalDoubleArray> { | 589 ExternalDoubleArray> { |
| 590 public: |
| 591 explicit ExternalDoubleElementsAccessor(const char* name) |
| 592 : ExternalElementsAccessor<ExternalDoubleElementsAccessor, |
| 593 ExternalDoubleArray>(name) {} |
| 542 }; | 594 }; |
| 543 | 595 |
| 544 | 596 |
| 545 class PixelElementsAccessor | 597 class PixelElementsAccessor |
| 546 : public ExternalElementsAccessor<PixelElementsAccessor, | 598 : public ExternalElementsAccessor<PixelElementsAccessor, |
| 547 ExternalPixelArray> { | 599 ExternalPixelArray> { |
| 600 public: |
| 601 explicit PixelElementsAccessor(const char* name) |
| 602 : ExternalElementsAccessor<PixelElementsAccessor, |
| 603 ExternalPixelArray>(name) {} |
| 548 }; | 604 }; |
| 549 | 605 |
| 550 | 606 |
| 551 class DictionaryElementsAccessor | 607 class DictionaryElementsAccessor |
| 552 : public ElementsAccessorBase<DictionaryElementsAccessor, | 608 : public ElementsAccessorBase<DictionaryElementsAccessor, |
| 553 SeededNumberDictionary> { | 609 SeededNumberDictionary> { |
| 554 public: | 610 public: |
| 611 explicit DictionaryElementsAccessor(const char* name) |
| 612 : ElementsAccessorBase<DictionaryElementsAccessor, |
| 613 SeededNumberDictionary>(name) {} |
| 614 |
| 555 // Adjusts the length of the dictionary backing store and returns the new | 615 // Adjusts the length of the dictionary backing store and returns the new |
| 556 // length according to ES5 section 15.4.5.2 behavior. | 616 // length according to ES5 section 15.4.5.2 behavior. |
| 557 static MaybeObject* SetLengthWithoutNormalize(SeededNumberDictionary* dict, | 617 static MaybeObject* SetLengthWithoutNormalize(SeededNumberDictionary* dict, |
| 558 JSArray* array, | 618 JSArray* array, |
| 559 Object* length_object, | 619 Object* length_object, |
| 560 uint32_t length) { | 620 uint32_t length) { |
| 561 if (length == 0) { | 621 if (length == 0) { |
| 562 // If the length of a slow array is reset to zero, we clear | 622 // If the length of a slow array is reset to zero, we clear |
| 563 // the array and flush backing storage. This has the added | 623 // the array and flush backing storage. This has the added |
| 564 // benefit that the array returns to fast mode. | 624 // benefit that the array returns to fast mode. |
| (...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 696 uint32_t index) { | 756 uint32_t index) { |
| 697 Object* key = dict->KeyAt(index); | 757 Object* key = dict->KeyAt(index); |
| 698 return Smi::cast(key)->value(); | 758 return Smi::cast(key)->value(); |
| 699 } | 759 } |
| 700 }; | 760 }; |
| 701 | 761 |
| 702 | 762 |
| 703 class NonStrictArgumentsElementsAccessor | 763 class NonStrictArgumentsElementsAccessor |
| 704 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor, | 764 : public ElementsAccessorBase<NonStrictArgumentsElementsAccessor, |
| 705 FixedArray> { | 765 FixedArray> { |
| 766 public: |
| 767 explicit NonStrictArgumentsElementsAccessor(const char* name) |
| 768 : ElementsAccessorBase<NonStrictArgumentsElementsAccessor, |
| 769 FixedArray>(name) {} |
| 706 protected: | 770 protected: |
| 707 friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor, | 771 friend class ElementsAccessorBase<NonStrictArgumentsElementsAccessor, |
| 708 FixedArray>; | 772 FixedArray>; |
| 709 | 773 |
| 710 static MaybeObject* GetImpl(FixedArray* parameter_map, | 774 static MaybeObject* GetImpl(FixedArray* parameter_map, |
| 711 uint32_t key, | 775 uint32_t key, |
| 712 JSObject* obj, | 776 JSObject* obj, |
| 713 Object* receiver) { | 777 Object* receiver) { |
| 714 Object* probe = GetParameterMapArg(obj, parameter_map, key); | 778 Object* probe = GetParameterMapArg(obj, parameter_map, key); |
| 715 if (!probe->IsTheHole()) { | 779 if (!probe->IsTheHole()) { |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 859 V(ExternalUnsignedIntElementsAccessor, EXTERNAL_UNSIGNED_INT_ELEMENTS) \ | 923 V(ExternalUnsignedIntElementsAccessor, EXTERNAL_UNSIGNED_INT_ELEMENTS) \ |
| 860 V(ExternalFloatElementsAccessor, EXTERNAL_FLOAT_ELEMENTS) \ | 924 V(ExternalFloatElementsAccessor, EXTERNAL_FLOAT_ELEMENTS) \ |
| 861 V(ExternalDoubleElementsAccessor, EXTERNAL_DOUBLE_ELEMENTS) \ | 925 V(ExternalDoubleElementsAccessor, EXTERNAL_DOUBLE_ELEMENTS) \ |
| 862 V(PixelElementsAccessor, EXTERNAL_PIXEL_ELEMENTS) | 926 V(PixelElementsAccessor, EXTERNAL_PIXEL_ELEMENTS) |
| 863 | 927 |
| 864 static struct ConcreteElementsAccessors { | 928 static struct ConcreteElementsAccessors { |
| 865 #define ACCESSOR_STRUCT(Class, Name) Class* Name##_handler; | 929 #define ACCESSOR_STRUCT(Class, Name) Class* Name##_handler; |
| 866 ELEMENTS_LIST(ACCESSOR_STRUCT) | 930 ELEMENTS_LIST(ACCESSOR_STRUCT) |
| 867 #undef ACCESSOR_STRUCT | 931 #undef ACCESSOR_STRUCT |
| 868 } element_accessors = { | 932 } element_accessors = { |
| 869 #define ACCESSOR_INIT(Class, Name) new Class(), | 933 #define ACCESSOR_INIT(Class, Name) new Class(#Name), |
| 870 ELEMENTS_LIST(ACCESSOR_INIT) | 934 ELEMENTS_LIST(ACCESSOR_INIT) |
| 871 #undef ACCESSOR_INIT | 935 #undef ACCESSOR_INIT |
| 872 }; | 936 }; |
| 873 | 937 |
| 874 static ElementsAccessor* accessor_array[] = { | 938 static ElementsAccessor* accessor_array[] = { |
| 875 #define ACCESSOR_ARRAY(Class, Name) element_accessors.Name##_handler, | 939 #define ACCESSOR_ARRAY(Class, Name) element_accessors.Name##_handler, |
| 876 ELEMENTS_LIST(ACCESSOR_ARRAY) | 940 ELEMENTS_LIST(ACCESSOR_ARRAY) |
| 877 #undef ACCESSOR_ARRAY | 941 #undef ACCESSOR_ARRAY |
| 878 }; | 942 }; |
| 879 | 943 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 940 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; | 1004 if (!maybe_obj->To(&new_backing_store)) return maybe_obj; |
| 941 new_backing_store->set(0, length); | 1005 new_backing_store->set(0, length); |
| 942 { MaybeObject* result = array->SetContent(new_backing_store); | 1006 { MaybeObject* result = array->SetContent(new_backing_store); |
| 943 if (result->IsFailure()) return result; | 1007 if (result->IsFailure()) return result; |
| 944 } | 1008 } |
| 945 return array; | 1009 return array; |
| 946 } | 1010 } |
| 947 | 1011 |
| 948 | 1012 |
| 949 } } // namespace v8::internal | 1013 } } // namespace v8::internal |
| OLD | NEW |