V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
slots-atomic-inl.h
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& other) : address_(other.address_) {}
36 
37  Reference& operator=(const Reference& other) {
38  AsAtomicTagged::Relaxed_Store(
39  address_, AsAtomicTagged::Relaxed_Load(other.address_));
40  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  operator Tagged_t() const { return AsAtomicTagged::Relaxed_Load(address_); }
50 
51  void swap(Reference& other) {
52  Address tmp = value();
53  AsAtomicTagged::Relaxed_Store(address_, other.value());
54  AsAtomicTagged::Relaxed_Store(other.address_, tmp);
55  }
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  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  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  friend void swap(Reference lhs, Reference rhs) { lhs.swap(rhs); }
91 
92  friend difference_type operator-(AtomicSlot a, AtomicSlot b) {
93  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_
Definition: libplatform.h:13