Chromium Code Reviews| 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/gc_marker.h" | 5 #include "vm/gc_marker.h" |
| 6 | 6 |
| 7 #include "vm/allocation.h" | 7 #include "vm/allocation.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/pages.h" | 10 #include "vm/pages.h" |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 | 181 |
| 182 Heap* heap_; | 182 Heap* heap_; |
| 183 Heap* vm_heap_; | 183 Heap* vm_heap_; |
| 184 PageSpace* page_space_; | 184 PageSpace* page_space_; |
| 185 MarkingStack* marking_stack_; | 185 MarkingStack* marking_stack_; |
| 186 | 186 |
| 187 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); | 187 DISALLOW_IMPLICIT_CONSTRUCTORS(MarkingVisitor); |
| 188 }; | 188 }; |
| 189 | 189 |
| 190 | 190 |
| 191 bool IsUnreachable(const RawObject* raw_obj) { | |
| 192 if (!raw_obj->IsHeapObject()) { | |
| 193 return false; | |
| 194 } | |
| 195 if (!raw_obj->IsOldObject()) { | |
| 196 return false; | |
| 197 } | |
| 198 return !raw_obj->IsMarked(); | |
|
siva
2012/03/02 18:30:33
Not sure if it matters but this seems slightly mor
cshapiro
2012/03/03 00:03:23
I think this ordering is preferable as IsMarked()
| |
| 199 } | |
| 200 | |
| 201 | |
| 191 class MarkingWeakVisitor : public HandleVisitor { | 202 class MarkingWeakVisitor : public HandleVisitor { |
| 192 public: | 203 public: |
| 193 MarkingWeakVisitor() { | 204 MarkingWeakVisitor() { |
| 194 } | 205 } |
| 195 | 206 |
| 196 void VisitHandle(uword addr) { | 207 void VisitHandle(uword addr) { |
| 197 WeakPersistentHandle* handle = | 208 WeakPersistentHandle* handle = |
| 198 reinterpret_cast<WeakPersistentHandle*>(addr); | 209 reinterpret_cast<WeakPersistentHandle*>(addr); |
| 199 RawObject* raw_obj = handle->raw(); | 210 RawObject* raw_obj = handle->raw(); |
| 200 if (!raw_obj->IsHeapObject()) return; | 211 if (IsUnreachable(raw_obj)) { |
| 201 if (!raw_obj->IsMarked() && raw_obj->IsOldObject()) { | |
| 202 WeakPersistentHandle::Finalize(handle); | 212 WeakPersistentHandle::Finalize(handle); |
| 203 } | 213 } |
| 204 } | 214 } |
| 205 | 215 |
| 206 private: | 216 private: |
| 207 DISALLOW_COPY_AND_ASSIGN(MarkingWeakVisitor); | 217 DISALLOW_COPY_AND_ASSIGN(MarkingWeakVisitor); |
| 208 }; | 218 }; |
| 209 | 219 |
| 210 | 220 |
| 211 void GCMarker::Prologue(Isolate* isolate) { | 221 void GCMarker::Prologue(Isolate* isolate) { |
| 212 // Nothing to do at the moment. | 222 // Nothing to do at the moment. |
| 213 } | 223 } |
| 214 | 224 |
| 215 | 225 |
| 216 void GCMarker::IterateRoots(Isolate* isolate, ObjectPointerVisitor* visitor) { | 226 void GCMarker::IterateRoots(Isolate* isolate, ObjectPointerVisitor* visitor) { |
| 217 isolate->VisitObjectPointers(visitor, | 227 isolate->VisitObjectPointers(visitor, |
| 218 StackFrameIterator::kDontValidateFrames); | 228 StackFrameIterator::kDontValidateFrames); |
| 219 heap_->IterateNewPointers(visitor); | 229 heap_->IterateNewPointers(visitor); |
| 220 heap_->IterateCodePointers(visitor); | 230 heap_->IterateCodePointers(visitor); |
| 221 } | 231 } |
| 222 | 232 |
| 223 | 233 |
| 224 void GCMarker::IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor) { | 234 void GCMarker::IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor) { |
| 225 isolate->VisitWeakPersistentHandles(visitor); | 235 isolate->VisitWeakPersistentHandles(visitor); |
| 226 } | 236 } |
| 227 | 237 |
| 228 | 238 |
| 239 void GCMarker::IterateWeakReferences(Isolate* isolate, | |
| 240 MarkingVisitor* visitor) { | |
| 241 ApiState* state = isolate->api_state(); | |
| 242 ASSERT(state != NULL); | |
| 243 for (;;) { | |
|
Ivan Posva
2012/03/05 19:04:42
while (true) {
| |
| 244 WeakReference* queue = state->delayed_weak_references(); | |
| 245 state->set_delayed_weak_references(NULL); | |
|
siva
2012/03/02 18:30:33
This setting could be moved after the 'if (queue !
cshapiro
2012/03/03 00:03:23
True. I'll do that.
| |
| 246 if (queue == NULL) { | |
| 247 break; | |
|
siva
2012/03/02 18:30:33
Could we return right here, instead of breaking ou
cshapiro
2012/03/03 00:03:23
Probably not as that would cause a space leak. Th
Ivan Posva
2012/03/05 19:04:42
I am not quite sure I follow your argument here. I
| |
| 248 } | |
| 249 while (queue != NULL) { | |
| 250 WeakReference* reference = WeakReference::Pop(&queue); | |
| 251 ASSERT(reference != NULL); | |
| 252 bool is_unreachable = true; | |
| 253 // Test each key object for reachability. If a key object is | |
| 254 // reachable, all value objects should be marked. | |
| 255 for (intptr_t k = 0; k < reference->num_keys(); ++k) { | |
| 256 if (!IsUnreachable(*reference->get_key(k))) { | |
| 257 for (intptr_t v = 0; v < reference->num_values(); ++v) { | |
| 258 visitor->VisitPointer(reference->get_value(v)); | |
| 259 } | |
| 260 is_unreachable = false; | |
| 261 delete reference; | |
| 262 break; | |
| 263 } | |
| 264 } | |
| 265 // If all key objects are unreachable put the reference on a | |
| 266 // delay queue. This reference will be revisited if another | |
| 267 // reference is marked. | |
| 268 if (is_unreachable) { | |
| 269 state->DelayWeakReference(reference); | |
| 270 } | |
| 271 } | |
| 272 if (!visitor->marking_stack()->IsEmpty()) { | |
| 273 DrainMarkingStack(isolate, visitor); | |
| 274 } else { | |
| 275 // Break out of the loop if there has been no forward process. | |
| 276 break; | |
| 277 } | |
| 278 } | |
| 279 // Deallocate any unmarked references on the delay queue. | |
| 280 if (state->delayed_weak_references() != NULL) { | |
| 281 WeakReference* queue = state->delayed_weak_references(); | |
| 282 state->set_delayed_weak_references(NULL); | |
| 283 while (queue != NULL) { | |
| 284 delete WeakReference::Pop(&queue); | |
| 285 } | |
| 286 } | |
| 287 } | |
| 288 | |
| 289 | |
| 229 void GCMarker::DrainMarkingStack(Isolate* isolate, | 290 void GCMarker::DrainMarkingStack(Isolate* isolate, |
| 230 MarkingVisitor* visitor) { | 291 MarkingVisitor* visitor) { |
| 231 while (!visitor->marking_stack()->IsEmpty()) { | 292 while (!visitor->marking_stack()->IsEmpty()) { |
| 232 RawObject* raw_obj = visitor->marking_stack()->Pop(); | 293 RawObject* raw_obj = visitor->marking_stack()->Pop(); |
| 233 raw_obj->VisitPointers(visitor); | 294 raw_obj->VisitPointers(visitor); |
| 234 } | 295 } |
| 235 } | 296 } |
| 236 | 297 |
| 237 | 298 |
| 238 void GCMarker::MarkObjects(Isolate* isolate, PageSpace* page_space) { | 299 void GCMarker::MarkObjects(Isolate* isolate, PageSpace* page_space) { |
| 239 MarkingStack marking_stack; | 300 MarkingStack marking_stack; |
| 240 Prologue(isolate); | 301 Prologue(isolate); |
| 241 MarkingVisitor mark(heap_, page_space, &marking_stack); | 302 MarkingVisitor mark(heap_, page_space, &marking_stack); |
| 242 IterateRoots(isolate, &mark); | 303 IterateRoots(isolate, &mark); |
| 243 DrainMarkingStack(isolate, &mark); | 304 DrainMarkingStack(isolate, &mark); |
| 305 IterateWeakReferences(isolate, &mark); | |
| 244 MarkingWeakVisitor mark_weak; | 306 MarkingWeakVisitor mark_weak; |
| 245 IterateWeakRoots(isolate, &mark_weak); | 307 IterateWeakRoots(isolate, &mark_weak); |
| 246 } | 308 } |
| 247 | 309 |
| 248 } // namespace dart | 310 } // namespace dart |
| OLD | NEW |