LCOV - code coverage report
Current view: top level - src/zone - zone-handle-set.h (source / functions) Hit Total Coverage
Test: app.info Lines: 45 47 95.7 %
Date: 2017-04-26 Functions: 4 5 80.0 %

          Line data    Source code
       1             : // Copyright 2016 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_ZONE_ZONE_HANDLE_SET_H_
       6             : #define V8_ZONE_ZONE_HANDLE_SET_H_
       7             : 
       8             : #include "src/handles.h"
       9             : #include "src/zone/zone.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : 
      14             : template <typename T>
      15             : class ZoneHandleSet final {
      16             :  public:
      17      357595 :   ZoneHandleSet() : data_(kEmptyTag) {}
      18             :   explicit ZoneHandleSet(Handle<T> handle)
      19      152452 :       : data_(bit_cast<intptr_t>(handle.address()) | kSingletonTag) {
      20             :     DCHECK(IsAligned(bit_cast<intptr_t>(handle.address()), kPointerAlignment));
      21             :   }
      22             : 
      23             :   bool is_empty() const { return data_ == kEmptyTag; }
      24             : 
      25             :   size_t size() const {
      26      388264 :     if ((data_ & kTagMask) == kEmptyTag) return 0;
      27      388142 :     if ((data_ & kTagMask) == kSingletonTag) return 1;
      28        6083 :     return list()->length();
      29             :   }
      30             : 
      31             :   Handle<T> at(size_t i) const {
      32             :     DCHECK_NE(kEmptyTag, data_ & kTagMask);
      33      245357 :     if ((data_ & kTagMask) == kSingletonTag) {
      34             :       DCHECK_EQ(0u, i);
      35             :       return Handle<T>(singleton());
      36             :     }
      37       14464 :     return Handle<T>(list()->at(static_cast<int>(i)));
      38             :   }
      39             : 
      40             :   Handle<T> operator[](size_t i) const { return at(i); }
      41             : 
      42       63189 :   void insert(Handle<T> handle, Zone* zone) {
      43             :     T** const value = bit_cast<T**>(handle.address());
      44             :     DCHECK(IsAligned(bit_cast<intptr_t>(value), kPointerAlignment));
      45       63189 :     if ((data_ & kTagMask) == kEmptyTag) {
      46       59937 :       data_ = bit_cast<intptr_t>(value) | kSingletonTag;
      47        3252 :     } else if ((data_ & kTagMask) == kSingletonTag) {
      48        2771 :       if (singleton() == value) return;
      49        2283 :       List* list = new (zone) List(2, zone);
      50        2283 :       if (singleton() < value) {
      51             :         list->Add(singleton(), zone);
      52             :         list->Add(value, zone);
      53             :       } else {
      54             :         list->Add(value, zone);
      55             :         list->Add(singleton(), zone);
      56             :       }
      57             :       DCHECK(IsAligned(bit_cast<intptr_t>(list), kPointerAlignment));
      58        2283 :       data_ = bit_cast<intptr_t>(list) | kListTag;
      59             :     } else {
      60             :       DCHECK_EQ(kListTag, data_ & kTagMask);
      61             :       List const* const old_list = list();
      62        2646 :       for (int i = 0; i < old_list->length(); ++i) {
      63        4054 :         if (old_list->at(i) == value) return;
      64         907 :         if (old_list->at(i) > value) break;
      65             :       }
      66         862 :       List* new_list = new (zone) List(old_list->length() + 1, zone);
      67             :       int i = 0;
      68        2440 :       for (; i < old_list->length(); ++i) {
      69             :         if (old_list->at(i) > value) break;
      70             :         new_list->Add(old_list->at(i), zone);
      71             :       }
      72             :       new_list->Add(value, zone);
      73         677 :       for (; i < old_list->length(); ++i) {
      74         123 :         new_list->Add(old_list->at(i), zone);
      75             :       }
      76             :       DCHECK_EQ(old_list->length() + 1, new_list->length());
      77             :       DCHECK(IsAligned(bit_cast<intptr_t>(new_list), kPointerAlignment));
      78         431 :       data_ = bit_cast<intptr_t>(new_list) | kListTag;
      79             :     }
      80             :   }
      81             : 
      82       37078 :   bool contains(ZoneHandleSet<T> const& other) const {
      83       37078 :     if (data_ == other.data_) return true;
      84        1419 :     if (data_ == kEmptyTag) return false;
      85        1419 :     if (other.data_ == kEmptyTag) return true;
      86        1419 :     if ((data_ & kTagMask) == kSingletonTag) return false;
      87             :     DCHECK_EQ(kListTag, data_ & kTagMask);
      88         678 :     if ((other.data_ & kTagMask) == kSingletonTag) {
      89          79 :       return list()->Contains(other.singleton());
      90             :     }
      91             :     DCHECK_EQ(kListTag, other.data_ & kTagMask);
      92             :     // TODO(bmeurer): Optimize this case.
      93        3205 :     for (int i = 0; i < other.list()->length(); ++i) {
      94        2606 :       if (!list()->Contains(other.list()->at(i))) return false;
      95             :     }
      96             :     return true;
      97             :   }
      98             : 
      99          62 :   void remove(Handle<T> handle, Zone* zone) {
     100             :     // TODO(bmeurer): Optimize this case.
     101             :     ZoneHandleSet<T> that;
     102         336 :     for (size_t i = 0; i < size(); ++i) {
     103             :       Handle<T> value = at(i);
     104         106 :       if (value.address() != handle.address()) {
     105          44 :         that.insert(value, zone);
     106             :       }
     107             :     }
     108             :     std::swap(*this, that);
     109          62 :   }
     110             : 
     111       33237 :   friend bool operator==(ZoneHandleSet<T> const& lhs,
     112             :                          ZoneHandleSet<T> const& rhs) {
     113       33237 :     if (lhs.data_ == rhs.data_) return true;
     114        1342 :     if ((lhs.data_ & kTagMask) == kListTag &&
     115             :         (rhs.data_ & kTagMask) == kListTag) {
     116             :       List const* const lhs_list = lhs.list();
     117             :       List const* const rhs_list = rhs.list();
     118          98 :       if (lhs_list->length() == rhs_list->length()) {
     119         279 :         for (int i = 0; i < lhs_list->length(); ++i) {
     120         558 :           if (lhs_list->at(i) != rhs_list->at(i)) return false;
     121             :         }
     122             :         return true;
     123             :       }
     124             :     }
     125             :     return false;
     126             :   }
     127             : 
     128             :   friend bool operator!=(ZoneHandleSet<T> const& lhs,
     129             :                          ZoneHandleSet<T> const& rhs) {
     130             :     return !(lhs == rhs);
     131             :   }
     132             : 
     133           0 :   friend size_t hash_value(ZoneHandleSet<T> const& set) {
     134           0 :     return static_cast<size_t>(set.data_);
     135             :   }
     136             : 
     137             :  private:
     138             :   typedef ZoneList<T**> List;
     139             : 
     140             :   List const* list() const {
     141             :     DCHECK_EQ(kListTag, data_ & kTagMask);
     142       17276 :     return bit_cast<List const*>(data_ - kListTag);
     143             :   }
     144             : 
     145             :   T** singleton() const {
     146             :     DCHECK_EQ(kSingletonTag, data_ & kTagMask);
     147        2421 :     return bit_cast<T**>(data_ - kSingletonTag);
     148             :   }
     149             : 
     150             :   enum Tag : intptr_t {
     151             :     kSingletonTag = 0,
     152             :     kEmptyTag = 1,
     153             :     kListTag = 2,
     154             :     kTagMask = 3
     155             :   };
     156             : 
     157             :   STATIC_ASSERT(kTagMask < kPointerAlignment);
     158             : 
     159             :   intptr_t data_;
     160             : };
     161             : 
     162             : }  // namespace internal
     163             : }  // namespace v8
     164             : 
     165             : #endif  // V8_ZONE_ZONE_HANDLE_SET_H_

Generated by: LCOV version 1.10