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

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

Issue 651713002: Oilpan: DOM wrappers don't need to keep persistent handles (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 2 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 | Annotate | Revision Log
« 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 ALLOW_ONLY_INLINE_ALLOCATION();
160 WTF_MAKE_NONCOPYABLE(WrapperPersistentNode);
161 public:
162 bool isAlive() { return m_regionOffset & wrapperPersistentLiveBitMask; }
163
164 WrapperPersistentRegion* region()
165 {
166 return reinterpret_cast<WrapperPersistentRegion*>(
167 reinterpret_cast<Address>(this) - regionOffset());
168 }
169
170 virtual void trace(Visitor* visitor) { }
171
172 static inline void destroy(const WrapperPersistentNode*);
173
174 protected:
175 WrapperPersistentNode() : m_raw(0), m_regionOffset(0) { }
176 WrapperPersistentNode(void *raw, size_t regionOffset) : m_raw(raw), m_region Offset(regionOffset) { }
177
178 private:
179 size_t regionOffset() { return m_regionOffset & wrapperPersistentOffsetMask; }
180
181 WrapperPersistentNode* takeSlot()
182 {
183 // The slot should not be alive at the point where it is allocated.
184 ASSERT(!isAlive());
185 WrapperPersistentNode* nextFree = reinterpret_cast<WrapperPersistentNode *>(m_raw);
186 m_raw = 0;
187 return nextFree;
188 }
189
190 WrapperPersistentNode* freeSlot(WrapperPersistentNode* nextFree)
191 {
192 m_regionOffset &= ~wrapperPersistentLiveBitMask;
193 m_raw = nextFree;
194 return this;
195 }
196
197 // Don't allow delete being called on wrapper persistent nodes. We
198 // do use placement new to initialize the slot with the right vtable. See
199 // WrapperPersistent<T> below.
200 void operator delete(void*);
201
202 protected:
203 // m_raw is used both to point to the object when the WrapperPersistentNode is used/alive
204 // and to point to the next free wrapperPersistentNode in the region when th e node is
205 // unused/dead.
206 void* m_raw;
207
208 // The m_regionOffset field encodes liveness of the slot as well as being an
209 // offset from this node to the base of the containing WrapperPersistentRegi on.
210 size_t m_regionOffset;
211
212 friend class WrapperPersistentRegion;
213 };
214
215 template<typename T>
216 class WrapperPersistent final : public WrapperPersistentNode {
217 ALLOW_ONLY_INLINE_ALLOCATION();
218 public:
219 static WrapperPersistent<T>* create(T* raw);
220
221 virtual void trace(Visitor* visitor) override
222 {
223 ASSERT(isAlive());
224 visitor->mark(static_cast<T*>(m_raw));
225 }
226
227 private:
228 WrapperPersistent() { }
229
230 // We need to use a constructor to initialize the allocated slot since it
231 // has a vtable which must be set to the WrapperPersistent<T> type.
232 WrapperPersistent(T* raw, size_t regionOffset) : WrapperPersistentNode(raw, regionOffset) { }
233
234 // Don't allow delete being called on wrapper persistents.
235 void operator delete(void*);
236 };
237
238 class PLATFORM_EXPORT WrapperPersistentRegion {
239 WTF_MAKE_NONCOPYABLE(WrapperPersistentRegion);
240 public:
241 WrapperPersistentRegion()
242 {
243 WrapperPersistentNode* nextFree = 0;
244 for (int i = wrapperPersistentsPerRegion - 1; i >= 0; --i) {
245 size_t regionOffset = reinterpret_cast<Address>(&m_entries[i]) - rei nterpret_cast<Address>(this);
246 // Setup the free slot with an offset to the containing region's bas e and a pointer to the next
247 // free slot in the region.
248 ASSERT(!(regionOffset & ~wrapperPersistentOffsetMask));
249 new (&m_entries[i]) WrapperPersistentNode(nextFree, regionOffset);
250 nextFree = &m_entries[i];
251 }
252 m_prev = 0;
253 m_next = 0;
254 m_freeHead = nextFree;
255 m_count = 0;
256 }
257
258 Address allocate()
259 {
260 if (!m_freeHead) {
261 ASSERT(m_count == wrapperPersistentsPerRegion);
262 return 0;
263 }
264 // We have a free persistent slot in this region.
265 WrapperPersistentNode* freeSlot = m_freeHead;
266 // Take the slot and advance m_freeHead to the next free slot.
267 m_freeHead = freeSlot->takeSlot();
268 ASSERT(m_count < wrapperPersistentsPerRegion);
269 m_count++;
270 return reinterpret_cast<Address>(freeSlot);
271 }
272
273 void free(WrapperPersistentNode* object)
274 {
275 ASSERT(object);
276 m_freeHead = object->freeSlot(m_freeHead);
277 ASSERT(m_count > 0);
278 m_count--;
279 if (!m_count)
280 ThreadState::current()->freeWrapperPersistentRegion(this);
281 }
282
283 bool removeIfNotLast(WrapperPersistentRegion** headPtr);
284 static void insertHead(WrapperPersistentRegion** headPtr, WrapperPersistentR egion* newHead);
285 static WrapperPersistentRegion* removeHead(WrapperPersistentRegion** headPtr );
286 static Address outOfLineAllocate(ThreadState*, WrapperPersistentRegion**);
287 static void trace(WrapperPersistentRegion* head, Visitor* visitor)
288 {
289 for (WrapperPersistentRegion* current = head; current; current = current ->m_next)
290 current->traceRegion(visitor);
291 }
292
293 private:
294 void traceRegion(Visitor* visitor)
295 {
296 size_t live = 0;
297
298 #ifdef NDEBUG
299 for (int i = 0; i < wrapperPersistentsPerRegion && live < m_count; ++i) {
300 #else
301 // In DEBUG mode we scan all entries to validate we only have m_count
302 // live entries.
303 for (int i = 0; i < wrapperPersistentsPerRegion; ++i) {
304 #endif
305 if (m_entries[i].isAlive()) {
306 m_entries[i].trace(visitor);
307 live++;
308 }
309 }
310 ASSERT(live == m_count);
311 }
312
313 WrapperPersistentRegion* m_prev;
314 WrapperPersistentRegion* m_next;
315 WrapperPersistentNode* m_freeHead;
316 size_t m_count;
317 WrapperPersistentNode m_entries[wrapperPersistentsPerRegion];
318 };
319
320 template<typename T>
321 WrapperPersistent<T>* WrapperPersistent<T>::create(T* raw)
322 {
323 ThreadState* state = ThreadState::current();
324 WrapperPersistentRegion* region = state->wrapperRoots();
325 ASSERT(region);
326 Address persistentSlot = region->allocate();
327 if (!persistentSlot)
328 persistentSlot = WrapperPersistentRegion::outOfLineAllocate(state, &regi on);
329 ASSERT(persistentSlot);
330 ASSERT(!reinterpret_cast<WrapperPersistentNode*>(persistentSlot)->isAlive()) ;
331
332 size_t regionOffset = persistentSlot - reinterpret_cast<Address>(region);
333 regionOffset |= wrapperPersistentLiveBitMask;
334
335 // We use placement new to call the constructor to ensure that we setup the
336 // vtable correctly.
337 return new (persistentSlot) WrapperPersistent<T>(raw, regionOffset);
338 }
339
340 void WrapperPersistentNode::destroy(const WrapperPersistentNode* node)
341 {
342 WrapperPersistentNode* persistent = const_cast<WrapperPersistentNode*>(node) ;
343 persistent->region()->free(persistent);
344 }
345
346 // RootsAccessor for Persistent that provides access to thread-local list 153 // RootsAccessor for Persistent that provides access to thread-local list
347 // of persistent handles. Can only be used to create handles that 154 // of persistent handles. Can only be used to create handles that
348 // are constructed and destructed on the same thread. 155 // are constructed and destructed on the same thread.
349 template<ThreadAffinity Affinity> 156 template<ThreadAffinity Affinity>
350 class ThreadLocalPersistents { 157 class ThreadLocalPersistents {
351 public: 158 public:
352 static PersistentNode* roots() { return state()->roots(); } 159 static PersistentNode* roots() { return state()->roots(); }
353 160
354 // 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.
355 class Lock { 162 class Lock {
(...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after
1349 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, blink::IsGa rbageCollectedType<T>::value> { 1156 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, blink::IsGa rbageCollectedType<T>::value> {
1350 }; 1157 };
1351 1158
1352 template<typename T> 1159 template<typename T>
1353 struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, bli nk::IsGarbageCollectedType<T>::value> { 1160 struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, bli nk::IsGarbageCollectedType<T>::value> {
1354 }; 1161 };
1355 1162
1356 } // namespace WTF 1163 } // namespace WTF
1357 1164
1358 #endif 1165 #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