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 #ifndef V8_TRANSITIONS_INL_H_
      6 #define V8_TRANSITIONS_INL_H_
      7 
      8 #include "src/transitions.h"
      9 
     10 namespace v8 {
     11 namespace internal {
     12 
     13 
     14 #define FIELD_ADDR(p, offset) \
     15   (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
     16 
     17 #define WRITE_FIELD(p, offset, value) \
     18   (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
     19 
     20 #define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode)    \
     21   if (mode == UPDATE_WRITE_BARRIER) {                                   \
     22     heap->incremental_marking()->RecordWrite(                           \
     23       object, HeapObject::RawField(object, offset), value);             \
     24     if (heap->InNewSpace(value)) {                                      \
     25       heap->RecordWrite(object->address(), offset);                     \
     26     }                                                                   \
     27   }
     28 
     29 
     30 TransitionArray* TransitionArray::cast(Object* object) {
     31   DCHECK(object->IsTransitionArray());
     32   return reinterpret_cast<TransitionArray*>(object);
     33 }
     34 
     35 
     36 bool TransitionArray::HasElementsTransition() {
     37   return Search(GetHeap()->elements_transition_symbol()) != kNotFound;
     38 }
     39 
     40 
     41 Object* TransitionArray::back_pointer_storage() {
     42   return get(kBackPointerStorageIndex);
     43 }
     44 
     45 
     46 void TransitionArray::set_back_pointer_storage(Object* back_pointer,
     47                                                WriteBarrierMode mode) {
     48   Heap* heap = GetHeap();
     49   WRITE_FIELD(this, kBackPointerStorageOffset, back_pointer);
     50   CONDITIONAL_WRITE_BARRIER(
     51       heap, this, kBackPointerStorageOffset, back_pointer, mode);
     52 }
     53 
     54 
     55 bool TransitionArray::HasPrototypeTransitions() {
     56   return IsFullTransitionArray() &&
     57       get(kPrototypeTransitionsIndex) != Smi::FromInt(0);
     58 }
     59 
     60 
     61 FixedArray* TransitionArray::GetPrototypeTransitions() {
     62   DCHECK(IsFullTransitionArray());
     63   Object* prototype_transitions = get(kPrototypeTransitionsIndex);
     64   return FixedArray::cast(prototype_transitions);
     65 }
     66 
     67 
     68 void TransitionArray::SetPrototypeTransitions(FixedArray* transitions,
     69                                               WriteBarrierMode mode) {
     70   DCHECK(IsFullTransitionArray());
     71   DCHECK(transitions->IsFixedArray());
     72   Heap* heap = GetHeap();
     73   WRITE_FIELD(this, kPrototypeTransitionsOffset, transitions);
     74   CONDITIONAL_WRITE_BARRIER(
     75       heap, this, kPrototypeTransitionsOffset, transitions, mode);
     76 }
     77 
     78 
     79 Object** TransitionArray::GetPrototypeTransitionsSlot() {
     80   return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
     81                               kPrototypeTransitionsOffset);
     82 }
     83 
     84 
     85 Object** TransitionArray::GetKeySlot(int transition_number) {
     86   DCHECK(!IsSimpleTransition());
     87   DCHECK(transition_number < number_of_transitions());
     88   return RawFieldOfElementAt(ToKeyIndex(transition_number));
     89 }
     90 
     91 
     92 Name* TransitionArray::GetKey(int transition_number) {
     93   if (IsSimpleTransition()) {
     94     Map* target = GetTarget(kSimpleTransitionIndex);
     95     int descriptor = target->LastAdded();
     96     Name* key = target->instance_descriptors()->GetKey(descriptor);
     97     return key;
     98   }
     99   DCHECK(transition_number < number_of_transitions());
    100   return Name::cast(get(ToKeyIndex(transition_number)));
    101 }
    102 
    103 
    104 void TransitionArray::SetKey(int transition_number, Name* key) {
    105   DCHECK(!IsSimpleTransition());
    106   DCHECK(transition_number < number_of_transitions());
    107   set(ToKeyIndex(transition_number), key);
    108 }
    109 
    110 
    111 Map* TransitionArray::GetTarget(int transition_number) {
    112   if (IsSimpleTransition()) {
    113     DCHECK(transition_number == kSimpleTransitionIndex);
    114     return Map::cast(get(kSimpleTransitionTarget));
    115   }
    116   DCHECK(transition_number < number_of_transitions());
    117   return Map::cast(get(ToTargetIndex(transition_number)));
    118 }
    119 
    120 
    121 void TransitionArray::SetTarget(int transition_number, Map* value) {
    122   if (IsSimpleTransition()) {
    123     DCHECK(transition_number == kSimpleTransitionIndex);
    124     return set(kSimpleTransitionTarget, value);
    125   }
    126   DCHECK(transition_number < number_of_transitions());
    127   set(ToTargetIndex(transition_number), value);
    128 }
    129 
    130 
    131 PropertyDetails TransitionArray::GetTargetDetails(int transition_number) {
    132   Map* map = GetTarget(transition_number);
    133   return map->GetLastDescriptorDetails();
    134 }
    135 
    136 
    137 int TransitionArray::Search(Name* name) {
    138   if (IsSimpleTransition()) {
    139     Name* key = GetKey(kSimpleTransitionIndex);
    140     if (key->Equals(name)) return kSimpleTransitionIndex;
    141     return kNotFound;
    142   }
    143   return internal::Search<ALL_ENTRIES>(this, name);
    144 }
    145 
    146 
    147 void TransitionArray::NoIncrementalWriteBarrierSet(int transition_number,
    148                                                    Name* key,
    149                                                    Map* target) {
    150   FixedArray::NoIncrementalWriteBarrierSet(
    151       this, ToKeyIndex(transition_number), key);
    152   FixedArray::NoIncrementalWriteBarrierSet(
    153       this, ToTargetIndex(transition_number), target);
    154 }
    155 
    156 
    157 #undef FIELD_ADDR
    158 #undef WRITE_FIELD
    159 #undef CONDITIONAL_WRITE_BARRIER
    160 
    161 
    162 } }  // namespace v8::internal
    163 
    164 #endif  // V8_TRANSITIONS_INL_H_
    165