• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
Reference(Tagged_t * address)35     explicit Reference(Tagged_t* address) : address_(address) {}
36     Reference(const Reference&) V8_NOEXCEPT = default;
37 
38     Reference& operator=(const Reference& other) V8_NOEXCEPT {
39       AsAtomicTagged::Relaxed_Store(
40           address_, AsAtomicTagged::Relaxed_Load(other.address_));
41       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.
Tagged_t()50     operator Tagged_t() const { return AsAtomicTagged::Relaxed_Load(address_); }
51 
swap(Reference & other)52     void swap(Reference& other) {
53       Tagged_t tmp = value();
54       AsAtomicTagged::Relaxed_Store(address_, other.value());
55       AsAtomicTagged::Relaxed_Store(other.address_, tmp);
56     }
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:
value()67     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   using difference_type = int;
75   using value_type = Tagged_t;
76   using reference = Reference;
77   using pointer = void*;  // Must be present, but should not be used.
78   using iterator_category = std::random_access_iterator_tag;
79 
AtomicSlot()80   AtomicSlot() : SlotBase(kNullAddress) {}
AtomicSlot(Address address)81   explicit AtomicSlot(Address address) : SlotBase(address) {}
AtomicSlot(ObjectSlot slot)82   explicit AtomicSlot(ObjectSlot slot) : SlotBase(slot.address()) {}
AtomicSlot(MaybeObjectSlot slot)83   explicit AtomicSlot(MaybeObjectSlot slot) : SlotBase(slot.address()) {}
84 
85   Reference operator*() const {
86     return Reference(reinterpret_cast<Tagged_t*>(address()));
87   }
88   Reference operator[](difference_type i) const {
89     return Reference(reinterpret_cast<Tagged_t*>(address() + i * kTaggedSize));
90   }
91 
swap(Reference lhs,Reference rhs)92   friend void swap(Reference lhs, Reference rhs) { lhs.swap(rhs); }
93 
94   friend difference_type operator-(AtomicSlot a, AtomicSlot b) {
95     return static_cast<int>(a.address() - b.address()) / kTaggedSize;
96   }
97 };
98 
99 }  // namespace internal
100 }  // namespace v8
101 
102 #endif  // V8_OBJECTS_SLOTS_ATOMIC_INL_H_
103