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

Generated by: LCOV version 1.10