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

Side by Side Diff: sky/engine/platform/heap/Handle.h

Issue 683593002: Remove GarbageCollected support from the bindings (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 6 years, 1 month 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
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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
80 private: 80 private:
81 PersistentNode* m_next; 81 PersistentNode* m_next;
82 PersistentNode* m_prev; 82 PersistentNode* m_prev;
83 83
84 template<typename RootsAccessor, typename Owner> friend class PersistentBase ; 84 template<typename RootsAccessor, typename Owner> friend class PersistentBase ;
85 friend class PersistentAnchor; 85 friend class PersistentAnchor;
86 friend class ThreadState; 86 friend class ThreadState;
87 }; 87 };
88 88
89 89
90 const int wrapperPersistentsPerRegion = 256;
91 const size_t wrapperPersistentOffsetMask = ~static_cast<size_t>(3);
92 const size_t wrapperPersistentLiveBitMask = 1;
93
94 class WrapperPersistentNode {
95 WTF_MAKE_NONCOPYABLE(WrapperPersistentNode);
96 public:
97 bool isAlive() { return m_regionOffset & wrapperPersistentLiveBitMask; }
98
99 WrapperPersistentRegion* region()
100 {
101 return reinterpret_cast<WrapperPersistentRegion*>(
102 reinterpret_cast<Address>(this) - (m_regionOffset & wrapperPersisten tOffsetMask));
103 }
104
105 virtual ~WrapperPersistentNode()
106 {
107 m_regionOffset &= ~wrapperPersistentLiveBitMask;
108 }
109
110 virtual void trace(Visitor* visitor) { }
111
112 protected:
113 WrapperPersistentNode() : m_raw(0), m_regionOffset(0) { }
114
115 explicit WrapperPersistentNode(void* raw)
116 {
117 // When the constructor is called the slot should have been taken (takeS lot)
118 // as part of allocating the memory (via operator new). Hence the m_raw
119 // pointer should be 0.
120 ASSERT(!m_raw);
121 m_raw = raw;
122 // The m_regionOffset should always be set as an offset to the containin g
123 // region. However it should not have the live bit set when the construc tor
124 // is called.
125 ASSERT(m_regionOffset);
126 ASSERT(!isAlive());
127 m_regionOffset |= wrapperPersistentLiveBitMask;
128 }
129
130 private:
131 void initSlot(size_t regionOffset, WrapperPersistentNode* nextFree)
132 {
133 ASSERT(!m_raw);
134 ASSERT(!m_regionOffset);
135 ASSERT(!(regionOffset & ~wrapperPersistentOffsetMask));
136 m_raw = nextFree;
137 m_regionOffset = regionOffset;
138 }
139
140 WrapperPersistentNode* takeSlot()
141 {
142 // The slot should not be alive at the point where it is allocated.
143 ASSERT(!isAlive());
144 WrapperPersistentNode* nextFree = reinterpret_cast<WrapperPersistentNode *>(m_raw);
145 m_raw = 0;
146 return nextFree;
147 }
148
149 WrapperPersistentNode* freeSlot(WrapperPersistentNode* nextFree)
150 {
151 // When the slot is freed the destructor should already have cleared the live bit.
152 ASSERT(!isAlive());
153 m_raw = nextFree;
154 return this;
155 }
156
157 protected:
158 // m_raw is used both to point to the object when the WrapperPersistentNode is used/alive
159 // and to point to the next free wrapperPersistentNode in the region when th e node is
160 // unused/dead.
161 void* m_raw;
162
163 // The m_regionOffset field is an offset from this node to the base of the c ontaining
164 // WrapperPersistentRegion.
165 size_t m_regionOffset;
166
167 friend class WrapperPersistentRegion;
168 };
169
170 template<typename T>
171 class WrapperPersistent final : public WrapperPersistentNode {
172 public:
173 WrapperPersistent() : WrapperPersistentNode(0) { }
174 WrapperPersistent(std::nullptr_t) : WrapperPersistentNode(0) { }
175 WrapperPersistent(T* raw) : WrapperPersistentNode(raw) { }
176 WrapperPersistent(T& raw) : WrapperPersistentNode(&raw) { }
177
178 void* operator new(size_t);
179 void operator delete(void*);
180
181 virtual void trace(Visitor* visitor)
182 {
183 ASSERT(isAlive());
184 visitor->mark(static_cast<T*>(m_raw));
185 }
186 };
187
188 class PLATFORM_EXPORT WrapperPersistentRegion {
189 WTF_MAKE_NONCOPYABLE(WrapperPersistentRegion);
190 public:
191 WrapperPersistentRegion()
192 {
193 WrapperPersistentNode* nextFree = 0;
194 for (int i = wrapperPersistentsPerRegion - 1; i >= 0; --i) {
195 size_t regionOffset = reinterpret_cast<Address>(&m_entries[i]) - rei nterpret_cast<Address>(this);
196 // Setup the free slot with an offset to the containing region's bas e and a pointer to the next
197 // free slot in the region.
198 m_entries[i].initSlot(regionOffset, nextFree);
199 nextFree = &m_entries[i];
200 }
201 m_prev = 0;
202 m_next = 0;
203 m_freeHead = nextFree;
204 m_count = 0;
205 }
206
207 void* allocate()
208 {
209 if (!m_freeHead) {
210 ASSERT(m_count == wrapperPersistentsPerRegion);
211 return 0;
212 }
213 // We have a free persistent slot in this region.
214 WrapperPersistentNode* freeSlot = m_freeHead;
215 // Take the slot and advance m_freeHead to the next free slot.
216 m_freeHead = freeSlot->takeSlot();
217 ASSERT(m_count < wrapperPersistentsPerRegion);
218 m_count++;
219 return reinterpret_cast<void*>(freeSlot);
220 }
221
222 void free(WrapperPersistentNode* object)
223 {
224 ASSERT(object);
225 ASSERT(!object->isAlive());
226 m_freeHead = object->freeSlot(m_freeHead);
227 ASSERT(m_count > 0);
228 m_count--;
229 if (!m_count)
230 ThreadState::current()->freeWrapperPersistentRegion(this);
231 }
232
233 bool removeIfNotLast(WrapperPersistentRegion** headPtr);
234 static void insertHead(WrapperPersistentRegion** headPtr, WrapperPersistentR egion* newHead);
235 static WrapperPersistentRegion* removeHead(WrapperPersistentRegion** headPtr );
236 static void* outOfLineAllocate(ThreadState*, WrapperPersistentRegion*);
237 static void trace(WrapperPersistentRegion* head, Visitor* visitor)
238 {
239 for (WrapperPersistentRegion* current = head; current; current = current ->m_next)
240 current->traceRegion(visitor);
241 }
242
243 private:
244 void traceRegion(Visitor* visitor)
245 {
246 size_t live = 0;
247
248 #ifdef NDEBUG
249 for (int i = 0; i < wrapperPersistentsPerRegion && live < m_count; ++i) {
250 #else
251 // In DEBUG mode we scan all entries to validate we only have m_count
252 // live entries.
253 for (int i = 0; i < wrapperPersistentsPerRegion; ++i) {
254 #endif
255 if (m_entries[i].isAlive()) {
256 m_entries[i].trace(visitor);
257 live++;
258 }
259 }
260 ASSERT(live == m_count);
261 }
262
263 WrapperPersistentRegion* m_prev;
264 WrapperPersistentRegion* m_next;
265 WrapperPersistentNode* m_freeHead;
266 size_t m_count;
267 WrapperPersistentNode m_entries[wrapperPersistentsPerRegion];
268 };
269
270 template<typename T>
271 void* WrapperPersistent<T>::operator new(size_t size)
272 {
273 ASSERT(size == sizeof(WrapperPersistent<T>));
274 ThreadState* state = ThreadState::current();
275 WrapperPersistentRegion* region = state->wrapperRoots();
276 ASSERT(region);
277 void* persistent = region->allocate();
278 if (!persistent)
279 return WrapperPersistentRegion::outOfLineAllocate(state, region);
280 return persistent;
281 }
282
283 template<typename T>
284 void WrapperPersistent<T>::operator delete(void* object)
285 {
286 WrapperPersistentNode* persistent = static_cast<WrapperPersistentNode*>(obje ct);
287 persistent->region()->free(persistent);
288 }
289
290 // RootsAccessor for Persistent that provides access to thread-local list 90 // RootsAccessor for Persistent that provides access to thread-local list
291 // of persistent handles. Can only be used to create handles that 91 // of persistent handles. Can only be used to create handles that
292 // are constructed and destructed on the same thread. 92 // are constructed and destructed on the same thread.
293 template<ThreadAffinity Affinity> 93 template<ThreadAffinity Affinity>
294 class ThreadLocalPersistents { 94 class ThreadLocalPersistents {
295 public: 95 public:
296 static PersistentNode* roots() { return state()->roots(); } 96 static PersistentNode* roots() { return state()->roots(); }
297 97
298 // No locking required. Just check that we are at the right thread. 98 // No locking required. Just check that we are at the right thread.
299 class Lock { 99 class Lock {
(...skipping 1036 matching lines...) Expand 10 before | Expand all | Expand 10 after
1336 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, false> { 1136 struct ParamStorageTraits<T*> : public PointerParamStorageTraits<T*, false> {
1337 }; 1137 };
1338 1138
1339 template<typename T> 1139 template<typename T>
1340 struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, fal se> { 1140 struct ParamStorageTraits<RawPtr<T> > : public PointerParamStorageTraits<T*, fal se> {
1341 }; 1141 };
1342 1142
1343 } // namespace WTF 1143 } // namespace WTF
1344 1144
1345 #endif 1145 #endif
OLDNEW
« no previous file with comments | « sky/engine/core/html/canvas/WebGLVertexArrayObjectOES.idl ('k') | sky/engine/platform/heap/Handle.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698