| 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 #include "vm/scavenger.h" | 5 #include "vm/scavenger.h" |
| 6 | 6 |
| 7 #include "vm/dart.h" | 7 #include "vm/dart.h" |
| 8 #include "vm/dart_api_state.h" | 8 #include "vm/dart_api_state.h" |
| 9 #include "vm/isolate.h" | 9 #include "vm/isolate.h" |
| 10 #include "vm/object.h" | 10 #include "vm/object.h" |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor); | 130 DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor); |
| 131 }; | 131 }; |
| 132 | 132 |
| 133 | 133 |
| 134 class ScavengerWeakVisitor : public HandleVisitor { | 134 class ScavengerWeakVisitor : public HandleVisitor { |
| 135 public: | 135 public: |
| 136 explicit ScavengerWeakVisitor(Scavenger* scavenger) : scavenger_(scavenger) { | 136 explicit ScavengerWeakVisitor(Scavenger* scavenger) : scavenger_(scavenger) { |
| 137 } | 137 } |
| 138 | 138 |
| 139 void VisitHandle(uword addr) { | 139 void VisitHandle(uword addr) { |
| 140 WeakPersistentHandle* handle = | 140 FinalizablePersistentHandle* handle = |
| 141 reinterpret_cast<WeakPersistentHandle*>(addr); | 141 reinterpret_cast<FinalizablePersistentHandle*>(addr); |
| 142 RawObject* raw_obj = handle->raw(); | 142 RawObject* raw_obj = handle->raw(); |
| 143 if (!raw_obj->IsHeapObject()) return; | 143 if (!raw_obj->IsHeapObject()) return; |
| 144 uword raw_addr = RawObject::ToAddr(raw_obj); | 144 uword raw_addr = RawObject::ToAddr(raw_obj); |
| 145 if (scavenger_->from_->Contains(raw_addr)) { | 145 if (scavenger_->from_->Contains(raw_addr)) { |
| 146 uword header = *reinterpret_cast<uword*>(raw_addr); | 146 uword header = *reinterpret_cast<uword*>(raw_addr); |
| 147 if (IsForwarding(header)) { | 147 if (IsForwarding(header)) { |
| 148 handle->set_raw(RawObject::FromAddr(ForwardedAddr(header))); | 148 handle->set_raw(RawObject::FromAddr(ForwardedAddr(header))); |
| 149 } else { | 149 } else { |
| 150 WeakPersistentHandle::Finalize(handle); | 150 FinalizablePersistentHandle::Finalize(handle); |
| 151 } | 151 } |
| 152 } | 152 } |
| 153 } | 153 } |
| 154 | 154 |
| 155 private: | 155 private: |
| 156 Scavenger* scavenger_; | 156 Scavenger* scavenger_; |
| 157 | 157 |
| 158 DISALLOW_COPY_AND_ASSIGN(ScavengerWeakVisitor); | 158 DISALLOW_COPY_AND_ASSIGN(ScavengerWeakVisitor); |
| 159 }; | 159 }; |
| 160 | 160 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 } | 195 } |
| 196 | 196 |
| 197 | 197 |
| 198 Scavenger::~Scavenger() { | 198 Scavenger::~Scavenger() { |
| 199 delete to_; | 199 delete to_; |
| 200 delete from_; | 200 delete from_; |
| 201 delete space_; | 201 delete space_; |
| 202 } | 202 } |
| 203 | 203 |
| 204 | 204 |
| 205 void Scavenger::Prologue() { | 205 void Scavenger::Prologue(Isolate* isolate, bool invoke_api_callbacks) { |
| 206 if (invoke_api_callbacks) { |
| 207 isolate->gc_prologue_callbacks().Invoke(); |
| 208 } |
| 206 // Flip the two semi-spaces so that to_ is always the space for allocating | 209 // Flip the two semi-spaces so that to_ is always the space for allocating |
| 207 // objects. | 210 // objects. |
| 208 MemoryRegion* temp = from_; | 211 MemoryRegion* temp = from_; |
| 209 from_ = to_; | 212 from_ = to_; |
| 210 to_ = temp; | 213 to_ = temp; |
| 211 top_ = FirstObjectStart(); | 214 top_ = FirstObjectStart(); |
| 212 end_ = to_->end(); | 215 end_ = to_->end(); |
| 213 } | 216 } |
| 214 | 217 |
| 215 | 218 |
| 216 void Scavenger::Epilogue() { | 219 void Scavenger::Epilogue(Isolate* isolate, bool invoke_api_callbacks) { |
| 217 // All objects in the to space have been copied from the from space at this | 220 // All objects in the to space have been copied from the from space at this |
| 218 // moment. | 221 // moment. |
| 219 survivor_end_ = top_; | 222 survivor_end_ = top_; |
| 220 | 223 |
| 221 #if defined(DEBUG) | 224 #if defined(DEBUG) |
| 222 memset(from_->pointer(), 0xf3, from_->size()); | 225 memset(from_->pointer(), 0xf3, from_->size()); |
| 223 #endif // defined(DEBUG) | 226 #endif // defined(DEBUG) |
| 227 if (invoke_api_callbacks) { |
| 228 isolate->gc_prologue_callbacks().Invoke(); |
| 229 } |
| 224 } | 230 } |
| 225 | 231 |
| 226 | 232 |
| 227 void Scavenger::IterateRoots(Isolate* isolate, ObjectPointerVisitor* visitor) { | 233 void Scavenger::IterateRoots(Isolate* isolate, |
| 234 ObjectPointerVisitor* visitor, |
| 235 bool visit_prologue_weak_persistent_handles) { |
| 228 isolate->VisitObjectPointers(visitor, | 236 isolate->VisitObjectPointers(visitor, |
| 237 visit_prologue_weak_persistent_handles, |
| 229 StackFrameIterator::kDontValidateFrames); | 238 StackFrameIterator::kDontValidateFrames); |
| 230 heap_->IterateOldPointers(visitor); | 239 heap_->IterateOldPointers(visitor); |
| 231 } | 240 } |
| 232 | 241 |
| 233 | 242 |
| 234 void Scavenger::IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor) { | 243 void Scavenger::IterateWeakRoots(Isolate* isolate, |
| 235 isolate->VisitWeakPersistentHandles(visitor); | 244 HandleVisitor* visitor, |
| 245 bool visit_prologue_weak_persistent_handles) { |
| 246 isolate->VisitWeakPersistentHandles(visitor, |
| 247 visit_prologue_weak_persistent_handles); |
| 236 } | 248 } |
| 237 | 249 |
| 238 | 250 |
| 239 void Scavenger::ProcessToSpace(ObjectPointerVisitor* visitor) { | 251 void Scavenger::ProcessToSpace(ObjectPointerVisitor* visitor) { |
| 240 uword resolved_top = FirstObjectStart(); | 252 uword resolved_top = FirstObjectStart(); |
| 241 // Iterate until all work has been drained. | 253 // Iterate until all work has been drained. |
| 242 while ((resolved_top < top_) || PromotedStackHasMore()) { | 254 while ((resolved_top < top_) || PromotedStackHasMore()) { |
| 243 while (resolved_top < top_) { | 255 while (resolved_top < top_) { |
| 244 RawObject* raw_obj = RawObject::FromAddr(resolved_top); | 256 RawObject* raw_obj = RawObject::FromAddr(resolved_top); |
| 245 resolved_top += raw_obj->VisitPointers(visitor); | 257 resolved_top += raw_obj->VisitPointers(visitor); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 257 | 269 |
| 258 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { | 270 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { |
| 259 uword cur = FirstObjectStart(); | 271 uword cur = FirstObjectStart(); |
| 260 while (cur < top_) { | 272 while (cur < top_) { |
| 261 RawObject* raw_obj = RawObject::FromAddr(cur); | 273 RawObject* raw_obj = RawObject::FromAddr(cur); |
| 262 cur += raw_obj->VisitPointers(visitor); | 274 cur += raw_obj->VisitPointers(visitor); |
| 263 } | 275 } |
| 264 } | 276 } |
| 265 | 277 |
| 266 | 278 |
| 267 void Scavenger::Scavenge() { | 279 void Scavenger::Scavenge(bool invoke_api_callbacks) { |
| 268 // Scavenging is not reentrant. Make sure that is the case. | 280 // Scavenging is not reentrant. Make sure that is the case. |
| 269 ASSERT(!scavenging_); | 281 ASSERT(!scavenging_); |
| 270 scavenging_ = true; | 282 scavenging_ = true; |
| 271 Isolate* isolate = Isolate::Current(); | 283 Isolate* isolate = Isolate::Current(); |
| 272 NoHandleScope no_handles(isolate); | 284 NoHandleScope no_handles(isolate); |
| 273 | 285 |
| 274 if (FLAG_verify_before_gc) { | 286 if (FLAG_verify_before_gc) { |
| 275 OS::PrintErr("Verifying before Scavenge... "); | 287 OS::PrintErr("Verifying before Scavenge... "); |
| 276 heap_->Verify(); | 288 heap_->Verify(); |
| 277 OS::PrintErr(" done.\n"); | 289 OS::PrintErr(" done.\n"); |
| 278 } | 290 } |
| 279 | 291 |
| 280 Timer timer(FLAG_verbose_gc, "Scavenge"); | 292 Timer timer(FLAG_verbose_gc, "Scavenge"); |
| 281 timer.Start(); | 293 timer.Start(); |
| 282 // Setup the visitor and run a scavenge. | 294 // Setup the visitor and run a scavenge. |
| 283 ScavengerVisitor visitor(this); | 295 ScavengerVisitor visitor(this); |
| 284 Prologue(); | 296 Prologue(isolate, invoke_api_callbacks); |
| 285 IterateRoots(isolate, &visitor); | 297 IterateRoots(isolate, &visitor, !invoke_api_callbacks); |
| 286 ProcessToSpace(&visitor); | 298 ProcessToSpace(&visitor); |
| 287 ScavengerWeakVisitor weak_visitor(this); | 299 ScavengerWeakVisitor weak_visitor(this); |
| 288 IterateWeakRoots(isolate, &weak_visitor); | 300 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); |
| 289 Epilogue(); | 301 Epilogue(isolate, invoke_api_callbacks); |
| 290 timer.Stop(); | 302 timer.Stop(); |
| 291 if (FLAG_verbose_gc) { | 303 if (FLAG_verbose_gc) { |
| 292 OS::PrintErr("Scavenge[%d]: %dus\n", count_, timer.TotalElapsedTime()); | 304 OS::PrintErr("Scavenge[%d]: %dus\n", count_, timer.TotalElapsedTime()); |
| 293 } | 305 } |
| 294 | 306 |
| 295 if (FLAG_verify_after_gc) { | 307 if (FLAG_verify_after_gc) { |
| 296 OS::PrintErr("Verifying after Scavenge... "); | 308 OS::PrintErr("Verifying after Scavenge... "); |
| 297 heap_->Verify(); | 309 heap_->Verify(); |
| 298 OS::PrintErr(" done.\n"); | 310 OS::PrintErr(" done.\n"); |
| 299 } | 311 } |
| 300 | 312 |
| 301 count_++; | 313 count_++; |
| 302 // Done scavenging. Reset the marker. | 314 // Done scavenging. Reset the marker. |
| 303 ASSERT(scavenging_); | 315 ASSERT(scavenging_); |
| 304 scavenging_ = false; | 316 scavenging_ = false; |
| 305 } | 317 } |
| 306 | 318 |
| 307 } // namespace dart | 319 } // namespace dart |
| OLD | NEW |