Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1135)

Side by Side Diff: Source/platform/heap/Handle.h

Issue 553483004: Revert of [oilpan]: optimize the way we allocate persistent handles in wrappers. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: merge conflicts Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/platform/heap/BUILD.gn ('k') | Source/platform/heap/Handle.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2014 Google Inc. All rights reserved. 2 * Copyright (C) 2014 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 143
144 private: 144 private:
145 PersistentNode* m_next; 145 PersistentNode* m_next;
146 PersistentNode* m_prev; 146 PersistentNode* m_prev;
147 147
148 template<typename RootsAccessor, typename Owner> friend class PersistentBase ; 148 template<typename RootsAccessor, typename Owner> friend class PersistentBase ;
149 friend class PersistentAnchor; 149 friend class PersistentAnchor;
150 friend class ThreadState; 150 friend class ThreadState;
151 }; 151 };
152 152
153
154 const int wrapperPersistentsPerRegion = 256;
155 const size_t wrapperPersistentOffsetMask = ~static_cast<size_t>(3);
156 const size_t wrapperPersistentLiveBitMask = 1;
157
158 class WrapperPersistentNode {
159 WTF_MAKE_NONCOPYABLE(WrapperPersistentNode);
160 public:
161 bool isAlive() { return m_regionOffset & wrapperPersistentLiveBitMask; }
162
163 WrapperPersistentRegion* region()
164 {
165 return reinterpret_cast<WrapperPersistentRegion*>(
166 reinterpret_cast<Address>(this) - (m_regionOffset & wrapperPersisten tOffsetMask));
167 }
168
169 virtual ~WrapperPersistentNode()
170 {
171 m_regionOffset &= ~wrapperPersistentLiveBitMask;
172 }
173
174 virtual void trace(Visitor* visitor) { }
175
176 protected:
177 WrapperPersistentNode() : m_raw(0), m_regionOffset(0) { }
178
179 explicit WrapperPersistentNode(void* raw)
180 {
181 // When the constructor is called the slot should have been taken (takeS lot)
182 // as part of allocating the memory (via operator new). Hence the m_raw
183 // pointer should be 0.
184 ASSERT(!m_raw);
185 m_raw = raw;
186 // The m_regionOffset should always be set as an offset to the containin g
187 // region. However it should not have the live bit set when the construc tor
188 // is called.
189 ASSERT(m_regionOffset);
190 ASSERT(!isAlive());
191 m_regionOffset |= wrapperPersistentLiveBitMask;
192 }
193
194 private:
195 void initSlot(size_t regionOffset, WrapperPersistentNode* nextFree)
196 {
197 ASSERT(!m_raw);
198 ASSERT(!m_regionOffset);
199 ASSERT(!(regionOffset & ~wrapperPersistentOffsetMask));
200 m_raw = nextFree;
201 m_regionOffset = regionOffset;
202 }
203
204 WrapperPersistentNode* takeSlot()
205 {
206 // The slot should not be alive at the point where it is allocated.
207 ASSERT(!isAlive());
208 WrapperPersistentNode* nextFree = reinterpret_cast<WrapperPersistentNode *>(m_raw);
209 m_raw = 0;
210 return nextFree;
211 }
212
213 WrapperPersistentNode* freeSlot(WrapperPersistentNode* nextFree)
214 {
215 // When the slot is freed the destructor should already have cleared the live bit.
216 ASSERT(!isAlive());
217 m_raw = nextFree;
218 return this;
219 }
220
221 protected:
222 // m_raw is used both to point to the object when the WrapperPersistentNode is used/alive
223 // and to point to the next free wrapperPersistentNode in the region when th e node is
224 // unused/dead.
225 void* m_raw;
226
227 // The m_regionOffset field is an offset from this node to the base of the c ontaining
228 // WrapperPersistentRegion.
229 size_t m_regionOffset;
230
231 friend class WrapperPersistentRegion;
232 };
233
234 template<typename T>
235 class WrapperPersistent FINAL : public WrapperPersistentNode {
236 public:
237 WrapperPersistent() : WrapperPersistentNode(0) { }
238 WrapperPersistent(std::nullptr_t) : WrapperPersistentNode(0) { }
239 WrapperPersistent(T* raw) : WrapperPersistentNode(raw) { }
240 WrapperPersistent(T& raw) : WrapperPersistentNode(&raw) { }
241
242 void* operator new(size_t);
243 void operator delete(void*);
244
245 virtual void trace(Visitor* visitor)
246 {
247 ASSERT(isAlive());
248 visitor->mark(static_cast<T*>(m_raw));
249 }
250 };
251
252 class PLATFORM_EXPORT WrapperPersistentRegion {
253 WTF_MAKE_NONCOPYABLE(WrapperPersistentRegion);
254 public:
255 WrapperPersistentRegion()
256 {
257 WrapperPersistentNode* nextFree = 0;
258 for (int i = wrapperPersistentsPerRegion - 1; i >= 0; --i) {
259 size_t regionOffset = reinterpret_cast<Address>(&m_entries[i]) - rei nterpret_cast<Address>(this);
260 // Setup the free slot with an offset to the containing region's bas e and a pointer to the next
261 // free slot in the region.
262 m_entries[i].initSlot(regionOffset, nextFree);
263 nextFree = &m_entries[i];
264 }
265 m_prev = 0;
266 m_next = 0;
267 m_freeHead = nextFree;
268 m_count = 0;
269 }
270
271 void* allocate()
272 {
273 if (!m_freeHead) {
274 ASSERT(m_count == wrapperPersistentsPerRegion);
275 return 0;
276 }
277 // We have a free persistent slot in this region.
278 WrapperPersistentNode* freeSlot = m_freeHead;
279 // Take the slot and advance m_freeHead to the next free slot.
280 m_freeHead = freeSlot->takeSlot();
281 ASSERT(m_count < wrapperPersistentsPerRegion);
282 m_count++;
283 return reinterpret_cast<void*>(freeSlot);
284 }
285
286 void free(WrapperPersistentNode* object)
287 {
288 ASSERT(object);
289 ASSERT(!object->isAlive());
290 m_freeHead = object->freeSlot(m_freeHead);
291 ASSERT(m_count > 0);
292 m_count--;
293 if (!m_count)
294 ThreadState::current()->freeWrapperPersistentRegion(this);
295 }
296
297 bool removeIfNotLast(WrapperPersistentRegion** headPtr);
298 static void insertHead(WrapperPersistentRegion** headPtr, WrapperPersistentR egion* newHead);
299 static WrapperPersistentRegion* removeHead(WrapperPersistentRegion** headPtr );
300 static void* outOfLineAllocate(ThreadState*, WrapperPersistentRegion*);
301 static void trace(WrapperPersistentRegion* head, Visitor* visitor)
302 {
303 for (WrapperPersistentRegion* current = head; current; current = current ->m_next)
304 current->traceRegion(visitor);
305 }
306
307 private:
308 void traceRegion(Visitor* visitor)
309 {
310 size_t live = 0;
311
312 #ifdef NDEBUG
313 for (int i = 0; i < wrapperPersistentsPerRegion && live < m_count; ++i) {
314 #else
315 // In DEBUG mode we scan all entries to validate we only have m_count
316 // live entries.
317 for (int i = 0; i < wrapperPersistentsPerRegion; ++i) {
318 #endif
319 if (m_entries[i].isAlive()) {
320 m_entries[i].trace(visitor);
321 live++;
322 }
323 }
324 ASSERT(live == m_count);
325 }
326
327 WrapperPersistentRegion* m_prev;
328 WrapperPersistentRegion* m_next;
329 WrapperPersistentNode* m_freeHead;
330 size_t m_count;
331 WrapperPersistentNode m_entries[wrapperPersistentsPerRegion];
332 };
333
334 template<typename T>
335 void* WrapperPersistent<T>::operator new(size_t size)
336 {
337 ASSERT(size == sizeof(WrapperPersistent<T>));
338 ThreadState* state = ThreadState::current();
339 WrapperPersistentRegion* region = state->wrapperRoots();
340 ASSERT(region);
341 void* persistent = region->allocate();
342 if (!persistent)
343 return WrapperPersistentRegion::outOfLineAllocate(state, region);
344 return persistent;
345 }
346
347 template<typename T>
348 void WrapperPersistent<T>::operator delete(void* object)
349 {
350 WrapperPersistentNode* persistent = static_cast<WrapperPersistentNode*>(obje ct);
351 persistent->region()->free(persistent);
352 }
353
354 // RootsAccessor for Persistent that provides access to thread-local list 153 // RootsAccessor for Persistent that provides access to thread-local list
355 // of persistent handles. Can only be used to create handles that 154 // of persistent handles. Can only be used to create handles that
356 // are constructed and destructed on the same thread. 155 // are constructed and destructed on the same thread.
357 template<ThreadAffinity Affinity> 156 template<ThreadAffinity Affinity>
358 class ThreadLocalPersistents { 157 class ThreadLocalPersistents {
359 public: 158 public:
360 static PersistentNode* roots() { return state()->roots(); } 159 static PersistentNode* roots() { return state()->roots(); }
361 160
362 // No locking required. Just check that we are at the right thread. 161 // No locking required. Just check that we are at the right thread.
363 class Lock { 162 class Lock {
(...skipping 1038 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, blink::IsGa rbageCollectedType<T>::value> { 1201 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, blink::IsGa rbageCollectedType<T>::value> {
1403 }; 1202 };
1404 1203
1405 template<typename T> 1204 template<typename T>
1406 struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, bli nk::IsGarbageCollectedType<T>::value> { 1205 struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, bli nk::IsGarbageCollectedType<T>::value> {
1407 }; 1206 };
1408 1207
1409 } // namespace WTF 1208 } // namespace WTF
1410 1209
1411 #endif 1210 #endif
OLDNEW
« no previous file with comments | « Source/platform/heap/BUILD.gn ('k') | Source/platform/heap/Handle.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698