OLD | NEW |
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #ifndef VM_HANDLES_H_ | 5 #ifndef VM_HANDLES_H_ |
6 #define VM_HANDLES_H_ | 6 #define VM_HANDLES_H_ |
7 | 7 |
8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/flags.h" | 9 #include "vm/flags.h" |
10 #include "vm/os.h" | 10 #include "vm/os.h" |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
70 } | 70 } |
71 }; | 71 }; |
72 | 72 |
73 | 73 |
74 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 74 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
75 class Handles { | 75 class Handles { |
76 public: | 76 public: |
77 Handles() | 77 Handles() |
78 : zone_blocks_(NULL), | 78 : zone_blocks_(NULL), |
79 first_scoped_block_(NULL), | 79 first_scoped_block_(NULL), |
80 scoped_blocks_(&first_scoped_block_), | 80 scoped_blocks_(&first_scoped_block_) { |
81 last_visited_block_(NULL) { | |
82 } | 81 } |
83 ~Handles() { | 82 ~Handles() { |
84 DeleteAll(); | 83 DeleteAll(); |
85 } | 84 } |
86 | 85 |
87 // Visit all object pointers stored in the various handles. | 86 // Visit all object pointers stored in the various handles. |
88 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 87 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
89 | 88 |
90 // Visit all the scoped handles. | 89 // Visit all the scoped handles. |
91 void VisitScopedHandles(ObjectPointerVisitor* visitor); | 90 void VisitScopedHandles(ObjectPointerVisitor* visitor); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
132 private: | 131 private: |
133 // Base structure for managing blocks of handles. | 132 // Base structure for managing blocks of handles. |
134 // Handles are allocated in Chunks (each chunk holds kHandlesPerChunk | 133 // Handles are allocated in Chunks (each chunk holds kHandlesPerChunk |
135 // handles). The chunk is uninitialized, subsequent requests for handles | 134 // handles). The chunk is uninitialized, subsequent requests for handles |
136 // is allocated from the chunk until we run out space in the chunk, | 135 // is allocated from the chunk until we run out space in the chunk, |
137 // at this point another chunk is allocated. These chunks are chained | 136 // at this point another chunk is allocated. These chunks are chained |
138 // together. | 137 // together. |
139 class HandlesBlock { | 138 class HandlesBlock { |
140 public: | 139 public: |
141 explicit HandlesBlock(HandlesBlock* next) | 140 explicit HandlesBlock(HandlesBlock* next) |
142 : last_visited_handle_(0), | 141 : next_handle_slot_(0), |
143 next_handle_slot_(0), | |
144 next_block_(next) { } | 142 next_block_(next) { } |
145 ~HandlesBlock(); | 143 ~HandlesBlock(); |
146 | 144 |
147 // Reinitializes handle block for reuse. | 145 // Reinitializes handle block for reuse. |
148 void ReInit(); | 146 void ReInit(); |
149 | 147 |
150 // Returns true if the handle block is full. | 148 // Returns true if the handle block is full. |
151 bool IsFull() const { | 149 bool IsFull() const { |
152 return next_handle_slot_ >= (kHandleSizeInWords * kHandlesPerChunk); | 150 return next_handle_slot_ >= (kHandleSizeInWords * kHandlesPerChunk); |
153 } | 151 } |
154 | 152 |
155 // Returns true if passed in handle belongs to this block. | 153 // Returns true if passed in handle belongs to this block. |
156 bool IsValidHandle(uword handle) const { | 154 bool IsValidHandle(uword handle) const { |
157 uword start = reinterpret_cast<uword>(data_); | 155 uword start = reinterpret_cast<uword>(data_); |
158 uword end = start + (kHandleSizeInWords * kWordSize * kHandlesPerChunk); | 156 uword end = start + (kHandleSizeInWords * kWordSize * kHandlesPerChunk); |
159 return (start <= handle && handle < end); | 157 return (start <= handle && handle < end); |
160 } | 158 } |
161 | 159 |
162 // Allocates space for a handle in the data area. | 160 // Allocates space for a handle in the data area. |
163 uword AllocateHandle() { | 161 uword AllocateHandle() { |
164 ASSERT(!IsFull()); | 162 ASSERT(!IsFull()); |
165 uword handle_address = reinterpret_cast<uword>(data_ + next_handle_slot_); | 163 uword handle_address = reinterpret_cast<uword>(data_ + next_handle_slot_); |
166 next_handle_slot_ += kHandleSizeInWords; | 164 next_handle_slot_ += kHandleSizeInWords; |
167 return handle_address; | 165 return handle_address; |
168 } | 166 } |
169 | 167 |
170 // Visit all object pointers in the handle block. | 168 // Visit all object pointers in the handle block. |
171 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 169 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
172 | 170 |
173 // Visit all the object pointers in the block since the last time this | |
174 // method was called. | |
175 void VisitUnvisitedObjectPointers(ObjectPointerVisitor* visitor); | |
176 | |
177 // Visit all of the handles in the handle block. | 171 // Visit all of the handles in the handle block. |
178 void Visit(HandleVisitor* visitor); | 172 void Visit(HandleVisitor* visitor); |
179 | 173 |
180 #if defined(DEBUG) | 174 #if defined(DEBUG) |
181 // Zaps the free handle area to an uninitialized value. | 175 // Zaps the free handle area to an uninitialized value. |
182 void ZapFreeHandles(); | 176 void ZapFreeHandles(); |
183 #endif | 177 #endif |
184 | 178 |
185 // Returns number of active handles in the handle block. | 179 // Returns number of active handles in the handle block. |
186 int HandleCount() const; | 180 int HandleCount() const; |
187 | 181 |
188 // Accessors. | 182 // Accessors. |
189 intptr_t next_handle_slot() const { return next_handle_slot_; } | 183 intptr_t next_handle_slot() const { return next_handle_slot_; } |
190 void set_next_handle_slot(intptr_t next_handle_slot) { | 184 void set_next_handle_slot(intptr_t next_handle_slot) { |
191 next_handle_slot_ = next_handle_slot; | 185 next_handle_slot_ = next_handle_slot; |
192 } | 186 } |
193 HandlesBlock* next_block() const { return next_block_; } | 187 HandlesBlock* next_block() const { return next_block_; } |
194 void set_next_block(HandlesBlock* next) { next_block_ = next; } | 188 void set_next_block(HandlesBlock* next) { next_block_ = next; } |
195 | 189 |
196 private: | 190 private: |
197 // Last handle visited by VisitUnvisitedObjectPointers. Handles | |
198 // at, or beyond this index are new. | |
199 intptr_t last_visited_handle_; | |
200 | |
201 uword data_[kHandleSizeInWords * kHandlesPerChunk]; // Handles area. | 191 uword data_[kHandleSizeInWords * kHandlesPerChunk]; // Handles area. |
202 intptr_t next_handle_slot_; // Next slot for allocation in current block. | 192 intptr_t next_handle_slot_; // Next slot for allocation in current block. |
203 HandlesBlock* next_block_; // Link to next block of handles. | 193 HandlesBlock* next_block_; // Link to next block of handles. |
204 | 194 |
205 DISALLOW_COPY_AND_ASSIGN(HandlesBlock); | 195 DISALLOW_COPY_AND_ASSIGN(HandlesBlock); |
206 }; | 196 }; |
207 | 197 |
208 // Deletes all the allocated handle blocks. | 198 // Deletes all the allocated handle blocks. |
209 void DeleteAll(); | 199 void DeleteAll(); |
210 void DeleteHandleBlocks(HandlesBlock* blocks); | 200 void DeleteHandleBlocks(HandlesBlock* blocks); |
(...skipping 16 matching lines...) Expand all Loading... |
227 // Verifies consistency of handle blocks after a scope is destroyed. | 217 // Verifies consistency of handle blocks after a scope is destroyed. |
228 void VerifyScopedHandleState(); | 218 void VerifyScopedHandleState(); |
229 | 219 |
230 // Zaps the free scoped handles to an uninitialized value. | 220 // Zaps the free scoped handles to an uninitialized value. |
231 void ZapFreeScopedHandles(); | 221 void ZapFreeScopedHandles(); |
232 #endif | 222 #endif |
233 | 223 |
234 HandlesBlock* zone_blocks_; // List of zone handles. | 224 HandlesBlock* zone_blocks_; // List of zone handles. |
235 HandlesBlock first_scoped_block_; // First block of scoped handles. | 225 HandlesBlock first_scoped_block_; // First block of scoped handles. |
236 HandlesBlock* scoped_blocks_; // List of scoped handles. | 226 HandlesBlock* scoped_blocks_; // List of scoped handles. |
237 // Last block visited by VisitUnvisitedHandles. | |
238 HandlesBlock* last_visited_block_; | |
239 | 227 |
240 friend class HandleScope; | 228 friend class HandleScope; |
241 friend class Dart; | 229 friend class Dart; |
242 friend class ObjectStore; | 230 friend class ObjectStore; |
243 DISALLOW_ALLOCATION(); | 231 DISALLOW_ALLOCATION(); |
244 DISALLOW_COPY_AND_ASSIGN(Handles); | 232 DISALLOW_COPY_AND_ASSIGN(Handles); |
245 }; | 233 }; |
246 | 234 |
247 | 235 |
248 static const int kVMHandleSizeInWords = 2; | 236 static const int kVMHandleSizeInWords = 2; |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
349 }; | 337 }; |
350 #endif // defined(DEBUG) | 338 #endif // defined(DEBUG) |
351 | 339 |
352 // Macro to start a no handles scope in the code. | 340 // Macro to start a no handles scope in the code. |
353 #define NOHANDLESCOPE(isolate) \ | 341 #define NOHANDLESCOPE(isolate) \ |
354 dart::NoHandleScope no_vm_internal_handles_scope_(isolate); | 342 dart::NoHandleScope no_vm_internal_handles_scope_(isolate); |
355 | 343 |
356 } // namespace dart | 344 } // namespace dart |
357 | 345 |
358 #endif // VM_HANDLES_H_ | 346 #endif // VM_HANDLES_H_ |
OLD | NEW |