| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 313 | 313 |
| 314 table_.RegisterSpecializations<JSObjectVisitor, | 314 table_.RegisterSpecializations<JSObjectVisitor, |
| 315 kVisitJSObject, | 315 kVisitJSObject, |
| 316 kVisitJSObjectGeneric>(); | 316 kVisitJSObjectGeneric>(); |
| 317 | 317 |
| 318 table_.RegisterSpecializations<StructObjectVisitor, | 318 table_.RegisterSpecializations<StructObjectVisitor, |
| 319 kVisitStruct, | 319 kVisitStruct, |
| 320 kVisitStructGeneric>(); | 320 kVisitStructGeneric>(); |
| 321 } | 321 } |
| 322 | 322 |
| 323 INLINE(static void VisitPointer(Object** p)) { | 323 INLINE(static void VisitPointer(Heap* heap, Object** p)) { |
| 324 MarkObjectByPointer(p); | 324 MarkObjectByPointer(heap, p); |
| 325 } | 325 } |
| 326 | 326 |
| 327 INLINE(static void VisitPointers(Object** start, Object** end)) { | 327 INLINE(static void VisitPointers(Heap* heap, Object** start, Object** end)) { |
| 328 // Mark all objects pointed to in [start, end). | 328 // Mark all objects pointed to in [start, end). |
| 329 const int kMinRangeForMarkingRecursion = 64; | 329 const int kMinRangeForMarkingRecursion = 64; |
| 330 if (end - start >= kMinRangeForMarkingRecursion) { | 330 if (end - start >= kMinRangeForMarkingRecursion) { |
| 331 if (VisitUnmarkedObjects(start, end)) return; | 331 if (VisitUnmarkedObjects(heap, start, end)) return; |
| 332 // We are close to a stack overflow, so just mark the objects. | 332 // We are close to a stack overflow, so just mark the objects. |
| 333 } | 333 } |
| 334 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); | 334 for (Object** p = start; p < end; p++) MarkObjectByPointer(heap, p); |
| 335 } | 335 } |
| 336 | 336 |
| 337 static inline void VisitCodeTarget(RelocInfo* rinfo) { | 337 static inline void VisitCodeTarget(RelocInfo* rinfo) { |
| 338 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 338 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); |
| 339 Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 339 Code* code = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
| 340 if (FLAG_cleanup_ics_at_gc && code->is_inline_cache_stub()) { | 340 if (FLAG_cleanup_ics_at_gc && code->is_inline_cache_stub()) { |
| 341 IC::Clear(rinfo->pc()); | 341 IC::Clear(rinfo->pc()); |
| 342 // Please note targets for cleared inline cached do not have to be | 342 // Please note targets for cleared inline cached do not have to be |
| 343 // marked since they are contained in HEAP->non_monomorphic_cache(). | 343 // marked since they are contained in HEAP->non_monomorphic_cache(). |
| 344 } else { | 344 } else { |
| 345 HEAP->mark_compact_collector()->MarkObject(code); | 345 HEAP->mark_compact_collector()->MarkObject(code); |
| 346 } | 346 } |
| 347 } | 347 } |
| 348 | 348 |
| 349 static inline void VisitDebugTarget(RelocInfo* rinfo) { | 349 static inline void VisitDebugTarget(RelocInfo* rinfo) { |
| 350 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && | 350 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && |
| 351 rinfo->IsPatchedReturnSequence()) || | 351 rinfo->IsPatchedReturnSequence()) || |
| 352 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 352 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && |
| 353 rinfo->IsPatchedDebugBreakSlotSequence())); | 353 rinfo->IsPatchedDebugBreakSlotSequence())); |
| 354 HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address()); | 354 HeapObject* code = Code::GetCodeFromTargetAddress(rinfo->call_address()); |
| 355 HEAP->mark_compact_collector()->MarkObject(code); | 355 HEAP->mark_compact_collector()->MarkObject(code); |
| 356 } | 356 } |
| 357 | 357 |
| 358 // Mark object pointed to by p. | 358 // Mark object pointed to by p. |
| 359 INLINE(static void MarkObjectByPointer(Object** p)) { | 359 INLINE(static void MarkObjectByPointer(Heap* heap, Object** p)) { |
| 360 if (!(*p)->IsHeapObject()) return; | 360 if (!(*p)->IsHeapObject()) return; |
| 361 HeapObject* object = ShortCircuitConsString(p); | 361 HeapObject* object = ShortCircuitConsString(p); |
| 362 HEAP->mark_compact_collector()->MarkObject(object); | 362 heap->mark_compact_collector()->MarkObject(object); |
| 363 } | 363 } |
| 364 | 364 |
| 365 | 365 |
| 366 // Visit an unmarked object. | 366 // Visit an unmarked object. |
| 367 static inline void VisitUnmarkedObject(HeapObject* obj) { | 367 static inline void VisitUnmarkedObject(HeapObject* obj) { |
| 368 #ifdef DEBUG | 368 #ifdef DEBUG |
| 369 ASSERT(HEAP->Contains(obj)); | 369 ASSERT(HEAP->Contains(obj)); |
| 370 ASSERT(!obj->IsMarked()); | 370 ASSERT(!obj->IsMarked()); |
| 371 #endif | 371 #endif |
| 372 Map* map = obj->map(); | 372 Map* map = obj->map(); |
| 373 map->heap()->mark_compact_collector()->SetMark(obj); | 373 MarkCompactCollector* collector = map->heap()->mark_compact_collector(); |
| 374 collector->SetMark(obj); |
| 374 // Mark the map pointer and the body. | 375 // Mark the map pointer and the body. |
| 375 map->heap()->mark_compact_collector()->MarkObject(map); | 376 collector->MarkObject(map); |
| 376 IterateBody(map, obj); | 377 IterateBody(map, obj); |
| 377 } | 378 } |
| 378 | 379 |
| 379 // Visit all unmarked objects pointed to by [start, end). | 380 // Visit all unmarked objects pointed to by [start, end). |
| 380 // Returns false if the operation fails (lack of stack space). | 381 // Returns false if the operation fails (lack of stack space). |
| 381 static inline bool VisitUnmarkedObjects(Object** start, Object** end) { | 382 static inline bool VisitUnmarkedObjects(Heap* heap, |
| 383 Object** start, |
| 384 Object** end) { |
| 382 // Return false is we are close to the stack limit. | 385 // Return false is we are close to the stack limit. |
| 383 StackLimitCheck check(Isolate::Current()); | 386 StackLimitCheck check(heap->isolate()); |
| 384 if (check.HasOverflowed()) return false; | 387 if (check.HasOverflowed()) return false; |
| 385 | 388 |
| 386 // Visit the unmarked objects. | 389 // Visit the unmarked objects. |
| 387 for (Object** p = start; p < end; p++) { | 390 for (Object** p = start; p < end; p++) { |
| 388 if (!(*p)->IsHeapObject()) continue; | 391 if (!(*p)->IsHeapObject()) continue; |
| 389 HeapObject* obj = HeapObject::cast(*p); | 392 HeapObject* obj = HeapObject::cast(*p); |
| 390 if (obj->IsMarked()) continue; | 393 if (obj->IsMarked()) continue; |
| 391 VisitUnmarkedObject(obj); | 394 VisitUnmarkedObject(obj); |
| 392 } | 395 } |
| 393 return true; | 396 return true; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 409 | 412 |
| 410 typedef FlexibleBodyVisitor<StaticMarkingVisitor, | 413 typedef FlexibleBodyVisitor<StaticMarkingVisitor, |
| 411 JSObject::BodyDescriptor, | 414 JSObject::BodyDescriptor, |
| 412 void> JSObjectVisitor; | 415 void> JSObjectVisitor; |
| 413 | 416 |
| 414 typedef FlexibleBodyVisitor<StaticMarkingVisitor, | 417 typedef FlexibleBodyVisitor<StaticMarkingVisitor, |
| 415 StructBodyDescriptor, | 418 StructBodyDescriptor, |
| 416 void> StructObjectVisitor; | 419 void> StructObjectVisitor; |
| 417 | 420 |
| 418 static void VisitCode(Map* map, HeapObject* object) { | 421 static void VisitCode(Map* map, HeapObject* object) { |
| 419 reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>(); | 422 reinterpret_cast<Code*>(object)->CodeIterateBody<StaticMarkingVisitor>( |
| 423 map->heap()); |
| 420 } | 424 } |
| 421 | 425 |
| 422 // Code flushing support. | 426 // Code flushing support. |
| 423 | 427 |
| 424 // How many collections newly compiled code object will survive before being | 428 // How many collections newly compiled code object will survive before being |
| 425 // flushed. | 429 // flushed. |
| 426 static const int kCodeAgeThreshold = 5; | 430 static const int kCodeAgeThreshold = 5; |
| 427 | 431 |
| 428 inline static bool HasSourceCode(SharedFunctionInfo* info) { | 432 inline static bool HasSourceCode(SharedFunctionInfo* info) { |
| 429 Object* undefined = HEAP->raw_unchecked_undefined_value(); | 433 Object* undefined = HEAP->raw_unchecked_undefined_value(); |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 529 Context* context = reinterpret_cast<Context*>(ctx); | 533 Context* context = reinterpret_cast<Context*>(ctx); |
| 530 | 534 |
| 531 if (IsJSBuiltinsObject(context->global())) { | 535 if (IsJSBuiltinsObject(context->global())) { |
| 532 return false; | 536 return false; |
| 533 } | 537 } |
| 534 | 538 |
| 535 return true; | 539 return true; |
| 536 } | 540 } |
| 537 | 541 |
| 538 | 542 |
| 539 static void VisitCodeEntry(Address entry_address) { | 543 static void VisitCodeEntry(Heap* heap, Address entry_address) { |
| 540 Object* code = Code::GetObjectFromEntryAddress(entry_address); | 544 Object* code = Code::GetObjectFromEntryAddress(entry_address); |
| 541 Object* old_code = code; | 545 Object* old_code = code; |
| 542 VisitPointer(&code); | 546 VisitPointer(heap, &code); |
| 543 if (code != old_code) { | 547 if (code != old_code) { |
| 544 Memory::Address_at(entry_address) = | 548 Memory::Address_at(entry_address) = |
| 545 reinterpret_cast<Code*>(code)->entry(); | 549 reinterpret_cast<Code*>(code)->entry(); |
| 546 } | 550 } |
| 547 } | 551 } |
| 548 | 552 |
| 549 | 553 |
| 550 static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) { | 554 static void VisitJSFunctionAndFlushCode(Map* map, HeapObject* object) { |
| 551 JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); | 555 JSFunction* jsfunction = reinterpret_cast<JSFunction*>(object); |
| 552 // The function must have a valid context and not be a builtin. | 556 // The function must have a valid context and not be a builtin. |
| 553 if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) { | 557 if (IsValidNotBuiltinContext(jsfunction->unchecked_context())) { |
| 554 FlushCodeForFunction(jsfunction); | 558 FlushCodeForFunction(jsfunction); |
| 555 } | 559 } |
| 556 VisitJSFunction(map, object); | 560 VisitJSFunction(map, object); |
| 557 } | 561 } |
| 558 | 562 |
| 559 | 563 |
| 560 static void VisitJSFunction(Map* map, HeapObject* object) { | 564 static void VisitJSFunction(Map* map, HeapObject* object) { |
| 561 #define SLOT_ADDR(obj, offset) \ | 565 #define SLOT_ADDR(obj, offset) \ |
| 562 reinterpret_cast<Object**>((obj)->address() + offset) | 566 reinterpret_cast<Object**>((obj)->address() + offset) |
| 563 | 567 Heap* heap = map->heap(); |
| 564 VisitPointers(SLOT_ADDR(object, JSFunction::kPropertiesOffset), | 568 VisitPointers(heap, |
| 569 SLOT_ADDR(object, JSFunction::kPropertiesOffset), |
| 565 SLOT_ADDR(object, JSFunction::kCodeEntryOffset)); | 570 SLOT_ADDR(object, JSFunction::kCodeEntryOffset)); |
| 566 | 571 |
| 567 VisitCodeEntry(object->address() + JSFunction::kCodeEntryOffset); | 572 VisitCodeEntry(heap, object->address() + JSFunction::kCodeEntryOffset); |
| 568 | 573 |
| 569 VisitPointers(SLOT_ADDR(object, | 574 VisitPointers(heap, |
| 575 SLOT_ADDR(object, |
| 570 JSFunction::kCodeEntryOffset + kPointerSize), | 576 JSFunction::kCodeEntryOffset + kPointerSize), |
| 571 SLOT_ADDR(object, JSFunction::kSize)); | 577 SLOT_ADDR(object, JSFunction::kSize)); |
| 572 #undef SLOT_ADDR | 578 #undef SLOT_ADDR |
| 573 } | 579 } |
| 574 | 580 |
| 575 | 581 |
| 576 typedef void (*Callback)(Map* map, HeapObject* object); | 582 typedef void (*Callback)(Map* map, HeapObject* object); |
| 577 | 583 |
| 578 static VisitorDispatchTable<Callback> table_; | 584 static VisitorDispatchTable<Callback> table_; |
| 579 }; | 585 }; |
| 580 | 586 |
| 581 | 587 |
| 582 VisitorDispatchTable<StaticMarkingVisitor::Callback> | 588 VisitorDispatchTable<StaticMarkingVisitor::Callback> |
| 583 StaticMarkingVisitor::table_; | 589 StaticMarkingVisitor::table_; |
| 584 | 590 |
| 585 | 591 |
| 586 class MarkingVisitor : public ObjectVisitor { | 592 class MarkingVisitor : public ObjectVisitor { |
| 587 public: | 593 public: |
| 594 explicit MarkingVisitor(Heap* heap) : heap_(heap) { } |
| 595 |
| 588 void VisitPointer(Object** p) { | 596 void VisitPointer(Object** p) { |
| 589 StaticMarkingVisitor::VisitPointer(p); | 597 StaticMarkingVisitor::VisitPointer(heap_, p); |
| 590 } | 598 } |
| 591 | 599 |
| 592 void VisitPointers(Object** start, Object** end) { | 600 void VisitPointers(Object** start, Object** end) { |
| 593 StaticMarkingVisitor::VisitPointers(start, end); | 601 StaticMarkingVisitor::VisitPointers(heap_, start, end); |
| 594 } | 602 } |
| 595 | 603 |
| 596 void VisitCodeTarget(RelocInfo* rinfo) { | 604 void VisitCodeTarget(RelocInfo* rinfo) { |
| 597 StaticMarkingVisitor::VisitCodeTarget(rinfo); | 605 StaticMarkingVisitor::VisitCodeTarget(rinfo); |
| 598 } | 606 } |
| 599 | 607 |
| 600 void VisitDebugTarget(RelocInfo* rinfo) { | 608 void VisitDebugTarget(RelocInfo* rinfo) { |
| 601 StaticMarkingVisitor::VisitDebugTarget(rinfo); | 609 StaticMarkingVisitor::VisitDebugTarget(rinfo); |
| 602 } | 610 } |
| 611 |
| 612 private: |
| 613 Heap* heap_; |
| 603 }; | 614 }; |
| 604 | 615 |
| 605 | 616 |
| 606 class CodeMarkingVisitor : public ThreadVisitor { | 617 class CodeMarkingVisitor : public ThreadVisitor { |
| 607 public: | 618 public: |
| 608 void VisitThread(ThreadLocalTop* top) { | 619 void VisitThread(ThreadLocalTop* top) { |
| 609 for (StackFrameIterator it(top); !it.done(); it.Advance()) { | 620 for (StackFrameIterator it(top); !it.done(); it.Advance()) { |
| 610 HEAP->mark_compact_collector()->MarkObject(it.frame()->unchecked_code()); | 621 HEAP->mark_compact_collector()->MarkObject(it.frame()->unchecked_code()); |
| 611 } | 622 } |
| 612 } | 623 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 657 SharedFunctionInfoMarkingVisitor visitor; | 668 SharedFunctionInfoMarkingVisitor visitor; |
| 658 Isolate::Current()->compilation_cache()->IterateFunctions(&visitor); | 669 Isolate::Current()->compilation_cache()->IterateFunctions(&visitor); |
| 659 | 670 |
| 660 HEAP->mark_compact_collector()->ProcessMarkingStack(); | 671 HEAP->mark_compact_collector()->ProcessMarkingStack(); |
| 661 } | 672 } |
| 662 | 673 |
| 663 | 674 |
| 664 // Visitor class for marking heap roots. | 675 // Visitor class for marking heap roots. |
| 665 class RootMarkingVisitor : public ObjectVisitor { | 676 class RootMarkingVisitor : public ObjectVisitor { |
| 666 public: | 677 public: |
| 678 explicit RootMarkingVisitor(Heap* heap) |
| 679 : collector_(heap->mark_compact_collector()) { } |
| 680 |
| 667 void VisitPointer(Object** p) { | 681 void VisitPointer(Object** p) { |
| 668 MarkObjectByPointer(p); | 682 MarkObjectByPointer(p); |
| 669 } | 683 } |
| 670 | 684 |
| 671 void VisitPointers(Object** start, Object** end) { | 685 void VisitPointers(Object** start, Object** end) { |
| 672 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); | 686 for (Object** p = start; p < end; p++) MarkObjectByPointer(p); |
| 673 } | 687 } |
| 674 | 688 |
| 675 private: | 689 private: |
| 676 void MarkObjectByPointer(Object** p) { | 690 void MarkObjectByPointer(Object** p) { |
| 677 if (!(*p)->IsHeapObject()) return; | 691 if (!(*p)->IsHeapObject()) return; |
| 678 | 692 |
| 679 // Replace flat cons strings in place. | 693 // Replace flat cons strings in place. |
| 680 HeapObject* object = ShortCircuitConsString(p); | 694 HeapObject* object = ShortCircuitConsString(p); |
| 681 if (object->IsMarked()) return; | 695 if (object->IsMarked()) return; |
| 682 | 696 |
| 683 Map* map = object->map(); | 697 Map* map = object->map(); |
| 684 // Mark the object. | 698 // Mark the object. |
| 685 HEAP->mark_compact_collector()->SetMark(object); | 699 collector_->SetMark(object); |
| 686 | 700 |
| 687 // Mark the map pointer and body, and push them on the marking stack. | 701 // Mark the map pointer and body, and push them on the marking stack. |
| 688 HEAP->mark_compact_collector()->MarkObject(map); | 702 collector_->MarkObject(map); |
| 689 StaticMarkingVisitor::IterateBody(map, object); | 703 StaticMarkingVisitor::IterateBody(map, object); |
| 690 | 704 |
| 691 // Mark all the objects reachable from the map and body. May leave | 705 // Mark all the objects reachable from the map and body. May leave |
| 692 // overflowed objects in the heap. | 706 // overflowed objects in the heap. |
| 693 HEAP->mark_compact_collector()->EmptyMarkingStack(); | 707 collector_->EmptyMarkingStack(); |
| 694 } | 708 } |
| 709 |
| 710 MarkCompactCollector* collector_; |
| 695 }; | 711 }; |
| 696 | 712 |
| 697 | 713 |
| 698 // Helper class for pruning the symbol table. | 714 // Helper class for pruning the symbol table. |
| 699 class SymbolTableCleaner : public ObjectVisitor { | 715 class SymbolTableCleaner : public ObjectVisitor { |
| 700 public: | 716 public: |
| 701 SymbolTableCleaner() : pointers_removed_(0) { } | 717 SymbolTableCleaner() : pointers_removed_(0) { } |
| 702 | 718 |
| 703 virtual void VisitPointers(Object** start, Object** end) { | 719 virtual void VisitPointers(Object** start, Object** end) { |
| 704 // Visit all HeapObject pointers in [start, end). | 720 // Visit all HeapObject pointers in [start, end). |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 755 *HeapObject::RawField(map, Map::kInstanceDescriptorsOffset))); | 771 *HeapObject::RawField(map, Map::kInstanceDescriptorsOffset))); |
| 756 | 772 |
| 757 // Mark the Object* fields of the Map. | 773 // Mark the Object* fields of the Map. |
| 758 // Since the descriptor array has been marked already, it is fine | 774 // Since the descriptor array has been marked already, it is fine |
| 759 // that one of these fields contains a pointer to it. | 775 // that one of these fields contains a pointer to it. |
| 760 Object** start_slot = HeapObject::RawField(map, | 776 Object** start_slot = HeapObject::RawField(map, |
| 761 Map::kPointerFieldsBeginOffset); | 777 Map::kPointerFieldsBeginOffset); |
| 762 | 778 |
| 763 Object** end_slot = HeapObject::RawField(map, Map::kPointerFieldsEndOffset); | 779 Object** end_slot = HeapObject::RawField(map, Map::kPointerFieldsEndOffset); |
| 764 | 780 |
| 765 StaticMarkingVisitor::VisitPointers(start_slot, end_slot); | 781 StaticMarkingVisitor::VisitPointers(map->heap(), start_slot, end_slot); |
| 766 } | 782 } |
| 767 | 783 |
| 768 | 784 |
| 769 void MarkCompactCollector::MarkDescriptorArray( | 785 void MarkCompactCollector::MarkDescriptorArray( |
| 770 DescriptorArray* descriptors) { | 786 DescriptorArray* descriptors) { |
| 771 if (descriptors->IsMarked()) return; | 787 if (descriptors->IsMarked()) return; |
| 772 // Empty descriptor array is marked as a root before any maps are marked. | 788 // Empty descriptor array is marked as a root before any maps are marked. |
| 773 ASSERT(descriptors != HEAP->raw_unchecked_empty_descriptor_array()); | 789 ASSERT(descriptors != HEAP->raw_unchecked_empty_descriptor_array()); |
| 774 SetMark(descriptors); | 790 SetMark(descriptors); |
| 775 | 791 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 } | 870 } |
| 855 }; | 871 }; |
| 856 | 872 |
| 857 | 873 |
| 858 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { | 874 bool MarkCompactCollector::IsUnmarkedHeapObject(Object** p) { |
| 859 return (*p)->IsHeapObject() && !HeapObject::cast(*p)->IsMarked(); | 875 return (*p)->IsHeapObject() && !HeapObject::cast(*p)->IsMarked(); |
| 860 } | 876 } |
| 861 | 877 |
| 862 | 878 |
| 863 void MarkCompactCollector::MarkSymbolTable() { | 879 void MarkCompactCollector::MarkSymbolTable() { |
| 864 SymbolTable* symbol_table = HEAP->raw_unchecked_symbol_table(); | 880 SymbolTable* symbol_table = heap_->raw_unchecked_symbol_table(); |
| 865 // Mark the symbol table itself. | 881 // Mark the symbol table itself. |
| 866 SetMark(symbol_table); | 882 SetMark(symbol_table); |
| 867 // Explicitly mark the prefix. | 883 // Explicitly mark the prefix. |
| 868 MarkingVisitor marker; | 884 MarkingVisitor marker(heap_); |
| 869 symbol_table->IteratePrefix(&marker); | 885 symbol_table->IteratePrefix(&marker); |
| 870 ProcessMarkingStack(); | 886 ProcessMarkingStack(); |
| 871 } | 887 } |
| 872 | 888 |
| 873 | 889 |
| 874 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { | 890 void MarkCompactCollector::MarkRoots(RootMarkingVisitor* visitor) { |
| 875 // Mark the heap roots including global variables, stack variables, | 891 // Mark the heap roots including global variables, stack variables, |
| 876 // etc., and all objects reachable from them. | 892 // etc., and all objects reachable from them. |
| 877 HEAP->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); | 893 HEAP->IterateStrongRoots(visitor, VISIT_ONLY_STRONG); |
| 878 | 894 |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 923 | 939 |
| 924 | 940 |
| 925 // Mark all objects reachable from the objects on the marking stack. | 941 // Mark all objects reachable from the objects on the marking stack. |
| 926 // Before: the marking stack contains zero or more heap object pointers. | 942 // Before: the marking stack contains zero or more heap object pointers. |
| 927 // After: the marking stack is empty, and all objects reachable from the | 943 // After: the marking stack is empty, and all objects reachable from the |
| 928 // marking stack have been marked, or are overflowed in the heap. | 944 // marking stack have been marked, or are overflowed in the heap. |
| 929 void MarkCompactCollector::EmptyMarkingStack() { | 945 void MarkCompactCollector::EmptyMarkingStack() { |
| 930 while (!marking_stack_.is_empty()) { | 946 while (!marking_stack_.is_empty()) { |
| 931 HeapObject* object = marking_stack_.Pop(); | 947 HeapObject* object = marking_stack_.Pop(); |
| 932 ASSERT(object->IsHeapObject()); | 948 ASSERT(object->IsHeapObject()); |
| 933 ASSERT(HEAP->Contains(object)); | 949 ASSERT(heap_->Contains(object)); |
| 934 ASSERT(object->IsMarked()); | 950 ASSERT(object->IsMarked()); |
| 935 ASSERT(!object->IsOverflowed()); | 951 ASSERT(!object->IsOverflowed()); |
| 936 | 952 |
| 937 // Because the object is marked, we have to recover the original map | 953 // Because the object is marked, we have to recover the original map |
| 938 // pointer and use it to mark the object's body. | 954 // pointer and use it to mark the object's body. |
| 939 MapWord map_word = object->map_word(); | 955 MapWord map_word = object->map_word(); |
| 940 map_word.ClearMark(); | 956 map_word.ClearMark(); |
| 941 Map* map = map_word.ToMap(); | 957 Map* map = map_word.ToMap(); |
| 942 MarkObject(map); | 958 MarkObject(map); |
| 943 | 959 |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1012 | 1028 |
| 1013 | 1029 |
| 1014 void MarkCompactCollector::MarkLiveObjects() { | 1030 void MarkCompactCollector::MarkLiveObjects() { |
| 1015 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK); | 1031 GCTracer::Scope gc_scope(tracer_, GCTracer::Scope::MC_MARK); |
| 1016 #ifdef DEBUG | 1032 #ifdef DEBUG |
| 1017 ASSERT(state_ == PREPARE_GC); | 1033 ASSERT(state_ == PREPARE_GC); |
| 1018 state_ = MARK_LIVE_OBJECTS; | 1034 state_ = MARK_LIVE_OBJECTS; |
| 1019 #endif | 1035 #endif |
| 1020 // The to space contains live objects, the from space is used as a marking | 1036 // The to space contains live objects, the from space is used as a marking |
| 1021 // stack. | 1037 // stack. |
| 1022 marking_stack_.Initialize(HEAP->new_space()->FromSpaceLow(), | 1038 marking_stack_.Initialize(heap_->new_space()->FromSpaceLow(), |
| 1023 HEAP->new_space()->FromSpaceHigh()); | 1039 heap_->new_space()->FromSpaceHigh()); |
| 1024 | 1040 |
| 1025 ASSERT(!marking_stack_.overflowed()); | 1041 ASSERT(!marking_stack_.overflowed()); |
| 1026 | 1042 |
| 1027 PrepareForCodeFlushing(); | 1043 PrepareForCodeFlushing(); |
| 1028 | 1044 |
| 1029 RootMarkingVisitor root_visitor; | 1045 RootMarkingVisitor root_visitor(heap_); |
| 1030 MarkRoots(&root_visitor); | 1046 MarkRoots(&root_visitor); |
| 1031 | 1047 |
| 1032 // The objects reachable from the roots are marked, yet unreachable | 1048 // The objects reachable from the roots are marked, yet unreachable |
| 1033 // objects are unmarked. Mark objects reachable from object groups | 1049 // objects are unmarked. Mark objects reachable from object groups |
| 1034 // containing at least one marked object, and continue until no new | 1050 // containing at least one marked object, and continue until no new |
| 1035 // objects are reachable from the object groups. | 1051 // objects are reachable from the object groups. |
| 1036 ProcessObjectGroups(); | 1052 ProcessObjectGroups(); |
| 1037 | 1053 |
| 1038 // The objects reachable from the roots or object groups are marked, | 1054 // The objects reachable from the roots or object groups are marked, |
| 1039 // yet unreachable objects are unmarked. Mark objects reachable | 1055 // yet unreachable objects are unmarked. Mark objects reachable |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1430 heap->CopyBlock(dst, src, size); | 1446 heap->CopyBlock(dst, src, size); |
| 1431 } | 1447 } |
| 1432 | 1448 |
| 1433 Memory::Address_at(src) = dst; | 1449 Memory::Address_at(src) = dst; |
| 1434 } | 1450 } |
| 1435 | 1451 |
| 1436 | 1452 |
| 1437 class StaticPointersToNewGenUpdatingVisitor : public | 1453 class StaticPointersToNewGenUpdatingVisitor : public |
| 1438 StaticNewSpaceVisitor<StaticPointersToNewGenUpdatingVisitor> { | 1454 StaticNewSpaceVisitor<StaticPointersToNewGenUpdatingVisitor> { |
| 1439 public: | 1455 public: |
| 1440 static inline void VisitPointer(Object** p) { | 1456 static inline void VisitPointer(Heap* heap, Object** p) { |
| 1441 if (!(*p)->IsHeapObject()) return; | 1457 if (!(*p)->IsHeapObject()) return; |
| 1442 | 1458 |
| 1443 HeapObject* obj = HeapObject::cast(*p); | 1459 HeapObject* obj = HeapObject::cast(*p); |
| 1444 Address old_addr = obj->address(); | 1460 Address old_addr = obj->address(); |
| 1445 | 1461 |
| 1446 if (HEAP->new_space()->Contains(obj)) { | 1462 if (heap->new_space()->Contains(obj)) { |
| 1447 ASSERT(HEAP->InFromSpace(*p)); | 1463 ASSERT(heap->InFromSpace(*p)); |
| 1448 *p = HeapObject::FromAddress(Memory::Address_at(old_addr)); | 1464 *p = HeapObject::FromAddress(Memory::Address_at(old_addr)); |
| 1449 } | 1465 } |
| 1450 } | 1466 } |
| 1451 }; | 1467 }; |
| 1452 | 1468 |
| 1453 | 1469 |
| 1454 // Visitor for updating pointers from live objects in old spaces to new space. | 1470 // Visitor for updating pointers from live objects in old spaces to new space. |
| 1455 // It does not expect to encounter pointers to dead objects. | 1471 // It does not expect to encounter pointers to dead objects. |
| 1456 class PointersToNewGenUpdatingVisitor: public ObjectVisitor { | 1472 class PointersToNewGenUpdatingVisitor: public ObjectVisitor { |
| 1457 public: | 1473 public: |
| 1474 explicit PointersToNewGenUpdatingVisitor(Heap* heap) : heap_(heap) { } |
| 1475 |
| 1458 void VisitPointer(Object** p) { | 1476 void VisitPointer(Object** p) { |
| 1459 StaticPointersToNewGenUpdatingVisitor::VisitPointer(p); | 1477 StaticPointersToNewGenUpdatingVisitor::VisitPointer(heap_, p); |
| 1460 } | 1478 } |
| 1461 | 1479 |
| 1462 void VisitPointers(Object** start, Object** end) { | 1480 void VisitPointers(Object** start, Object** end) { |
| 1463 for (Object** p = start; p < end; p++) { | 1481 for (Object** p = start; p < end; p++) { |
| 1464 StaticPointersToNewGenUpdatingVisitor::VisitPointer(p); | 1482 StaticPointersToNewGenUpdatingVisitor::VisitPointer(heap_, p); |
| 1465 } | 1483 } |
| 1466 } | 1484 } |
| 1467 | 1485 |
| 1468 void VisitCodeTarget(RelocInfo* rinfo) { | 1486 void VisitCodeTarget(RelocInfo* rinfo) { |
| 1469 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); | 1487 ASSERT(RelocInfo::IsCodeTarget(rinfo->rmode())); |
| 1470 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); | 1488 Object* target = Code::GetCodeFromTargetAddress(rinfo->target_address()); |
| 1471 VisitPointer(&target); | 1489 VisitPointer(&target); |
| 1472 rinfo->set_target_address(Code::cast(target)->instruction_start()); | 1490 rinfo->set_target_address(Code::cast(target)->instruction_start()); |
| 1473 } | 1491 } |
| 1474 | 1492 |
| 1475 void VisitDebugTarget(RelocInfo* rinfo) { | 1493 void VisitDebugTarget(RelocInfo* rinfo) { |
| 1476 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && | 1494 ASSERT((RelocInfo::IsJSReturn(rinfo->rmode()) && |
| 1477 rinfo->IsPatchedReturnSequence()) || | 1495 rinfo->IsPatchedReturnSequence()) || |
| 1478 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 1496 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && |
| 1479 rinfo->IsPatchedDebugBreakSlotSequence())); | 1497 rinfo->IsPatchedDebugBreakSlotSequence())); |
| 1480 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); | 1498 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); |
| 1481 VisitPointer(&target); | 1499 VisitPointer(&target); |
| 1482 rinfo->set_call_address(Code::cast(target)->instruction_start()); | 1500 rinfo->set_call_address(Code::cast(target)->instruction_start()); |
| 1483 } | 1501 } |
| 1502 private: |
| 1503 Heap* heap_; |
| 1484 }; | 1504 }; |
| 1485 | 1505 |
| 1486 | 1506 |
| 1487 // Visitor for updating pointers from live objects in old spaces to new space. | 1507 // Visitor for updating pointers from live objects in old spaces to new space. |
| 1488 // It can encounter pointers to dead objects in new space when traversing map | 1508 // It can encounter pointers to dead objects in new space when traversing map |
| 1489 // space (see comment for MigrateObject). | 1509 // space (see comment for MigrateObject). |
| 1490 static void UpdatePointerToNewGen(HeapObject** p) { | 1510 static void UpdatePointerToNewGen(HeapObject** p) { |
| 1491 if (!(*p)->IsHeapObject()) return; | 1511 if (!(*p)->IsHeapObject()) return; |
| 1492 | 1512 |
| 1493 Address old_addr = (*p)->address(); | 1513 Address old_addr = (*p)->address(); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1590 current, | 1610 current, |
| 1591 size, | 1611 size, |
| 1592 false); | 1612 false); |
| 1593 } else { | 1613 } else { |
| 1594 size = object->Size(); | 1614 size = object->Size(); |
| 1595 Memory::Address_at(current) = NULL; | 1615 Memory::Address_at(current) = NULL; |
| 1596 } | 1616 } |
| 1597 } | 1617 } |
| 1598 | 1618 |
| 1599 // Second pass: find pointers to new space and update them. | 1619 // Second pass: find pointers to new space and update them. |
| 1600 PointersToNewGenUpdatingVisitor updating_visitor; | 1620 PointersToNewGenUpdatingVisitor updating_visitor(heap); |
| 1601 | 1621 |
| 1602 // Update pointers in to space. | 1622 // Update pointers in to space. |
| 1603 Address current = space->bottom(); | 1623 Address current = space->bottom(); |
| 1604 while (current < space->top()) { | 1624 while (current < space->top()) { |
| 1605 HeapObject* object = HeapObject::FromAddress(current); | 1625 HeapObject* object = HeapObject::FromAddress(current); |
| 1606 current += | 1626 current += |
| 1607 StaticPointersToNewGenUpdatingVisitor::IterateBody(object->map(), | 1627 StaticPointersToNewGenUpdatingVisitor::IterateBody(object->map(), |
| 1608 object); | 1628 object); |
| 1609 } | 1629 } |
| 1610 | 1630 |
| (...skipping 1021 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2632 } | 2652 } |
| 2633 | 2653 |
| 2634 | 2654 |
| 2635 void MarkCompactCollector::Initialize() { | 2655 void MarkCompactCollector::Initialize() { |
| 2636 StaticPointersToNewGenUpdatingVisitor::Initialize(); | 2656 StaticPointersToNewGenUpdatingVisitor::Initialize(); |
| 2637 StaticMarkingVisitor::Initialize(); | 2657 StaticMarkingVisitor::Initialize(); |
| 2638 } | 2658 } |
| 2639 | 2659 |
| 2640 | 2660 |
| 2641 } } // namespace v8::internal | 2661 } } // namespace v8::internal |
| OLD | NEW |