| 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 to_ = new MemoryRegion(space_->address(), semi_space_size); | 170 to_ = new MemoryRegion(space_->address(), semi_space_size); |
| 171 uword middle = space_->start() + semi_space_size; | 171 uword middle = space_->start() + semi_space_size; |
| 172 from_ = new MemoryRegion(reinterpret_cast<void*>(middle), semi_space_size); | 172 from_ = new MemoryRegion(reinterpret_cast<void*>(middle), semi_space_size); |
| 173 | 173 |
| 174 // Make sure that the two semi-spaces are aligned properly. | 174 // Make sure that the two semi-spaces are aligned properly. |
| 175 ASSERT(Utils::IsAligned(to_->start(), kObjectAlignment)); | 175 ASSERT(Utils::IsAligned(to_->start(), kObjectAlignment)); |
| 176 ASSERT(Utils::IsAligned(from_->start(), kObjectAlignment)); | 176 ASSERT(Utils::IsAligned(from_->start(), kObjectAlignment)); |
| 177 | 177 |
| 178 // Setup local fields. | 178 // Setup local fields. |
| 179 top_ = FirstObjectStart(); | 179 top_ = FirstObjectStart(); |
| 180 resolved_top_ = top_; |
| 180 end_ = to_->end(); | 181 end_ = to_->end(); |
| 181 | 182 |
| 182 survivor_end_ = FirstObjectStart(); | 183 survivor_end_ = FirstObjectStart(); |
| 183 | 184 |
| 184 #if defined(DEBUG) | 185 #if defined(DEBUG) |
| 185 memset(to_->pointer(), 0xf3, to_->size()); | 186 memset(to_->pointer(), 0xf3, to_->size()); |
| 186 memset(from_->pointer(), 0xf3, from_->size()); | 187 memset(from_->pointer(), 0xf3, from_->size()); |
| 187 #endif // defined(DEBUG) | 188 #endif // defined(DEBUG) |
| 188 } | 189 } |
| 189 | 190 |
| 190 | 191 |
| 191 Scavenger::~Scavenger() { | 192 Scavenger::~Scavenger() { |
| 192 delete to_; | 193 delete to_; |
| 193 delete from_; | 194 delete from_; |
| 194 delete space_; | 195 delete space_; |
| 195 } | 196 } |
| 196 | 197 |
| 197 | 198 |
| 198 void Scavenger::Prologue(Isolate* isolate, bool invoke_api_callbacks) { | 199 void Scavenger::Prologue(Isolate* isolate, bool invoke_api_callbacks) { |
| 199 if (invoke_api_callbacks) { | 200 if (invoke_api_callbacks) { |
| 200 isolate->gc_prologue_callbacks().Invoke(); | 201 isolate->gc_prologue_callbacks().Invoke(); |
| 201 } | 202 } |
| 202 // Flip the two semi-spaces so that to_ is always the space for allocating | 203 // Flip the two semi-spaces so that to_ is always the space for allocating |
| 203 // objects. | 204 // objects. |
| 204 MemoryRegion* temp = from_; | 205 MemoryRegion* temp = from_; |
| 205 from_ = to_; | 206 from_ = to_; |
| 206 to_ = temp; | 207 to_ = temp; |
| 207 top_ = FirstObjectStart(); | 208 top_ = FirstObjectStart(); |
| 209 resolved_top_ = top_; |
| 208 end_ = to_->end(); | 210 end_ = to_->end(); |
| 209 } | 211 } |
| 210 | 212 |
| 211 | 213 |
| 212 void Scavenger::Epilogue(Isolate* isolate, bool invoke_api_callbacks) { | 214 void Scavenger::Epilogue(Isolate* isolate, bool invoke_api_callbacks) { |
| 213 // All objects in the to space have been copied from the from space at this | 215 // All objects in the to space have been copied from the from space at this |
| 214 // moment. | 216 // moment. |
| 215 survivor_end_ = top_; | 217 survivor_end_ = top_; |
| 216 | 218 |
| 217 #if defined(DEBUG) | 219 #if defined(DEBUG) |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 break; | 284 break; |
| 283 } | 285 } |
| 284 } | 286 } |
| 285 // If all key objects are unreachable put the reference on a | 287 // If all key objects are unreachable put the reference on a |
| 286 // delay queue. This reference will be revisited if another | 288 // delay queue. This reference will be revisited if another |
| 287 // reference is scavenged. | 289 // reference is scavenged. |
| 288 if (is_unreachable) { | 290 if (is_unreachable) { |
| 289 state->DelayWeakReference(reference); | 291 state->DelayWeakReference(reference); |
| 290 } | 292 } |
| 291 } | 293 } |
| 292 if ((FirstObjectStart() < top_) || PromotedStackHasMore()) { | 294 if ((resolved_top_ < top_) || PromotedStackHasMore()) { |
| 293 ProcessToSpace(visitor); | 295 ProcessToSpace(visitor); |
| 294 } else { | 296 } else { |
| 295 // Break out of the loop if there has been no forward process. | 297 // Break out of the loop if there has been no forward process. |
| 296 break; | 298 break; |
| 297 } | 299 } |
| 298 } | 300 } |
| 299 // Deallocate any unreachable references on the delay queue. | 301 // Deallocate any unreachable references on the delay queue. |
| 300 if (state->delayed_weak_references() != NULL) { | 302 if (state->delayed_weak_references() != NULL) { |
| 301 WeakReference* queue = state->delayed_weak_references(); | 303 WeakReference* queue = state->delayed_weak_references(); |
| 302 state->set_delayed_weak_references(NULL); | 304 state->set_delayed_weak_references(NULL); |
| 303 while (queue != NULL) { | 305 while (queue != NULL) { |
| 304 delete WeakReference::Pop(&queue); | 306 delete WeakReference::Pop(&queue); |
| 305 } | 307 } |
| 306 } | 308 } |
| 307 } | 309 } |
| 308 | 310 |
| 309 | 311 |
| 310 void Scavenger::IterateWeakRoots(Isolate* isolate, | 312 void Scavenger::IterateWeakRoots(Isolate* isolate, |
| 311 HandleVisitor* visitor, | 313 HandleVisitor* visitor, |
| 312 bool visit_prologue_weak_persistent_handles) { | 314 bool visit_prologue_weak_persistent_handles) { |
| 313 isolate->VisitWeakPersistentHandles(visitor, | 315 isolate->VisitWeakPersistentHandles(visitor, |
| 314 visit_prologue_weak_persistent_handles); | 316 visit_prologue_weak_persistent_handles); |
| 315 } | 317 } |
| 316 | 318 |
| 317 | 319 |
| 318 void Scavenger::ProcessToSpace(ObjectPointerVisitor* visitor) { | 320 void Scavenger::ProcessToSpace(ObjectPointerVisitor* visitor) { |
| 319 uword resolved_top = FirstObjectStart(); | |
| 320 // Iterate until all work has been drained. | 321 // Iterate until all work has been drained. |
| 321 while ((resolved_top < top_) || PromotedStackHasMore()) { | 322 while ((resolved_top_ < top_) || PromotedStackHasMore()) { |
| 322 while (resolved_top < top_) { | 323 while (resolved_top_ < top_) { |
| 323 RawObject* raw_obj = RawObject::FromAddr(resolved_top); | 324 RawObject* raw_obj = RawObject::FromAddr(resolved_top_); |
| 324 resolved_top += raw_obj->VisitPointers(visitor); | 325 resolved_top_ += raw_obj->VisitPointers(visitor); |
| 325 } | 326 } |
| 326 while (PromotedStackHasMore()) { | 327 while (PromotedStackHasMore()) { |
| 327 RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack()); | 328 RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack()); |
| 328 // Resolve or copy all objects referred to by the current object. This | 329 // Resolve or copy all objects referred to by the current object. This |
| 329 // can potentially push more objects on this stack as well as add more | 330 // can potentially push more objects on this stack as well as add more |
| 330 // objects to be resolved in the to space. | 331 // objects to be resolved in the to space. |
| 331 raw_object->VisitPointers(visitor); | 332 raw_object->VisitPointers(visitor); |
| 332 } | 333 } |
| 333 } | 334 } |
| 334 } | 335 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 OS::PrintErr(" done.\n"); | 386 OS::PrintErr(" done.\n"); |
| 386 } | 387 } |
| 387 | 388 |
| 388 count_++; | 389 count_++; |
| 389 // Done scavenging. Reset the marker. | 390 // Done scavenging. Reset the marker. |
| 390 ASSERT(scavenging_); | 391 ASSERT(scavenging_); |
| 391 scavenging_ = false; | 392 scavenging_ = false; |
| 392 } | 393 } |
| 393 | 394 |
| 394 } // namespace dart | 395 } // namespace dart |
| OLD | NEW |