| 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 |