Home | History | Annotate | Download | only in src
      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 
     16 int 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     case FAST_STRING_WRAPPER_ELEMENTS:
     41     case SLOW_STRING_WRAPPER_ELEMENTS:
     42       return kPointerSizeLog2;
     43     case NO_ELEMENTS:
     44       UNREACHABLE();
     45       return 0;
     46   }
     47   UNREACHABLE();
     48   return 0;
     49 }
     50 
     51 
     52 int GetDefaultHeaderSizeForElementsKind(ElementsKind elements_kind) {
     53   STATIC_ASSERT(FixedArray::kHeaderSize == FixedDoubleArray::kHeaderSize);
     54 
     55   if (IsFixedTypedArrayElementsKind(elements_kind)) {
     56     return 0;
     57   } else {
     58     return FixedArray::kHeaderSize - kHeapObjectTag;
     59   }
     60 }
     61 
     62 
     63 const char* ElementsKindToString(ElementsKind kind) {
     64   ElementsAccessor* accessor = ElementsAccessor::ForKind(kind);
     65   return accessor->name();
     66 }
     67 
     68 
     69 struct InitializeFastElementsKindSequence {
     70   static void Construct(
     71       ElementsKind** fast_elements_kind_sequence_ptr) {
     72     ElementsKind* fast_elements_kind_sequence =
     73         new ElementsKind[kFastElementsKindCount];
     74     *fast_elements_kind_sequence_ptr = fast_elements_kind_sequence;
     75     STATIC_ASSERT(FAST_SMI_ELEMENTS == FIRST_FAST_ELEMENTS_KIND);
     76     fast_elements_kind_sequence[0] = FAST_SMI_ELEMENTS;
     77     fast_elements_kind_sequence[1] = FAST_HOLEY_SMI_ELEMENTS;
     78     fast_elements_kind_sequence[2] = FAST_DOUBLE_ELEMENTS;
     79     fast_elements_kind_sequence[3] = FAST_HOLEY_DOUBLE_ELEMENTS;
     80     fast_elements_kind_sequence[4] = FAST_ELEMENTS;
     81     fast_elements_kind_sequence[5] = FAST_HOLEY_ELEMENTS;
     82 
     83     // Verify that kFastElementsKindPackedToHoley is correct.
     84     STATIC_ASSERT(FAST_SMI_ELEMENTS + kFastElementsKindPackedToHoley ==
     85                   FAST_HOLEY_SMI_ELEMENTS);
     86     STATIC_ASSERT(FAST_DOUBLE_ELEMENTS + kFastElementsKindPackedToHoley ==
     87                   FAST_HOLEY_DOUBLE_ELEMENTS);
     88     STATIC_ASSERT(FAST_ELEMENTS + kFastElementsKindPackedToHoley ==
     89                   FAST_HOLEY_ELEMENTS);
     90   }
     91 };
     92 
     93 
     94 static base::LazyInstance<ElementsKind*,
     95                           InitializeFastElementsKindSequence>::type
     96     fast_elements_kind_sequence = LAZY_INSTANCE_INITIALIZER;
     97 
     98 
     99 ElementsKind GetFastElementsKindFromSequenceIndex(int sequence_number) {
    100   DCHECK(sequence_number >= 0 &&
    101          sequence_number < kFastElementsKindCount);
    102   return fast_elements_kind_sequence.Get()[sequence_number];
    103 }
    104 
    105 
    106 int GetSequenceIndexFromFastElementsKind(ElementsKind elements_kind) {
    107   for (int i = 0; i < kFastElementsKindCount; ++i) {
    108     if (fast_elements_kind_sequence.Get()[i] == elements_kind) {
    109       return i;
    110     }
    111   }
    112   UNREACHABLE();
    113   return 0;
    114 }
    115 
    116 
    117 ElementsKind GetNextTransitionElementsKind(ElementsKind kind) {
    118   int index = GetSequenceIndexFromFastElementsKind(kind);
    119   return GetFastElementsKindFromSequenceIndex(index + 1);
    120 }
    121 
    122 
    123 static inline bool IsFastTransitionTarget(ElementsKind elements_kind) {
    124   return IsFastElementsKind(elements_kind) ||
    125       elements_kind == DICTIONARY_ELEMENTS;
    126 }
    127 
    128 bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
    129                                          ElementsKind to_kind) {
    130   if (IsFixedTypedArrayElementsKind(from_kind) ||
    131       IsFixedTypedArrayElementsKind(to_kind)) {
    132     return false;
    133   }
    134   if (IsFastElementsKind(from_kind) && IsFastTransitionTarget(to_kind)) {
    135     switch (from_kind) {
    136       case FAST_SMI_ELEMENTS:
    137         return to_kind != FAST_SMI_ELEMENTS;
    138       case FAST_HOLEY_SMI_ELEMENTS:
    139         return to_kind != FAST_SMI_ELEMENTS &&
    140             to_kind != FAST_HOLEY_SMI_ELEMENTS;
    141       case FAST_DOUBLE_ELEMENTS:
    142         return to_kind != FAST_SMI_ELEMENTS &&
    143             to_kind != FAST_HOLEY_SMI_ELEMENTS &&
    144             to_kind != FAST_DOUBLE_ELEMENTS;
    145       case FAST_HOLEY_DOUBLE_ELEMENTS:
    146         return to_kind == FAST_ELEMENTS ||
    147             to_kind == FAST_HOLEY_ELEMENTS;
    148       case FAST_ELEMENTS:
    149         return to_kind == FAST_HOLEY_ELEMENTS;
    150       case FAST_HOLEY_ELEMENTS:
    151         return false;
    152       default:
    153         return false;
    154     }
    155   }
    156   return false;
    157 }
    158 
    159 
    160 }  // namespace internal
    161 }  // namespace v8
    162