LCOV - code coverage report
Current view: top level - src/objects - slots-atomic-inl.h (source / functions) Hit Total Coverage
Test: app.info Lines: 12 12 100.0 %
Date: 2019-02-19 Functions: 2 2 100.0 %

          Line data    Source code
       1             : // Copyright 2018 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_OBJECTS_SLOTS_ATOMIC_INL_H_
       6             : #define V8_OBJECTS_SLOTS_ATOMIC_INL_H_
       7             : 
       8             : #include "src/base/atomic-utils.h"
       9             : #include "src/objects/slots.h"
      10             : 
      11             : namespace v8 {
      12             : namespace internal {
      13             : 
      14             : // This class is intended to be used as a wrapper for elements of an array
      15             : // that is passed in to STL functions such as std::sort. It ensures that
      16             : // elements accesses are atomic.
      17             : // Usage example:
      18             : //   FixedArray array;
      19             : //   AtomicSlot start(array->GetFirstElementAddress());
      20             : //   std::sort(start, start + given_length,
      21             : //             [](Tagged_t a, Tagged_t b) {
      22             : //               // Decompress a and b if necessary.
      23             : //               return my_comparison(a, b);
      24             : //             });
      25             : // Note how the comparator operates on Address values, representing the raw
      26             : // data found at the given heap location, so you probably want to construct
      27             : // an Object from it.
      28             : class AtomicSlot : public SlotBase<AtomicSlot, Tagged_t, kTaggedSize> {
      29             :  public:
      30             :   // This class is a stand-in for "Address&" that uses custom atomic
      31             :   // read/write operations for the actual memory accesses.
      32             :   class Reference {
      33             :    public:
      34             :     explicit Reference(Tagged_t* address) : address_(address) {}
      35             :     Reference(const Reference&) V8_NOEXCEPT = default;
      36             : 
      37    35034700 :     Reference& operator=(const Reference& other) V8_NOEXCEPT {
      38             :       AsAtomicTagged::Relaxed_Store(
      39    70069400 :           address_, AsAtomicTagged::Relaxed_Load(other.address_));
      40    35034700 :       return *this;
      41             :     }
      42             :     Reference& operator=(Tagged_t value) {
      43             :       AsAtomicTagged::Relaxed_Store(address_, value);
      44             :       return *this;
      45             :     }
      46             : 
      47             :     // Values of type AtomicSlot::reference must be implicitly convertible
      48             :     // to AtomicSlot::value_type.
      49    66549017 :     operator Tagged_t() const { return AsAtomicTagged::Relaxed_Load(address_); }
      50             : 
      51    13648399 :     void swap(Reference& other) {
      52             :       Address tmp = value();
      53    13648399 :       AsAtomicTagged::Relaxed_Store(address_, other.value());
      54    13648399 :       AsAtomicTagged::Relaxed_Store(other.address_, tmp);
      55    13648399 :     }
      56             : 
      57             :     bool operator<(const Reference& other) const {
      58             :       return value() < other.value();
      59             :     }
      60             : 
      61             :     bool operator==(const Reference& other) const {
      62             :       return value() == other.value();
      63             :     }
      64             : 
      65             :    private:
      66    27296798 :     Address value() const { return AsAtomicTagged::Relaxed_Load(address_); }
      67             : 
      68             :     Tagged_t* address_;
      69             :   };
      70             : 
      71             :   // The rest of this class follows C++'s "RandomAccessIterator" requirements.
      72             :   // Most of the heavy lifting is inherited from SlotBase.
      73             :   typedef int difference_type;
      74             :   typedef Tagged_t value_type;
      75             :   typedef Reference reference;
      76             :   typedef void* pointer;  // Must be present, but should not be used.
      77             :   typedef std::random_access_iterator_tag iterator_category;
      78             : 
      79             :   AtomicSlot() : SlotBase(kNullAddress) {}
      80             :   explicit AtomicSlot(Address address) : SlotBase(address) {}
      81             :   explicit AtomicSlot(ObjectSlot slot) : SlotBase(slot.address()) {}
      82             : 
      83             :   Reference operator*() const {
      84   190183738 :     return Reference(reinterpret_cast<Tagged_t*>(address()));
      85             :   }
      86             :   Reference operator[](difference_type i) const {
      87             :     return Reference(reinterpret_cast<Tagged_t*>(address() + i * kTaggedSize));
      88             :   }
      89             : 
      90    13648399 :   friend void swap(Reference lhs, Reference rhs) { lhs.swap(rhs); }
      91             : 
      92             :   friend difference_type operator-(AtomicSlot a, AtomicSlot b) {
      93     6282982 :     return static_cast<int>(a.address() - b.address()) / kTaggedSize;
      94             :   }
      95             : };
      96             : 
      97             : }  // namespace internal
      98             : }  // namespace v8
      99             : 
     100             : #endif  // V8_OBJECTS_SLOTS_ATOMIC_INL_H_

Generated by: LCOV version 1.10