1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/elements-kind.h" 6 7 #include "src/api.h" 8 #include "src/base/lazy-instance.h" 9 #include "src/elements.h" 10 #include "src/objects.h" 11 12 namespace v8 { 13 namespace internal { 14 15 ElementsKindToShiftSize(ElementsKind elements_kind)16int ElementsKindToShiftSize(ElementsKind elements_kind) { 17 switch (elements_kind) { 18 case UINT8_ELEMENTS: 19 case INT8_ELEMENTS: 20 case UINT8_CLAMPED_ELEMENTS: 21 return 0; 22 case UINT16_ELEMENTS: 23 case INT16_ELEMENTS: 24 return 1; 25 case UINT32_ELEMENTS: 26 case INT32_ELEMENTS: 27 case FLOAT32_ELEMENTS: 28 return 2; 29 case FAST_DOUBLE_ELEMENTS: 30 case FAST_HOLEY_DOUBLE_ELEMENTS: 31 case FLOAT64_ELEMENTS: 32 return 3; 33 case FAST_SMI_ELEMENTS: 34 case FAST_ELEMENTS: 35 case FAST_HOLEY_SMI_ELEMENTS: 36 case FAST_HOLEY_ELEMENTS: 37 case DICTIONARY_ELEMENTS: 38 case FAST_SLOPPY_ARGUMENTS_ELEMENTS: 39 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS: 40 return kPointerSizeLog2; 41 } 42 UNREACHABLE(); 43 return 0; 44 } 45 46 GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind)47int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind) { 48 STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize); 49 50 if (IsFixedTypedArrayElementsKind(elements_kind)) { 51 return 0; 52 } else { 53 return FixedArray::kHeaderSize - kHeapObjectTag; 54 } 55 } 56 57 ElementsKindToString(ElementsKind kind)58const char* ElementsKindToString(ElementsKind kind) { 59 ElementsAccessor* accessor = ElementsAccessor::ForKind(kind); 60 return accessor->name(); 61 } 62 63 64 struct InitializeFastElementsKindSequence { Constructv8::internal::InitializeFastElementsKindSequence65 static void Construct( 66 ElementsKind** fast_elements_kind_sequence_ptr) { 67 ElementsKind* fast_elements_kind_sequence = 68 new ElementsKind[kFastElementsKindCount]; 69 *fast_elements_kind_sequence_ptr = fast_elements_kind_sequence; 70 STATIC_ASSERT(FAST_SMI_ELEMENTS == FIRST_FAST_ELEMENTS_KIND); 71 fast_elements_kind_sequence[0] = FAST_SMI_ELEMENTS; 72 fast_elements_kind_sequence[1] = FAST_HOLEY_SMI_ELEMENTS; 73 fast_elements_kind_sequence[2] = FAST_DOUBLE_ELEMENTS; 74 fast_elements_kind_sequence[3] = FAST_HOLEY_DOUBLE_ELEMENTS; 75 fast_elements_kind_sequence[4] = FAST_ELEMENTS; 76 fast_elements_kind_sequence[5] = FAST_HOLEY_ELEMENTS; 77 78 // Verify that kFastElementsKindPackedToHoley is correct. 79 STATIC_ASSERT(FAST_SMI_ELEMENTS + kFastElementsKindPackedToHoley == 80 FAST_HOLEY_SMI_ELEMENTS); 81 STATIC_ASSERT(FAST_DOUBLE_ELEMENTS + kFastElementsKindPackedToHoley == 82 FAST_HOLEY_DOUBLE_ELEMENTS); 83 STATIC_ASSERT(FAST_ELEMENTS + kFastElementsKindPackedToHoley == 84 FAST_HOLEY_ELEMENTS); 85 } 86 }; 87 88 89 static base::LazyInstance<ElementsKind*, 90 InitializeFastElementsKindSequence>::type 91 fast_elements_kind_sequence = LAZY_INSTANCE_INITIALIZER; 92 93 GetFastElementsKindFromSequenceIndex(int sequence_number)94ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number) { 95 DCHECK(sequence_number >= 0 && 96 sequence_number < kFastElementsKindCount); 97 return fast_elements_kind_sequence.Get()[sequence_number]; 98 } 99 100 GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind)101int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind) { 102 for (int i = 0; i < kFastElementsKindCount; ++i) { 103 if (fast_elements_kind_sequence.Get()[i] == elements_kind) { 104 return i; 105 } 106 } 107 UNREACHABLE(); 108 return 0; 109 } 110 111 GetNextTransitionElementsKind(ElementsKind kind)112ElementsKind GetNextTransitionElementsKind(ElementsKind kind) { 113 int index = GetSequenceIndexFromFastElementsKind(kind); 114 return GetFastElementsKindFromSequenceIndex(index + 1); 115 } 116 117 IsFastTransitionTarget(ElementsKind elements_kind)118static inline bool IsFastTransitionTarget(ElementsKind elements_kind) { 119 return IsFastElementsKind(elements_kind) || 120 elements_kind == DICTIONARY_ELEMENTS; 121 } 122 IsMoreGeneralElementsKindTransition(ElementsKind from_kind,ElementsKind to_kind)123bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind, 124 ElementsKind to_kind) { 125 if (IsFixedTypedArrayElementsKind(from_kind) || 126 IsFixedTypedArrayElementsKind(to_kind)) { 127 return false; 128 } 129 if (IsFastElementsKind(from_kind) && IsFastTransitionTarget(to_kind)) { 130 switch (from_kind) { 131 case FAST_SMI_ELEMENTS: 132 return to_kind != FAST_SMI_ELEMENTS; 133 case FAST_HOLEY_SMI_ELEMENTS: 134 return to_kind != FAST_SMI_ELEMENTS && 135 to_kind != FAST_HOLEY_SMI_ELEMENTS; 136 case FAST_DOUBLE_ELEMENTS: 137 return to_kind != FAST_SMI_ELEMENTS && 138 to_kind != FAST_HOLEY_SMI_ELEMENTS && 139 to_kind != FAST_DOUBLE_ELEMENTS; 140 case FAST_HOLEY_DOUBLE_ELEMENTS: 141 return to_kind == FAST_ELEMENTS || 142 to_kind == FAST_HOLEY_ELEMENTS; 143 case FAST_ELEMENTS: 144 return to_kind == FAST_HOLEY_ELEMENTS; 145 case FAST_HOLEY_ELEMENTS: 146 return false; 147 default: 148 return false; 149 } 150 } 151 return false; 152 } 153 154 155 } // namespace internal 156 } // namespace v8 157