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 |