LCOV - code coverage report
Current view: top level - src - transitions-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 40 46 87.0 %
Date: 2017-10-20 Functions: 7 7 100.0 %

          Line data    Source code
       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             : #include "src/ic/handler-configuration-inl.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : 
      15             : template <TransitionsAccessor::Encoding enc>
      16             : WeakCell* TransitionsAccessor::GetTargetCell() {
      17             :   DCHECK(!needs_reload_);
      18    46563197 :   if (target_cell_ != nullptr) return target_cell_;
      19             :   if (enc == kWeakCell) {
      20    26781564 :     target_cell_ = WeakCell::cast(raw_transitions_);
      21             :   } else if (enc == kHandler) {
      22      251191 :     target_cell_ = StoreHandler::GetTransitionCell(raw_transitions_);
      23             :   } else {
      24             :     UNREACHABLE();
      25             :   }
      26             :   return target_cell_;
      27             : }
      28             : 
      29             : TransitionArray* TransitionsAccessor::transitions() {
      30             :   DCHECK_EQ(kFullTransitionArray, encoding());
      31             :   return TransitionArray::cast(raw_transitions_);
      32             : }
      33             : 
      34             : // static
      35      659042 : TransitionArray* TransitionArray::cast(Object* object) {
      36             :   DCHECK(object->IsTransitionArray());
      37      659042 :   return reinterpret_cast<TransitionArray*>(object);
      38             : }
      39             : 
      40             : 
      41             : bool TransitionArray::HasPrototypeTransitions() {
      42             :   return get(kPrototypeTransitionsIndex) != Smi::kZero;
      43             : }
      44             : 
      45             : 
      46             : FixedArray* TransitionArray::GetPrototypeTransitions() {
      47             :   DCHECK(HasPrototypeTransitions());  // Callers must check first.
      48             :   Object* prototype_transitions = get(kPrototypeTransitionsIndex);
      49             :   return FixedArray::cast(prototype_transitions);
      50             : }
      51             : 
      52             : 
      53             : void TransitionArray::SetPrototypeTransitions(FixedArray* transitions) {
      54             :   DCHECK(transitions->IsFixedArray());
      55      182456 :   set(kPrototypeTransitionsIndex, transitions);
      56             : }
      57             : 
      58             : 
      59             : Object** TransitionArray::GetPrototypeTransitionsSlot() {
      60             :   return RawFieldOfElementAt(kPrototypeTransitionsIndex);
      61             : }
      62             : 
      63             : 
      64             : Object** TransitionArray::GetKeySlot(int transition_number) {
      65             :   DCHECK(transition_number < number_of_transitions());
      66             :   return RawFieldOfElementAt(ToKeyIndex(transition_number));
      67             : }
      68             : 
      69             : 
      70             : Name* TransitionArray::GetKey(int transition_number) {
      71             :   DCHECK(transition_number < number_of_transitions());
      72             :   return Name::cast(get(ToKeyIndex(transition_number)));
      73             : }
      74             : 
      75         504 : Name* TransitionsAccessor::GetKey(int transition_number) {
      76             :   WeakCell* cell = nullptr;
      77         252 :   switch (encoding()) {
      78             :     case kPrototypeInfo:
      79             :     case kUninitialized:
      80           0 :       UNREACHABLE();
      81             :       return nullptr;
      82             :     case kWeakCell:
      83             :       cell = GetTargetCell<kWeakCell>();
      84           6 :       break;
      85             :     case kHandler:
      86             :       cell = GetTargetCell<kHandler>();
      87           0 :       break;
      88             :     case kFullTransitionArray:
      89         246 :       return transitions()->GetKey(transition_number);
      90             :   }
      91             :   DCHECK(!cell->cleared());
      92           6 :   return GetSimpleTransitionKey(Map::cast(cell->value()));
      93             : }
      94             : 
      95             : void TransitionArray::SetKey(int transition_number, Name* key) {
      96             :   DCHECK(transition_number < number_of_transitions());
      97    10036245 :   set(ToKeyIndex(transition_number), key);
      98             : }
      99             : 
     100             : Object** TransitionArray::GetTargetSlot(int transition_number) {
     101             :   DCHECK(transition_number < number_of_transitions());
     102             :   return RawFieldOfElementAt(ToTargetIndex(transition_number));
     103             : }
     104             : 
     105             : // static
     106             : PropertyDetails TransitionsAccessor::GetTargetDetails(Name* name, Map* target) {
     107             :   DCHECK(!IsSpecialTransition(name));
     108             :   int descriptor = target->LastAdded();
     109             :   DescriptorArray* descriptors = target->instance_descriptors();
     110             :   // Transitions are allowed only for the last added property.
     111             :   DCHECK(descriptors->GetKey(descriptor)->Equals(name));
     112    11019469 :   return descriptors->GetDetails(descriptor);
     113             : }
     114             : 
     115             : // static
     116    23946736 : Map* TransitionsAccessor::GetTargetFromRaw(Object* raw) {
     117    47850936 :   if (raw->IsWeakCell()) return Map::cast(WeakCell::cast(raw)->value());
     118       85072 :   return Map::cast(StoreHandler::GetTransitionCell(raw)->value());
     119             : }
     120             : 
     121    34037887 : Object* TransitionArray::GetRawTarget(int transition_number) {
     122             :   DCHECK(transition_number < number_of_transitions());
     123    34037887 :   return get(ToTargetIndex(transition_number));
     124             : }
     125             : 
     126             : Map* TransitionArray::GetTarget(int transition_number) {
     127    23946737 :   Object* raw = GetRawTarget(transition_number);
     128    23946737 :   return TransitionsAccessor::GetTargetFromRaw(raw);
     129             : }
     130             : 
     131    42179648 : Map* TransitionsAccessor::GetTarget(int transition_number) {
     132             :   WeakCell* cell = nullptr;
     133    21089824 :   switch (encoding()) {
     134             :     case kPrototypeInfo:
     135             :     case kUninitialized:
     136           0 :       UNREACHABLE();
     137             :       return nullptr;
     138             :     case kWeakCell:
     139             :       cell = GetTargetCell<kWeakCell>();
     140    21086286 :       break;
     141             :     case kHandler:
     142             :       cell = GetTargetCell<kHandler>();
     143        2449 :       break;
     144             :     case kFullTransitionArray:
     145        1089 :       return transitions()->GetTarget(transition_number);
     146             :   }
     147             :   DCHECK(!cell->cleared());
     148    21088735 :   return Map::cast(cell->value());
     149             : }
     150             : 
     151             : void TransitionArray::SetTarget(int transition_number, Object* value) {
     152             :   DCHECK(!value->IsMap());
     153             :   DCHECK(transition_number < number_of_transitions());
     154    10058728 :   set(ToTargetIndex(transition_number), value);
     155             : }
     156             : 
     157             : 
     158    12789039 : int TransitionArray::SearchName(Name* name, int* out_insertion_index) {
     159             :   DCHECK(name->IsUniqueName());
     160             :   return internal::Search<ALL_ENTRIES>(this, name, number_of_entries(),
     161    12789039 :                                        out_insertion_index);
     162             : }
     163             : 
     164             : int TransitionArray::CompareKeys(Name* key1, uint32_t hash1, PropertyKind kind1,
     165             :                                  PropertyAttributes attributes1, Name* key2,
     166             :                                  uint32_t hash2, PropertyKind kind2,
     167             :                                  PropertyAttributes attributes2) {
     168             :   int cmp = CompareNames(key1, hash1, key2, hash2);
     169           0 :   if (cmp != 0) return cmp;
     170             : 
     171             :   return CompareDetails(kind1, attributes1, kind2, attributes2);
     172             : }
     173             : 
     174             : int TransitionArray::CompareNames(Name* key1, uint32_t hash1, Name* key2,
     175             :                                   uint32_t hash2) {
     176           0 :   if (key1 != key2) {
     177             :     // In case of hash collisions key1 is always "less" than key2.
     178           0 :     return hash1 <= hash2 ? -1 : 1;
     179             :   }
     180             : 
     181             :   return 0;
     182             : }
     183             : 
     184             : int TransitionArray::CompareDetails(PropertyKind kind1,
     185             :                                     PropertyAttributes attributes1,
     186             :                                     PropertyKind kind2,
     187             :                                     PropertyAttributes attributes2) {
     188    10697626 :   if (kind1 != kind2) {
     189       15258 :     return static_cast<int>(kind1) < static_cast<int>(kind2) ? -1 : 1;
     190             :   }
     191             : 
     192    10682368 :   if (attributes1 != attributes2) {
     193        9473 :     return static_cast<int>(attributes1) < static_cast<int>(attributes2) ? -1
     194        9473 :                                                                          : 1;
     195             :   }
     196             : 
     197             :   return 0;
     198             : }
     199             : 
     200      588090 : void TransitionArray::Set(int transition_number, Name* key, Object* target) {
     201      588090 :   set(ToKeyIndex(transition_number), key);
     202      588090 :   set(ToTargetIndex(transition_number), target);
     203      588090 : }
     204             : 
     205             : int TransitionArray::Capacity() {
     206      493802 :   if (length() <= kFirstIndex) return 0;
     207      490002 :   return (length() - kFirstIndex) / kTransitionSize;
     208             : }
     209             : 
     210             : void TransitionArray::SetNumberOfTransitions(int number_of_transitions) {
     211             :   DCHECK(number_of_transitions <= Capacity());
     212             :   set(kTransitionLengthIndex, Smi::FromInt(number_of_transitions));
     213             : }
     214             : 
     215             : }  // namespace internal
     216             : }  // namespace v8
     217             : 
     218             : #endif  // V8_TRANSITIONS_INL_H_

Generated by: LCOV version 1.10