Backed out changeset 4191b252db9b (bug 1886734) for causing build bustages @netwerk...
[gecko.git] / js / src / gc / GCArray.h
blobabd940037d13478f2f005e4883e90c9d754f0ede
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2 * vim: set ts=8 sts=2 et sw=2 tw=80:
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef js_GCArray_h
8 #define js_GCArray_h
10 #include "mozilla/Assertions.h"
12 #include "gc/Barrier.h"
13 #include "gc/Tracer.h"
14 #include "js/Value.h"
16 namespace js {
19 * A fixed size array of |T| for use with GC things.
21 * Must be allocated manually to allow space for the trailing elements
22 * data. Call bytesRequired to get the required allocation size.
24 * Does not provide any barriers by default.
26 template <typename T>
27 class GCArray {
28 const uint32_t size_;
29 T elements_[1];
31 public:
32 explicit GCArray(uint32_t size) : size_(size) {
33 // The array contents following the first element are not initialized.
36 uint32_t size() const { return size_; }
38 const T& operator[](uint32_t i) const {
39 MOZ_ASSERT(i < size_);
40 return elements_[i];
42 T& operator[](uint32_t i) {
43 MOZ_ASSERT(i < size_);
44 return elements_[i];
47 const T* begin() const { return elements_; }
48 T* begin() { return elements_; }
49 const T* end() const { return elements_ + size_; }
50 T* end() { return elements_ + size_; }
52 void trace(JSTracer* trc) {
53 TraceRange(trc, size(), begin(), "array element");
56 static constexpr ptrdiff_t offsetOfElements() {
57 return offsetof(GCArray, elements_);
60 static size_t bytesRequired(size_t size) {
61 return offsetOfElements() + std::max(size, size_t(1)) * sizeof(T);
66 * A fixed size array of GC things owned by a GC thing.
68 * Uses the appropriate barriers depending on whether the owner is in the
69 * nursery or the tenured heap. If the owner cannot be allocated in the nursery
70 * then this class is not required.
72 template <typename T>
73 class GCOwnedArray {
74 using StorageType = GCArray<PreAndPostBarrierWrapper<T>>;
75 using TenuredInterface = StorageType;
76 using NurseryInterface = GCArray<PreBarrierWrapper<T>>;
78 StorageType array;
80 public:
81 explicit GCOwnedArray(uint32_t size) : array(size) {}
83 uint32_t size() const { return array.size(); }
84 const T& operator[](uint32_t i) const { return array[i].get(); }
86 // Apply |f| to a view of the data with appropriate barriers given |owner|.
87 template <typename F>
88 void withOwner(gc::Cell* owner, F&& f) {
89 if (gc::IsInsideNursery(owner)) {
90 f(nurseryOwned());
91 } else {
92 f(tenuredOwned());
96 // For convenience, special case setElement.
97 void setElement(gc::Cell* owner, uint32_t i, const T& newValue) {
98 withOwner(owner, [&](auto& self) { self[i] = newValue; });
101 void trace(JSTracer* trc) { array.trace(trc); }
103 static constexpr ptrdiff_t offsetOfElements() {
104 return offsetof(GCOwnedArray, array) + StorageType::offsetOfElements();
107 static size_t bytesRequired(size_t size) {
108 return offsetof(GCOwnedArray, array) + StorageType::bytesRequired(size);
111 private:
112 TenuredInterface& tenuredOwned() { return array; }
113 NurseryInterface& nurseryOwned() {
114 return reinterpret_cast<NurseryInterface&>(array);
118 } // namespace js
120 #endif // js_GCArray_h