| 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 RUNTIME_VM_HANDLES_H_ | 5 #ifndef RUNTIME_VM_HANDLES_H_ |
| 6 #define RUNTIME_VM_HANDLES_H_ | 6 #define RUNTIME_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 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 77 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleVisitor); | 77 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleVisitor); |
| 78 }; | 78 }; |
| 79 | 79 |
| 80 | 80 |
| 81 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 81 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 82 class Handles { | 82 class Handles { |
| 83 public: | 83 public: |
| 84 Handles() | 84 Handles() |
| 85 : zone_blocks_(NULL), | 85 : zone_blocks_(NULL), |
| 86 first_scoped_block_(NULL), | 86 first_scoped_block_(NULL), |
| 87 scoped_blocks_(&first_scoped_block_) { | 87 scoped_blocks_(&first_scoped_block_) {} |
| 88 } | 88 ~Handles() { DeleteAll(); } |
| 89 ~Handles() { | |
| 90 DeleteAll(); | |
| 91 } | |
| 92 | 89 |
| 93 // Visit all object pointers stored in the various handles. | 90 // Visit all object pointers stored in the various handles. |
| 94 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 91 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 95 | 92 |
| 96 // Visit all the scoped handles. | 93 // Visit all the scoped handles. |
| 97 void VisitScopedHandles(ObjectPointerVisitor* visitor); | 94 void VisitScopedHandles(ObjectPointerVisitor* visitor); |
| 98 | 95 |
| 99 // Visit all blocks that have been added since the last time | 96 // Visit all blocks that have been added since the last time |
| 100 // this method was called. | 97 // this method was called. |
| 101 // Be careful with this, since multiple users of this method could | 98 // Be careful with this, since multiple users of this method could |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 private: | 138 private: |
| 142 // Base structure for managing blocks of handles. | 139 // Base structure for managing blocks of handles. |
| 143 // Handles are allocated in Chunks (each chunk holds kHandlesPerChunk | 140 // Handles are allocated in Chunks (each chunk holds kHandlesPerChunk |
| 144 // handles). The chunk is uninitialized, subsequent requests for handles | 141 // handles). The chunk is uninitialized, subsequent requests for handles |
| 145 // is allocated from the chunk until we run out space in the chunk, | 142 // is allocated from the chunk until we run out space in the chunk, |
| 146 // at this point another chunk is allocated. These chunks are chained | 143 // at this point another chunk is allocated. These chunks are chained |
| 147 // together. | 144 // together. |
| 148 class HandlesBlock { | 145 class HandlesBlock { |
| 149 public: | 146 public: |
| 150 explicit HandlesBlock(HandlesBlock* next) | 147 explicit HandlesBlock(HandlesBlock* next) |
| 151 : next_handle_slot_(0), | 148 : next_handle_slot_(0), next_block_(next) {} |
| 152 next_block_(next) { } | |
| 153 ~HandlesBlock(); | 149 ~HandlesBlock(); |
| 154 | 150 |
| 155 // Reinitializes handle block for reuse. | 151 // Reinitializes handle block for reuse. |
| 156 void ReInit(); | 152 void ReInit(); |
| 157 | 153 |
| 158 // Returns true if the handle block is full. | 154 // Returns true if the handle block is full. |
| 159 bool IsFull() const { | 155 bool IsFull() const { |
| 160 return next_handle_slot_ >= (kHandleSizeInWords * kHandlesPerChunk); | 156 return next_handle_slot_ >= (kHandleSizeInWords * kHandlesPerChunk); |
| 161 } | 157 } |
| 162 | 158 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 193 intptr_t next_handle_slot() const { return next_handle_slot_; } | 189 intptr_t next_handle_slot() const { return next_handle_slot_; } |
| 194 void set_next_handle_slot(intptr_t next_handle_slot) { | 190 void set_next_handle_slot(intptr_t next_handle_slot) { |
| 195 next_handle_slot_ = next_handle_slot; | 191 next_handle_slot_ = next_handle_slot; |
| 196 } | 192 } |
| 197 HandlesBlock* next_block() const { return next_block_; } | 193 HandlesBlock* next_block() const { return next_block_; } |
| 198 void set_next_block(HandlesBlock* next) { next_block_ = next; } | 194 void set_next_block(HandlesBlock* next) { next_block_ = next; } |
| 199 | 195 |
| 200 private: | 196 private: |
| 201 uword data_[kHandleSizeInWords * kHandlesPerChunk]; // Handles area. | 197 uword data_[kHandleSizeInWords * kHandlesPerChunk]; // Handles area. |
| 202 intptr_t next_handle_slot_; // Next slot for allocation in current block. | 198 intptr_t next_handle_slot_; // Next slot for allocation in current block. |
| 203 HandlesBlock* next_block_; // Link to next block of handles. | 199 HandlesBlock* next_block_; // Link to next block of handles. |
| 204 | 200 |
| 205 DISALLOW_COPY_AND_ASSIGN(HandlesBlock); | 201 DISALLOW_COPY_AND_ASSIGN(HandlesBlock); |
| 206 }; | 202 }; |
| 207 | 203 |
| 208 // Deletes all the allocated handle blocks. | 204 // Deletes all the allocated handle blocks. |
| 209 void DeleteAll(); | 205 void DeleteAll(); |
| 210 void DeleteHandleBlocks(HandlesBlock* blocks); | 206 void DeleteHandleBlocks(HandlesBlock* blocks); |
| 211 | 207 |
| 212 // Sets up the next handle block (allocates a new one if needed). | 208 // Sets up the next handle block (allocates a new one if needed). |
| 213 void SetupNextScopeBlock(); | 209 void SetupNextScopeBlock(); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 224 void SetupNextZoneBlock(); | 220 void SetupNextZoneBlock(); |
| 225 | 221 |
| 226 #if defined(DEBUG) | 222 #if defined(DEBUG) |
| 227 // Verifies consistency of handle blocks after a scope is destroyed. | 223 // Verifies consistency of handle blocks after a scope is destroyed. |
| 228 void VerifyScopedHandleState(); | 224 void VerifyScopedHandleState(); |
| 229 | 225 |
| 230 // Zaps the free scoped handles to an uninitialized value. | 226 // Zaps the free scoped handles to an uninitialized value. |
| 231 void ZapFreeScopedHandles(); | 227 void ZapFreeScopedHandles(); |
| 232 #endif | 228 #endif |
| 233 | 229 |
| 234 HandlesBlock* zone_blocks_; // List of zone handles. | 230 HandlesBlock* zone_blocks_; // List of zone handles. |
| 235 HandlesBlock first_scoped_block_; // First block of scoped handles. | 231 HandlesBlock first_scoped_block_; // First block of scoped handles. |
| 236 HandlesBlock* scoped_blocks_; // List of scoped handles. | 232 HandlesBlock* scoped_blocks_; // List of scoped handles. |
| 237 | 233 |
| 238 friend class HandleScope; | 234 friend class HandleScope; |
| 239 friend class Dart; | 235 friend class Dart; |
| 240 friend class ObjectStore; | 236 friend class ObjectStore; |
| 241 friend class Thread; | 237 friend class Thread; |
| 242 DISALLOW_ALLOCATION(); | 238 DISALLOW_ALLOCATION(); |
| 243 DISALLOW_COPY_AND_ASSIGN(Handles); | 239 DISALLOW_COPY_AND_ASSIGN(Handles); |
| 244 }; | 240 }; |
| 245 | 241 |
| 246 | 242 |
| 247 static const int kVMHandleSizeInWords = 2; | 243 static const int kVMHandleSizeInWords = 2; |
| 248 static const int kVMHandlesPerChunk = 64; | 244 static const int kVMHandlesPerChunk = 64; |
| 249 static const int kOffsetOfRawPtr = kWordSize; | 245 static const int kOffsetOfRawPtr = kWordSize; |
| 250 class VMHandles : public Handles<kVMHandleSizeInWords, | 246 class VMHandles : public Handles<kVMHandleSizeInWords, |
| 251 kVMHandlesPerChunk, | 247 kVMHandlesPerChunk, |
| 252 kOffsetOfRawPtr> { | 248 kOffsetOfRawPtr> { |
| 253 public: | 249 public: |
| 254 static const int kOffsetOfRawPtrInHandle = kOffsetOfRawPtr; | 250 static const int kOffsetOfRawPtrInHandle = kOffsetOfRawPtr; |
| 255 | 251 |
| 256 VMHandles() : Handles<kVMHandleSizeInWords, | 252 VMHandles() |
| 257 kVMHandlesPerChunk, | 253 : Handles<kVMHandleSizeInWords, kVMHandlesPerChunk, kOffsetOfRawPtr>() { |
| 258 kOffsetOfRawPtr>() { | |
| 259 if (FLAG_trace_handles) { | 254 if (FLAG_trace_handles) { |
| 260 OS::PrintErr("*** Starting a new VM handle block 0x%" Px "\n", | 255 OS::PrintErr("*** Starting a new VM handle block 0x%" Px "\n", |
| 261 reinterpret_cast<intptr_t>(this)); | 256 reinterpret_cast<intptr_t>(this)); |
| 262 } | 257 } |
| 263 } | 258 } |
| 264 ~VMHandles(); | 259 ~VMHandles(); |
| 265 | 260 |
| 266 // Visit all object pointers stored in the various handles. | 261 // Visit all object pointers stored in the various handles. |
| 267 void VisitObjectPointers(ObjectPointerVisitor* visitor); | 262 void VisitObjectPointers(ObjectPointerVisitor* visitor); |
| 268 | 263 |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 VMHandles::HandlesBlock* saved_handle_block_; // Handle block at prev scope. | 302 VMHandles::HandlesBlock* saved_handle_block_; // Handle block at prev scope. |
| 308 uword saved_handle_slot_; // Next available handle slot at previous scope. | 303 uword saved_handle_slot_; // Next available handle slot at previous scope. |
| 309 #if defined(DEBUG) | 304 #if defined(DEBUG) |
| 310 HandleScope* link_; // Link to previous scope. | 305 HandleScope* link_; // Link to previous scope. |
| 311 #endif | 306 #endif |
| 312 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleScope); | 307 DISALLOW_IMPLICIT_CONSTRUCTORS(HandleScope); |
| 313 }; | 308 }; |
| 314 | 309 |
| 315 // Macro to start a new Handle scope. | 310 // Macro to start a new Handle scope. |
| 316 #define HANDLESCOPE(thread) \ | 311 #define HANDLESCOPE(thread) \ |
| 317 dart::HandleScope vm_internal_handles_scope_(thread); | 312 dart::HandleScope vm_internal_handles_scope_(thread); |
| 318 | 313 |
| 319 | 314 |
| 320 // The class NoHandleScope is used in critical regions of the virtual machine | 315 // The class NoHandleScope is used in critical regions of the virtual machine |
| 321 // code where raw dart object pointers are directly manipulated. | 316 // code where raw dart object pointers are directly manipulated. |
| 322 // This class asserts that we do not add code that will allocate new handles | 317 // This class asserts that we do not add code that will allocate new handles |
| 323 // during this critical area. | 318 // during this critical area. |
| 324 // It is used as follows: | 319 // It is used as follows: |
| 325 // { | 320 // { |
| 326 // NOHANDLESCOPE(thread); | 321 // NOHANDLESCOPE(thread); |
| 327 // .... | 322 // .... |
| 328 // ..... | 323 // ..... |
| 329 // critical code that manipulates dart objects directly. | 324 // critical code that manipulates dart objects directly. |
| 330 // .... | 325 // .... |
| 331 // } | 326 // } |
| 332 #if defined(DEBUG) | 327 #if defined(DEBUG) |
| 333 class NoHandleScope : public StackResource { | 328 class NoHandleScope : public StackResource { |
| 334 public: | 329 public: |
| 335 explicit NoHandleScope(Thread* thread); | 330 explicit NoHandleScope(Thread* thread); |
| 336 ~NoHandleScope(); | 331 ~NoHandleScope(); |
| 337 | 332 |
| 338 private: | 333 private: |
| 339 DISALLOW_COPY_AND_ASSIGN(NoHandleScope); | 334 DISALLOW_COPY_AND_ASSIGN(NoHandleScope); |
| 340 }; | 335 }; |
| 341 #else // defined(DEBUG) | 336 #else // defined(DEBUG) |
| 342 class NoHandleScope : public ValueObject { | 337 class NoHandleScope : public ValueObject { |
| 343 public: | 338 public: |
| 344 explicit NoHandleScope(Thread* thread) { } | 339 explicit NoHandleScope(Thread* thread) {} |
| 345 NoHandleScope() { } | 340 NoHandleScope() {} |
| 346 ~NoHandleScope() { } | 341 ~NoHandleScope() {} |
| 347 | 342 |
| 348 private: | 343 private: |
| 349 DISALLOW_COPY_AND_ASSIGN(NoHandleScope); | 344 DISALLOW_COPY_AND_ASSIGN(NoHandleScope); |
| 350 }; | 345 }; |
| 351 #endif // defined(DEBUG) | 346 #endif // defined(DEBUG) |
| 352 | 347 |
| 353 // Macro to start a no handles scope in the code. | 348 // Macro to start a no handles scope in the code. |
| 354 #define NOHANDLESCOPE(thread) \ | 349 #define NOHANDLESCOPE(thread) \ |
| 355 dart::NoHandleScope no_vm_internal_handles_scope_(thread); | 350 dart::NoHandleScope no_vm_internal_handles_scope_(thread); |
| 356 | 351 |
| 357 } // namespace dart | 352 } // namespace dart |
| 358 | 353 |
| 359 #endif // RUNTIME_VM_HANDLES_H_ | 354 #endif // RUNTIME_VM_HANDLES_H_ |
| OLD | NEW |