| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/heap/objects-visiting.h" | 7 #include "src/heap/objects-visiting.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 184 return heap->gc_state() == Heap::MARK_COMPACT && | 184 return heap->gc_state() == Heap::MARK_COMPACT && |
| 185 heap->mark_compact_collector()->is_compacting(); | 185 heap->mark_compact_collector()->is_compacting(); |
| 186 } | 186 } |
| 187 | 187 |
| 188 | 188 |
| 189 template <class T> | 189 template <class T> |
| 190 struct WeakListVisitor; | 190 struct WeakListVisitor; |
| 191 | 191 |
| 192 | 192 |
| 193 template <class T> | 193 template <class T> |
| 194 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer, | 194 Object* VisitWeakList(Heap* heap, Object* list, WeakObjectRetainer* retainer) { |
| 195 bool stop_after_young) { | |
| 196 Object* undefined = heap->undefined_value(); | 195 Object* undefined = heap->undefined_value(); |
| 197 Object* head = undefined; | 196 Object* head = undefined; |
| 198 T* tail = NULL; | 197 T* tail = NULL; |
| 199 MarkCompactCollector* collector = heap->mark_compact_collector(); | 198 MarkCompactCollector* collector = heap->mark_compact_collector(); |
| 200 bool record_slots = MustRecordSlots(heap); | 199 bool record_slots = MustRecordSlots(heap); |
| 201 | |
| 202 while (list != undefined) { | 200 while (list != undefined) { |
| 203 // Check whether to keep the candidate in the list. | 201 // Check whether to keep the candidate in the list. |
| 204 T* candidate = reinterpret_cast<T*>(list); | 202 T* candidate = reinterpret_cast<T*>(list); |
| 205 T* original_candidate = candidate; | |
| 206 | |
| 207 Object* retained = retainer->RetainAs(list); | 203 Object* retained = retainer->RetainAs(list); |
| 208 if (retained != NULL) { | 204 if (retained != NULL) { |
| 209 if (head == undefined) { | 205 if (head == undefined) { |
| 210 // First element in the list. | 206 // First element in the list. |
| 211 head = retained; | 207 head = retained; |
| 212 } else { | 208 } else { |
| 213 // Subsequent elements in the list. | 209 // Subsequent elements in the list. |
| 214 DCHECK(tail != NULL); | 210 DCHECK(tail != NULL); |
| 215 WeakListVisitor<T>::SetWeakNext(tail, retained); | 211 WeakListVisitor<T>::SetWeakNext(tail, retained); |
| 216 if (record_slots) { | 212 if (record_slots) { |
| 217 Object** next_slot = | 213 Object** next_slot = |
| 218 HeapObject::RawField(tail, WeakListVisitor<T>::WeakNextOffset()); | 214 HeapObject::RawField(tail, WeakListVisitor<T>::WeakNextOffset()); |
| 219 collector->RecordSlot(next_slot, next_slot, retained); | 215 collector->RecordSlot(next_slot, next_slot, retained); |
| 220 } | 216 } |
| 221 } | 217 } |
| 222 // Retained object is new tail. | 218 // Retained object is new tail. |
| 223 DCHECK(!retained->IsUndefined()); | 219 DCHECK(!retained->IsUndefined()); |
| 224 candidate = reinterpret_cast<T*>(retained); | 220 candidate = reinterpret_cast<T*>(retained); |
| 225 tail = candidate; | 221 tail = candidate; |
| 226 | 222 |
| 223 |
| 227 // tail is a live object, visit it. | 224 // tail is a live object, visit it. |
| 228 WeakListVisitor<T>::VisitLiveObject(heap, tail, retainer); | 225 WeakListVisitor<T>::VisitLiveObject(heap, tail, retainer); |
| 229 | |
| 230 // The list of weak objects is usually order. It starts with objects | |
| 231 // recently allocated in the young generation followed by objects | |
| 232 // allocated in the old generation. When a promotion failure happens, | |
| 233 // the list is not ordered until the next GC. | |
| 234 // For young generation collections we just have to visit until the last | |
| 235 // young generation objects. | |
| 236 if (stop_after_young && !heap->promotion_failure() && | |
| 237 !heap->InNewSpace(original_candidate)) { | |
| 238 return head; | |
| 239 } | |
| 240 } else { | 226 } else { |
| 241 WeakListVisitor<T>::VisitPhantomObject(heap, candidate); | 227 WeakListVisitor<T>::VisitPhantomObject(heap, candidate); |
| 242 } | 228 } |
| 243 | 229 |
| 244 // Move to next element in the list. | 230 // Move to next element in the list. |
| 245 list = WeakListVisitor<T>::WeakNext(candidate); | 231 list = WeakListVisitor<T>::WeakNext(candidate); |
| 246 } | 232 } |
| 247 | 233 |
| 248 // Terminate the list if there is one or more elements. | 234 // Terminate the list if there is one or more elements. |
| 249 if (tail != NULL) { | 235 if (tail != NULL) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 323 if (heap->gc_state() == Heap::MARK_COMPACT) { | 309 if (heap->gc_state() == Heap::MARK_COMPACT) { |
| 324 DoWeakList<Code>(heap, context, retainer, Context::OPTIMIZED_CODE_LIST); | 310 DoWeakList<Code>(heap, context, retainer, Context::OPTIMIZED_CODE_LIST); |
| 325 DoWeakList<Code>(heap, context, retainer, Context::DEOPTIMIZED_CODE_LIST); | 311 DoWeakList<Code>(heap, context, retainer, Context::DEOPTIMIZED_CODE_LIST); |
| 326 } | 312 } |
| 327 } | 313 } |
| 328 | 314 |
| 329 template <class T> | 315 template <class T> |
| 330 static void DoWeakList(Heap* heap, Context* context, | 316 static void DoWeakList(Heap* heap, Context* context, |
| 331 WeakObjectRetainer* retainer, int index) { | 317 WeakObjectRetainer* retainer, int index) { |
| 332 // Visit the weak list, removing dead intermediate elements. | 318 // Visit the weak list, removing dead intermediate elements. |
| 333 Object* list_head = | 319 Object* list_head = VisitWeakList<T>(heap, context->get(index), retainer); |
| 334 VisitWeakList<T>(heap, context->get(index), retainer, false); | |
| 335 | 320 |
| 336 // Update the list head. | 321 // Update the list head. |
| 337 context->set(index, list_head, UPDATE_WRITE_BARRIER); | 322 context->set(index, list_head, UPDATE_WRITE_BARRIER); |
| 338 | 323 |
| 339 if (MustRecordSlots(heap)) { | 324 if (MustRecordSlots(heap)) { |
| 340 // Record the updated slot if necessary. | 325 // Record the updated slot if necessary. |
| 341 Object** head_slot = | 326 Object** head_slot = |
| 342 HeapObject::RawField(context, FixedArray::SizeFor(index)); | 327 HeapObject::RawField(context, FixedArray::SizeFor(index)); |
| 343 heap->mark_compact_collector()->RecordSlot(head_slot, head_slot, | 328 heap->mark_compact_collector()->RecordSlot(head_slot, head_slot, |
| 344 list_head); | 329 list_head); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 obj->set_weak_next(next); | 361 obj->set_weak_next(next); |
| 377 } | 362 } |
| 378 | 363 |
| 379 static Object* WeakNext(JSArrayBuffer* obj) { return obj->weak_next(); } | 364 static Object* WeakNext(JSArrayBuffer* obj) { return obj->weak_next(); } |
| 380 | 365 |
| 381 static int WeakNextOffset() { return JSArrayBuffer::kWeakNextOffset; } | 366 static int WeakNextOffset() { return JSArrayBuffer::kWeakNextOffset; } |
| 382 | 367 |
| 383 static void VisitLiveObject(Heap* heap, JSArrayBuffer* array_buffer, | 368 static void VisitLiveObject(Heap* heap, JSArrayBuffer* array_buffer, |
| 384 WeakObjectRetainer* retainer) { | 369 WeakObjectRetainer* retainer) { |
| 385 Object* typed_array_obj = VisitWeakList<JSArrayBufferView>( | 370 Object* typed_array_obj = VisitWeakList<JSArrayBufferView>( |
| 386 heap, array_buffer->weak_first_view(), retainer, false); | 371 heap, array_buffer->weak_first_view(), retainer); |
| 387 array_buffer->set_weak_first_view(typed_array_obj); | 372 array_buffer->set_weak_first_view(typed_array_obj); |
| 388 if (typed_array_obj != heap->undefined_value() && MustRecordSlots(heap)) { | 373 if (typed_array_obj != heap->undefined_value() && MustRecordSlots(heap)) { |
| 389 Object** slot = HeapObject::RawField(array_buffer, | 374 Object** slot = HeapObject::RawField(array_buffer, |
| 390 JSArrayBuffer::kWeakFirstViewOffset); | 375 JSArrayBuffer::kWeakFirstViewOffset); |
| 391 heap->mark_compact_collector()->RecordSlot(slot, slot, typed_array_obj); | 376 heap->mark_compact_collector()->RecordSlot(slot, slot, typed_array_obj); |
| 392 } | 377 } |
| 393 } | 378 } |
| 394 | 379 |
| 395 static void VisitPhantomObject(Heap* heap, JSArrayBuffer* phantom) { | 380 static void VisitPhantomObject(Heap* heap, JSArrayBuffer* phantom) { |
| 396 Runtime::FreeArrayBuffer(heap->isolate(), phantom); | 381 Runtime::FreeArrayBuffer(heap->isolate(), phantom); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 407 static Object* WeakNext(AllocationSite* obj) { return obj->weak_next(); } | 392 static Object* WeakNext(AllocationSite* obj) { return obj->weak_next(); } |
| 408 | 393 |
| 409 static int WeakNextOffset() { return AllocationSite::kWeakNextOffset; } | 394 static int WeakNextOffset() { return AllocationSite::kWeakNextOffset; } |
| 410 | 395 |
| 411 static void VisitLiveObject(Heap*, AllocationSite*, WeakObjectRetainer*) {} | 396 static void VisitLiveObject(Heap*, AllocationSite*, WeakObjectRetainer*) {} |
| 412 | 397 |
| 413 static void VisitPhantomObject(Heap*, AllocationSite*) {} | 398 static void VisitPhantomObject(Heap*, AllocationSite*) {} |
| 414 }; | 399 }; |
| 415 | 400 |
| 416 | 401 |
| 402 template Object* VisitWeakList<Code>(Heap* heap, Object* list, |
| 403 WeakObjectRetainer* retainer); |
| 404 |
| 405 |
| 406 template Object* VisitWeakList<JSFunction>(Heap* heap, Object* list, |
| 407 WeakObjectRetainer* retainer); |
| 408 |
| 409 |
| 417 template Object* VisitWeakList<Context>(Heap* heap, Object* list, | 410 template Object* VisitWeakList<Context>(Heap* heap, Object* list, |
| 418 WeakObjectRetainer* retainer, | 411 WeakObjectRetainer* retainer); |
| 419 bool stop_after_young); | |
| 420 | 412 |
| 421 | 413 |
| 422 template Object* VisitWeakList<JSArrayBuffer>(Heap* heap, Object* list, | 414 template Object* VisitWeakList<JSArrayBuffer>(Heap* heap, Object* list, |
| 423 WeakObjectRetainer* retainer, | 415 WeakObjectRetainer* retainer); |
| 424 bool stop_after_young); | |
| 425 | 416 |
| 426 template Object* VisitWeakList<JSArrayBufferView>(Heap* heap, Object* list, | |
| 427 WeakObjectRetainer* retainer, | |
| 428 bool stop_after_young); | |
| 429 | 417 |
| 430 template Object* VisitWeakList<AllocationSite>(Heap* heap, Object* list, | 418 template Object* VisitWeakList<AllocationSite>(Heap* heap, Object* list, |
| 431 WeakObjectRetainer* retainer, | 419 WeakObjectRetainer* retainer); |
| 432 bool stop_after_young); | |
| 433 } | 420 } |
| 434 } // namespace v8::internal | 421 } // namespace v8::internal |
| OLD | NEW |