| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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_IMPL_H_ | 5 #ifndef RUNTIME_VM_HANDLES_IMPL_H_ |
| 6 #define RUNTIME_VM_HANDLES_IMPL_H_ | 6 #define RUNTIME_VM_HANDLES_IMPL_H_ |
| 7 | 7 |
| 8 #include "vm/heap.h" | 8 #include "vm/heap.h" |
| 9 #include "vm/thread.h" | 9 #include "vm/thread.h" |
| 10 #include "vm/visitor.h" | 10 #include "vm/visitor.h" |
| 11 | 11 |
| 12 namespace dart { | 12 namespace dart { |
| 13 | 13 |
| 14 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 14 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 15 void Handles<kHandleSizeInWords, | 15 void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 16 kHandlesPerChunk, | 16 VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 17 kOffsetOfRawPtr>::VisitObjectPointers( | |
| 18 ObjectPointerVisitor* visitor) { | |
| 19 // Visit all zone handles. | 17 // Visit all zone handles. |
| 20 HandlesBlock* block = zone_blocks_; | 18 HandlesBlock* block = zone_blocks_; |
| 21 while (block != NULL) { | 19 while (block != NULL) { |
| 22 block->VisitObjectPointers(visitor); | 20 block->VisitObjectPointers(visitor); |
| 23 block = block->next_block(); | 21 block = block->next_block(); |
| 24 } | 22 } |
| 25 | 23 |
| 26 // Visit all scoped handles. | 24 // Visit all scoped handles. |
| 27 VisitScopedHandles(visitor); | 25 VisitScopedHandles(visitor); |
| 28 } | 26 } |
| 29 | 27 |
| 30 | 28 |
| 31 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 29 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 32 void Handles<kHandleSizeInWords, | 30 void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 33 kHandlesPerChunk, | 31 VisitScopedHandles(ObjectPointerVisitor* visitor) { |
| 34 kOffsetOfRawPtr>::VisitScopedHandles( | |
| 35 ObjectPointerVisitor* visitor) { | |
| 36 HandlesBlock* block = &first_scoped_block_; | 32 HandlesBlock* block = &first_scoped_block_; |
| 37 do { | 33 do { |
| 38 block->VisitObjectPointers(visitor); | 34 block->VisitObjectPointers(visitor); |
| 39 if (block == scoped_blocks_) { | 35 if (block == scoped_blocks_) { |
| 40 return; | 36 return; |
| 41 } | 37 } |
| 42 block = block->next_block(); | 38 block = block->next_block(); |
| 43 } while (block != NULL); | 39 } while (block != NULL); |
| 44 UNREACHABLE(); | 40 UNREACHABLE(); |
| 45 } | 41 } |
| 46 | 42 |
| 47 | 43 |
| 48 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 44 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 49 void Handles<kHandleSizeInWords, | 45 void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::Visit( |
| 50 kHandlesPerChunk, | 46 HandleVisitor* visitor) { |
| 51 kOffsetOfRawPtr>::Visit(HandleVisitor* visitor) { | |
| 52 // Visit all zone handles. | 47 // Visit all zone handles. |
| 53 HandlesBlock* block = zone_blocks_; | 48 HandlesBlock* block = zone_blocks_; |
| 54 while (block != NULL) { | 49 while (block != NULL) { |
| 55 block->Visit(visitor); | 50 block->Visit(visitor); |
| 56 block = block->next_block(); | 51 block = block->next_block(); |
| 57 } | 52 } |
| 58 | 53 |
| 59 // Visit all scoped handles. | 54 // Visit all scoped handles. |
| 60 block = &first_scoped_block_; | 55 block = &first_scoped_block_; |
| 61 do { | 56 do { |
| 62 block->Visit(visitor); | 57 block->Visit(visitor); |
| 63 block = block->next_block(); | 58 block = block->next_block(); |
| 64 } while (block != NULL); | 59 } while (block != NULL); |
| 65 } | 60 } |
| 66 | 61 |
| 67 | 62 |
| 68 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 63 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 69 void Handles<kHandleSizeInWords, | 64 void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::Reset() { |
| 70 kHandlesPerChunk, | |
| 71 kOffsetOfRawPtr>::Reset() { | |
| 72 // Delete all the extra zone handle blocks allocated and reinit the first | 65 // Delete all the extra zone handle blocks allocated and reinit the first |
| 73 // zone block. | 66 // zone block. |
| 74 if (zone_blocks_ != NULL) { | 67 if (zone_blocks_ != NULL) { |
| 75 DeleteHandleBlocks(zone_blocks_->next_block()); | 68 DeleteHandleBlocks(zone_blocks_->next_block()); |
| 76 zone_blocks_->ReInit(); | 69 zone_blocks_->ReInit(); |
| 77 } | 70 } |
| 78 | 71 |
| 79 // Delete all the extra scoped handle blocks allocated and reinit the first | 72 // Delete all the extra scoped handle blocks allocated and reinit the first |
| 80 // scoped block. | 73 // scoped block. |
| 81 DeleteHandleBlocks(first_scoped_block_.next_block()); | 74 DeleteHandleBlocks(first_scoped_block_.next_block()); |
| 82 first_scoped_block_.ReInit(); | 75 first_scoped_block_.ReInit(); |
| 83 scoped_blocks_ = &first_scoped_block_; | 76 scoped_blocks_ = &first_scoped_block_; |
| 84 } | 77 } |
| 85 | 78 |
| 86 | 79 |
| 87 // Figure out the current handle scope using the current Zone and | 80 // Figure out the current handle scope using the current Zone and |
| 88 // allocate a handle in that scope. The function assumes that a | 81 // allocate a handle in that scope. The function assumes that a |
| 89 // current handle scope exists. It asserts for this appropriately. | 82 // current handle scope exists. It asserts for this appropriately. |
| 90 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 83 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 91 uword Handles<kHandleSizeInWords, | 84 uword Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 92 kHandlesPerChunk, | 85 AllocateHandle(Zone* zone) { |
| 93 kOffsetOfRawPtr>::AllocateHandle(Zone* zone) { | |
| 94 #if defined(DEBUG) | 86 #if defined(DEBUG) |
| 95 Thread* thread = Thread::Current(); | 87 Thread* thread = Thread::Current(); |
| 96 ASSERT(thread->top_handle_scope() != NULL); | 88 ASSERT(thread->top_handle_scope() != NULL); |
| 97 ASSERT(thread->no_handle_scope_depth() == 0); | 89 ASSERT(thread->no_handle_scope_depth() == 0); |
| 98 #endif // DEBUG | 90 #endif // DEBUG |
| 99 Handles* handles = zone->handles(); | 91 Handles* handles = zone->handles(); |
| 100 ASSERT(handles != NULL); | 92 ASSERT(handles != NULL); |
| 101 return handles->AllocateScopedHandle(); | 93 return handles->AllocateScopedHandle(); |
| 102 } | 94 } |
| 103 | 95 |
| 104 | 96 |
| 105 // The function assumes that 'zone' is the current zone and asserts for | 97 // The function assumes that 'zone' is the current zone and asserts for |
| 106 // this appropriately. | 98 // this appropriately. |
| 107 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 99 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 108 uword Handles<kHandleSizeInWords, | 100 uword Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 109 kHandlesPerChunk, | 101 AllocateZoneHandle(Zone* zone) { |
| 110 kOffsetOfRawPtr>::AllocateZoneHandle(Zone* zone) { | |
| 111 #if defined(DEBUG) | 102 #if defined(DEBUG) |
| 112 Thread* thread = Thread::Current(); | 103 Thread* thread = Thread::Current(); |
| 113 ASSERT(thread->zone() == zone); | 104 ASSERT(thread->zone() == zone); |
| 114 ASSERT(thread->no_handle_scope_depth() == 0); | 105 ASSERT(thread->no_handle_scope_depth() == 0); |
| 115 #endif // DEBUG | 106 #endif // DEBUG |
| 116 Handles* handles = zone->handles(); | 107 Handles* handles = zone->handles(); |
| 117 ASSERT(handles != NULL); | 108 ASSERT(handles != NULL); |
| 118 uword address = handles->AllocateHandleInZone(); | 109 uword address = handles->AllocateHandleInZone(); |
| 119 return address; | 110 return address; |
| 120 } | 111 } |
| 121 | 112 |
| 122 | 113 |
| 123 // Figure out the current zone using the current Thread and | 114 // Figure out the current zone using the current Thread and |
| 124 // check if the specified handle has been allocated in this zone. | 115 // check if the specified handle has been allocated in this zone. |
| 125 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 116 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 126 bool Handles<kHandleSizeInWords, | 117 bool Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 127 kHandlesPerChunk, | 118 IsZoneHandle(uword handle) { |
| 128 kOffsetOfRawPtr>::IsZoneHandle(uword handle) { | |
| 129 // TODO(5411412): Accessing the current thread is a performance problem, | 119 // TODO(5411412): Accessing the current thread is a performance problem, |
| 130 // consider passing it down as a parameter. | 120 // consider passing it down as a parameter. |
| 131 Thread* thread = Thread::Current(); | 121 Thread* thread = Thread::Current(); |
| 132 ASSERT(thread != NULL); | 122 ASSERT(thread != NULL); |
| 133 ASSERT(thread->zone() != NULL); | 123 ASSERT(thread->zone() != NULL); |
| 134 Handles* handles = thread->zone()->handles(); | 124 Handles* handles = thread->zone()->handles(); |
| 135 ASSERT(handles != NULL); | 125 ASSERT(handles != NULL); |
| 136 return handles->IsValidZoneHandle(handle); | 126 return handles->IsValidZoneHandle(handle); |
| 137 } | 127 } |
| 138 | 128 |
| 139 | 129 |
| 140 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 130 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 141 void Handles<kHandleSizeInWords, | 131 void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 142 kHandlesPerChunk, | 132 DeleteAll() { |
| 143 kOffsetOfRawPtr>::DeleteAll() { | |
| 144 // Delete all the zone allocated handle blocks. | 133 // Delete all the zone allocated handle blocks. |
| 145 // GCTrace does not need to trace this call to DeleteHandleBlocks, | 134 // GCTrace does not need to trace this call to DeleteHandleBlocks, |
| 146 // since the individual zone deletions will be caught | 135 // since the individual zone deletions will be caught |
| 147 // by instrumentation in the BaseZone destructor. | 136 // by instrumentation in the BaseZone destructor. |
| 148 DeleteHandleBlocks(zone_blocks_); | 137 DeleteHandleBlocks(zone_blocks_); |
| 149 zone_blocks_ = NULL; | 138 zone_blocks_ = NULL; |
| 150 | 139 |
| 151 // Delete all the scoped handle blocks. | 140 // Delete all the scoped handle blocks. |
| 152 scoped_blocks_ = first_scoped_block_.next_block(); | 141 scoped_blocks_ = first_scoped_block_.next_block(); |
| 153 DeleteHandleBlocks(scoped_blocks_); | 142 DeleteHandleBlocks(scoped_blocks_); |
| 154 first_scoped_block_.ReInit(); | 143 first_scoped_block_.ReInit(); |
| 155 scoped_blocks_ = &first_scoped_block_; | 144 scoped_blocks_ = &first_scoped_block_; |
| 156 } | 145 } |
| 157 | 146 |
| 158 | 147 |
| 159 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 148 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 160 void Handles<kHandleSizeInWords, | 149 void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 161 kHandlesPerChunk, | 150 DeleteHandleBlocks(HandlesBlock* blocks) { |
| 162 kOffsetOfRawPtr>::DeleteHandleBlocks( | |
| 163 HandlesBlock* blocks) { | |
| 164 while (blocks != NULL) { | 151 while (blocks != NULL) { |
| 165 HandlesBlock* block = blocks; | 152 HandlesBlock* block = blocks; |
| 166 blocks = blocks->next_block(); | 153 blocks = blocks->next_block(); |
| 167 delete block; | 154 delete block; |
| 168 } | 155 } |
| 169 } | 156 } |
| 170 | 157 |
| 171 | 158 |
| 172 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 159 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 173 void Handles<kHandleSizeInWords, | 160 void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 174 kHandlesPerChunk, | 161 SetupNextScopeBlock() { |
| 175 kOffsetOfRawPtr>::SetupNextScopeBlock() { | |
| 176 if (FLAG_trace_handles) { | 162 if (FLAG_trace_handles) { |
| 177 OS::PrintErr("*** Handle Counts for (0x%" Px "):Zone = %d,Scoped = %d\n", | 163 OS::PrintErr("*** Handle Counts for (0x%" Px "):Zone = %d,Scoped = %d\n", |
| 178 reinterpret_cast<intptr_t>(this), | 164 reinterpret_cast<intptr_t>(this), CountZoneHandles(), |
| 179 CountZoneHandles(), CountScopedHandles()); | 165 CountScopedHandles()); |
| 180 } | 166 } |
| 181 if (scoped_blocks_->next_block() == NULL) { | 167 if (scoped_blocks_->next_block() == NULL) { |
| 182 scoped_blocks_->set_next_block(new HandlesBlock(NULL)); | 168 scoped_blocks_->set_next_block(new HandlesBlock(NULL)); |
| 183 } | 169 } |
| 184 scoped_blocks_ = scoped_blocks_->next_block(); | 170 scoped_blocks_ = scoped_blocks_->next_block(); |
| 185 scoped_blocks_->set_next_handle_slot(0); | 171 scoped_blocks_->set_next_handle_slot(0); |
| 186 #if defined(DEBUG) | 172 #if defined(DEBUG) |
| 187 scoped_blocks_->ZapFreeHandles(); | 173 scoped_blocks_->ZapFreeHandles(); |
| 188 #endif | 174 #endif |
| 189 } | 175 } |
| 190 | 176 |
| 191 | 177 |
| 192 // Validation of the handle involves iterating through all the | 178 // Validation of the handle involves iterating through all the |
| 193 // handle blocks to check if the handle is valid, please | 179 // handle blocks to check if the handle is valid, please |
| 194 // use this only in ASSERT code for verification purposes. | 180 // use this only in ASSERT code for verification purposes. |
| 195 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 181 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 196 bool Handles<kHandleSizeInWords, | 182 bool Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 197 kHandlesPerChunk, | 183 IsValidScopedHandle(uword handle) const { |
| 198 kOffsetOfRawPtr>::IsValidScopedHandle(uword handle) const { | |
| 199 const HandlesBlock* iterator = &first_scoped_block_; | 184 const HandlesBlock* iterator = &first_scoped_block_; |
| 200 while (iterator != NULL) { | 185 while (iterator != NULL) { |
| 201 if (iterator->IsValidHandle(handle)) { | 186 if (iterator->IsValidHandle(handle)) { |
| 202 return true; | 187 return true; |
| 203 } | 188 } |
| 204 iterator = iterator->next_block(); | 189 iterator = iterator->next_block(); |
| 205 } | 190 } |
| 206 return false; | 191 return false; |
| 207 } | 192 } |
| 208 | 193 |
| 209 | 194 |
| 210 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 195 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 211 bool Handles<kHandleSizeInWords, | 196 bool Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 212 kHandlesPerChunk, | 197 IsValidZoneHandle(uword handle) const { |
| 213 kOffsetOfRawPtr>::IsValidZoneHandle(uword handle) const { | |
| 214 const HandlesBlock* iterator = zone_blocks_; | 198 const HandlesBlock* iterator = zone_blocks_; |
| 215 while (iterator != NULL) { | 199 while (iterator != NULL) { |
| 216 if (iterator->IsValidHandle(handle)) { | 200 if (iterator->IsValidHandle(handle)) { |
| 217 return true; | 201 return true; |
| 218 } | 202 } |
| 219 iterator = iterator->next_block(); | 203 iterator = iterator->next_block(); |
| 220 } | 204 } |
| 221 return false; | 205 return false; |
| 222 } | 206 } |
| 223 | 207 |
| 224 | 208 |
| 225 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 209 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 226 void Handles<kHandleSizeInWords, | 210 void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 227 kHandlesPerChunk, | 211 SetupNextZoneBlock() { |
| 228 kOffsetOfRawPtr>::SetupNextZoneBlock() { | |
| 229 if (FLAG_trace_handles) { | 212 if (FLAG_trace_handles) { |
| 230 OS::PrintErr("*** Handle Counts for (0x%" Px "):Zone = %d,Scoped = %d\n", | 213 OS::PrintErr("*** Handle Counts for (0x%" Px "):Zone = %d,Scoped = %d\n", |
| 231 reinterpret_cast<intptr_t>(this), | 214 reinterpret_cast<intptr_t>(this), CountZoneHandles(), |
| 232 CountZoneHandles(), CountScopedHandles()); | 215 CountScopedHandles()); |
| 233 } | 216 } |
| 234 zone_blocks_ = new HandlesBlock(zone_blocks_); | 217 zone_blocks_ = new HandlesBlock(zone_blocks_); |
| 235 ASSERT(zone_blocks_ != NULL); | 218 ASSERT(zone_blocks_ != NULL); |
| 236 } | 219 } |
| 237 | 220 |
| 238 | 221 |
| 239 #if defined(DEBUG) | 222 #if defined(DEBUG) |
| 240 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 223 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 241 void Handles<kHandleSizeInWords, | 224 void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 242 kHandlesPerChunk, | 225 VerifyScopedHandleState() { |
| 243 kOffsetOfRawPtr>::VerifyScopedHandleState() { | |
| 244 HandlesBlock* block = &first_scoped_block_; | 226 HandlesBlock* block = &first_scoped_block_; |
| 245 const intptr_t end_index = (kHandleSizeInWords * kHandlesPerChunk); | 227 const intptr_t end_index = (kHandleSizeInWords * kHandlesPerChunk); |
| 246 do { | 228 do { |
| 247 if (scoped_blocks_ == block && block->next_handle_slot() <= end_index) { | 229 if (scoped_blocks_ == block && block->next_handle_slot() <= end_index) { |
| 248 return; | 230 return; |
| 249 } | 231 } |
| 250 block = block->next_block(); | 232 block = block->next_block(); |
| 251 } while (block != NULL); | 233 } while (block != NULL); |
| 252 ASSERT(false); | 234 ASSERT(false); |
| 253 } | 235 } |
| 254 | 236 |
| 255 | 237 |
| 256 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 238 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 257 void Handles<kHandleSizeInWords, | 239 void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 258 kHandlesPerChunk, | 240 ZapFreeScopedHandles() { |
| 259 kOffsetOfRawPtr>::ZapFreeScopedHandles() { | |
| 260 HandlesBlock* block = scoped_blocks_; | 241 HandlesBlock* block = scoped_blocks_; |
| 261 while (block != NULL) { | 242 while (block != NULL) { |
| 262 block->ZapFreeHandles(); | 243 block->ZapFreeHandles(); |
| 263 block = block->next_block(); | 244 block = block->next_block(); |
| 264 } | 245 } |
| 265 } | 246 } |
| 266 #endif | 247 #endif |
| 267 | 248 |
| 268 | 249 |
| 269 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 250 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 270 int Handles<kHandleSizeInWords, | 251 int Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 271 kHandlesPerChunk, | 252 CountScopedHandles() const { |
| 272 kOffsetOfRawPtr>::CountScopedHandles() const { | |
| 273 int count = 0; | 253 int count = 0; |
| 274 const HandlesBlock* block = &first_scoped_block_; | 254 const HandlesBlock* block = &first_scoped_block_; |
| 275 do { | 255 do { |
| 276 count += block->HandleCount(); | 256 count += block->HandleCount(); |
| 277 if (block == scoped_blocks_) { | 257 if (block == scoped_blocks_) { |
| 278 return count; | 258 return count; |
| 279 } | 259 } |
| 280 block = block->next_block(); | 260 block = block->next_block(); |
| 281 } while (block != NULL); | 261 } while (block != NULL); |
| 282 UNREACHABLE(); | 262 UNREACHABLE(); |
| 283 return 0; | 263 return 0; |
| 284 } | 264 } |
| 285 | 265 |
| 286 | 266 |
| 287 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 267 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 288 int Handles<kHandleSizeInWords, | 268 int Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 289 kHandlesPerChunk, | 269 CountZoneHandles() const { |
| 290 kOffsetOfRawPtr>::CountZoneHandles() const { | |
| 291 int count = 0; | 270 int count = 0; |
| 292 const HandlesBlock* block = zone_blocks_; | 271 const HandlesBlock* block = zone_blocks_; |
| 293 while (block != NULL) { | 272 while (block != NULL) { |
| 294 count += block->HandleCount(); | 273 count += block->HandleCount(); |
| 295 block = block->next_block(); | 274 block = block->next_block(); |
| 296 } | 275 } |
| 297 return count; | 276 return count; |
| 298 } | 277 } |
| 299 | 278 |
| 300 | 279 |
| 301 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 280 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 302 Handles<kHandleSizeInWords, | 281 Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>::HandlesBlock:: |
| 303 kHandlesPerChunk, | 282 ~HandlesBlock() { |
| 304 kOffsetOfRawPtr>::HandlesBlock::~HandlesBlock() { | |
| 305 #if defined(DEBUG) | 283 #if defined(DEBUG) |
| 306 ReInit(); | 284 ReInit(); |
| 307 #endif | 285 #endif |
| 308 } | 286 } |
| 309 | 287 |
| 310 | 288 |
| 311 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 289 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 312 void Handles<kHandleSizeInWords, | 290 void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 313 kHandlesPerChunk, | 291 HandlesBlock::ReInit() { |
| 314 kOffsetOfRawPtr>::HandlesBlock::ReInit() { | |
| 315 next_handle_slot_ = 0; | 292 next_handle_slot_ = 0; |
| 316 next_block_ = NULL; | 293 next_block_ = NULL; |
| 317 #if defined(DEBUG) | 294 #if defined(DEBUG) |
| 318 ZapFreeHandles(); | 295 ZapFreeHandles(); |
| 319 #endif | 296 #endif |
| 320 } | 297 } |
| 321 | 298 |
| 322 | 299 |
| 323 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 300 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 324 void Handles<kHandleSizeInWords, | 301 void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 325 kHandlesPerChunk, | 302 HandlesBlock::VisitObjectPointers(ObjectPointerVisitor* visitor) { |
| 326 kOffsetOfRawPtr>::HandlesBlock::VisitObjectPointers( | |
| 327 ObjectPointerVisitor* visitor) { | |
| 328 ASSERT(visitor != NULL); | 303 ASSERT(visitor != NULL); |
| 329 for (intptr_t i = 0; i < next_handle_slot_; i += kHandleSizeInWords) { | 304 for (intptr_t i = 0; i < next_handle_slot_; i += kHandleSizeInWords) { |
| 330 visitor->VisitPointer( | 305 visitor->VisitPointer( |
| 331 reinterpret_cast<RawObject**>(&data_[i + kOffsetOfRawPtr/kWordSize])); | 306 reinterpret_cast<RawObject**>(&data_[i + kOffsetOfRawPtr / kWordSize])); |
| 332 } | 307 } |
| 333 } | 308 } |
| 334 | 309 |
| 335 | 310 |
| 336 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 311 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 337 void Handles<kHandleSizeInWords, | 312 void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 338 kHandlesPerChunk, | 313 HandlesBlock::Visit(HandleVisitor* visitor) { |
| 339 kOffsetOfRawPtr>::HandlesBlock::Visit(HandleVisitor* visitor) { | |
| 340 ASSERT(visitor != NULL); | 314 ASSERT(visitor != NULL); |
| 341 for (intptr_t i = 0; i < next_handle_slot_; i += kHandleSizeInWords) { | 315 for (intptr_t i = 0; i < next_handle_slot_; i += kHandleSizeInWords) { |
| 342 visitor->VisitHandle(reinterpret_cast<uword>(&data_[i])); | 316 visitor->VisitHandle(reinterpret_cast<uword>(&data_[i])); |
| 343 } | 317 } |
| 344 } | 318 } |
| 345 | 319 |
| 346 | 320 |
| 347 #if defined(DEBUG) | 321 #if defined(DEBUG) |
| 348 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 322 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 349 void Handles<kHandleSizeInWords, | 323 void Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 350 kHandlesPerChunk, | 324 HandlesBlock::ZapFreeHandles() { |
| 351 kOffsetOfRawPtr>::HandlesBlock::ZapFreeHandles() { | |
| 352 // Reinitialize the handle area to some uninitialized value. | 325 // Reinitialize the handle area to some uninitialized value. |
| 353 for (intptr_t i = next_handle_slot_; | 326 for (intptr_t i = next_handle_slot_; |
| 354 i < (kHandleSizeInWords * kHandlesPerChunk); | 327 i < (kHandleSizeInWords * kHandlesPerChunk); i++) { |
| 355 i++) { | |
| 356 data_[i] = kZapUninitializedWord; | 328 data_[i] = kZapUninitializedWord; |
| 357 } | 329 } |
| 358 } | 330 } |
| 359 #endif | 331 #endif |
| 360 | 332 |
| 361 | 333 |
| 362 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> | 334 template <int kHandleSizeInWords, int kHandlesPerChunk, int kOffsetOfRawPtr> |
| 363 int Handles<kHandleSizeInWords, | 335 int Handles<kHandleSizeInWords, kHandlesPerChunk, kOffsetOfRawPtr>:: |
| 364 kHandlesPerChunk, | 336 HandlesBlock::HandleCount() const { |
| 365 kOffsetOfRawPtr>::HandlesBlock::HandleCount() const { | |
| 366 return (next_handle_slot_ / kHandleSizeInWords); | 337 return (next_handle_slot_ / kHandleSizeInWords); |
| 367 } | 338 } |
| 368 | 339 |
| 369 } // namespace dart | 340 } // namespace dart |
| 370 | 341 |
| 371 #endif // RUNTIME_VM_HANDLES_IMPL_H_ | 342 #endif // RUNTIME_VM_HANDLES_IMPL_H_ |
| OLD | NEW |