114
115 class ZPerWorkerStorage : public ZValueStorage<ZPerWorkerStorage> {
116 public:
117 static size_t alignment() {
118 return sizeof(uintptr_t);
119 }
120
121 static uint32_t count() {
122 return MAX2(ParallelGCThreads, ConcGCThreads);
123 }
124
125 static uint32_t id() {
126 return ZThread::worker_id();
127 }
128 };
129
130 template <typename S, typename T>
131 class ZValueIterator;
132
133 template <typename S, typename T>
134 class ZValue {
135 private:
136 const uintptr_t _addr;
137
138 uintptr_t value_addr(uint32_t value_id) const {
139 return _addr + (value_id * S::offset);
140 }
141
142 public:
143 ZValue() :
144 _addr(S::alloc(sizeof(T))) {
145 // Initialize all instances
146 ZValueIterator<S, T> iter(this);
147 for (T* addr; iter.next(&addr);) {
148 ::new (addr) T;
149 }
150 }
151
152 ZValue(const T& value) :
153 _addr(S::alloc(sizeof(T))) {
154 // Initialize all instances
|
114
115 class ZPerWorkerStorage : public ZValueStorage<ZPerWorkerStorage> {
116 public:
117 static size_t alignment() {
118 return sizeof(uintptr_t);
119 }
120
121 static uint32_t count() {
122 return MAX2(ParallelGCThreads, ConcGCThreads);
123 }
124
125 static uint32_t id() {
126 return ZThread::worker_id();
127 }
128 };
129
130 template <typename S, typename T>
131 class ZValueIterator;
132
133 template <typename S, typename T>
134 class ZValue : public CHeapObj<mtGC> {
135 private:
136 const uintptr_t _addr;
137
138 uintptr_t value_addr(uint32_t value_id) const {
139 return _addr + (value_id * S::offset);
140 }
141
142 public:
143 ZValue() :
144 _addr(S::alloc(sizeof(T))) {
145 // Initialize all instances
146 ZValueIterator<S, T> iter(this);
147 for (T* addr; iter.next(&addr);) {
148 ::new (addr) T;
149 }
150 }
151
152 ZValue(const T& value) :
153 _addr(S::alloc(sizeof(T))) {
154 // Initialize all instances
|