Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(494)

Side by Side Diff: runtime/vm/scavenger.cc

Issue 18826007: Reland r24563 and r24564 with fixes cumbersome API leading to leaks. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/scavenger.h ('k') | runtime/vm/vm_sources.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <algorithm> 7 #include <algorithm>
8 #include <map> 8 #include <map>
9 #include <utility> 9 #include <utility>
10 10
11 #include "vm/dart.h" 11 #include "vm/dart.h"
12 #include "vm/dart_api_state.h" 12 #include "vm/dart_api_state.h"
13 #include "vm/isolate.h" 13 #include "vm/isolate.h"
14 #include "vm/object.h" 14 #include "vm/object.h"
15 #include "vm/stack_frame.h" 15 #include "vm/stack_frame.h"
16 #include "vm/store_buffer.h" 16 #include "vm/store_buffer.h"
17 #include "vm/verifier.h" 17 #include "vm/verifier.h"
18 #include "vm/visitor.h" 18 #include "vm/visitor.h"
19 #include "vm/weak_table.h"
19 20
20 namespace dart { 21 namespace dart {
21 22
22 // Scavenger uses RawObject::kMarkBit to distinguish forwaded and non-forwarded 23 // Scavenger uses RawObject::kMarkBit to distinguish forwaded and non-forwarded
23 // objects. The kMarkBit does not intersect with the target address because of 24 // objects. The kMarkBit does not intersect with the target address because of
24 // object alignment. 25 // object alignment.
25 enum { 26 enum {
26 kForwardingMask = 1 << RawObject::kMarkBit, 27 kForwardingMask = 1 << RawObject::kMarkBit,
27 kNotForwarded = 0, 28 kNotForwarded = 0,
28 kForwarded = kForwardingMask, 29 kForwarded = kForwardingMask,
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 // Key is white. Delay the weak property. 550 // Key is white. Delay the weak property.
550 visitor->DelayWeakProperty(raw_weak); 551 visitor->DelayWeakProperty(raw_weak);
551 return raw_weak->Size(); 552 return raw_weak->Size();
552 } 553 }
553 } 554 }
554 // Key is gray or black. Make the weak property black. 555 // Key is gray or black. Make the weak property black.
555 return raw_weak->VisitPointers(visitor); 556 return raw_weak->VisitPointers(visitor);
556 } 557 }
557 558
558 559
559 void Scavenger::ProcessPeerReferents() { 560 void Scavenger::ProcessWeakTables() {
560 PeerTable prev; 561 for (int sel = 0;
561 std::swap(prev, peer_table_); 562 sel < Heap::kNumWeakSelectors;
562 for (PeerTable::iterator it = prev.begin(); it != prev.end(); ++it) { 563 sel++) {
563 RawObject* raw_obj = it->first; 564 WeakTable* table = heap_->GetWeakTable(
564 ASSERT(raw_obj->IsHeapObject()); 565 Heap::kNew, static_cast<Heap::WeakSelector>(sel));
565 uword raw_addr = RawObject::ToAddr(raw_obj); 566 heap_->SetWeakTable(Heap::kNew,
566 uword header = *reinterpret_cast<uword*>(raw_addr); 567 static_cast<Heap::WeakSelector>(sel),
567 if (IsForwarding(header)) { 568 WeakTable::NewFrom(table));
568 // The object has survived. Preserve its record. 569 intptr_t size = table->size();
569 uword new_addr = ForwardedAddr(header); 570 for (intptr_t i = 0; i < size; i++) {
570 raw_obj = RawObject::FromAddr(new_addr); 571 if (table->IsValidEntryAt(i)) {
571 heap_->SetPeer(raw_obj, it->second); 572 RawObject* raw_obj = table->ObjectAt(i);
573 ASSERT(raw_obj->IsHeapObject());
574 uword raw_addr = RawObject::ToAddr(raw_obj);
575 uword header = *reinterpret_cast<uword*>(raw_addr);
576 if (IsForwarding(header)) {
577 // The object has survived. Preserve its record.
578 uword new_addr = ForwardedAddr(header);
579 raw_obj = RawObject::FromAddr(new_addr);
580 heap_->SetWeakEntry(raw_obj,
581 static_cast<Heap::WeakSelector>(sel),
582 table->ValueAt(i));
583 }
584 }
572 } 585 }
586 // Remove the old table as it has been replaced with the newly allocated
587 // table above.
588 delete table;
573 } 589 }
574 } 590 }
575 591
576 592
577 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const { 593 void Scavenger::VisitObjectPointers(ObjectPointerVisitor* visitor) const {
578 uword cur = FirstObjectStart(); 594 uword cur = FirstObjectStart();
579 while (cur < top_) { 595 while (cur < top_) {
580 RawObject* raw_obj = RawObject::FromAddr(cur); 596 RawObject* raw_obj = RawObject::FromAddr(cur);
581 cur += raw_obj->VisitPointers(visitor); 597 cur += raw_obj->VisitPointers(visitor);
582 } 598 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 ScavengerVisitor visitor(isolate, this); 634 ScavengerVisitor visitor(isolate, this);
619 Prologue(isolate, invoke_api_callbacks); 635 Prologue(isolate, invoke_api_callbacks);
620 IterateRoots(isolate, &visitor, !invoke_api_callbacks); 636 IterateRoots(isolate, &visitor, !invoke_api_callbacks);
621 int64_t start = OS::GetCurrentTimeMicros(); 637 int64_t start = OS::GetCurrentTimeMicros();
622 ProcessToSpace(&visitor); 638 ProcessToSpace(&visitor);
623 int64_t middle = OS::GetCurrentTimeMicros(); 639 int64_t middle = OS::GetCurrentTimeMicros();
624 IterateWeakReferences(isolate, &visitor); 640 IterateWeakReferences(isolate, &visitor);
625 ScavengerWeakVisitor weak_visitor(this); 641 ScavengerWeakVisitor weak_visitor(this);
626 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks); 642 IterateWeakRoots(isolate, &weak_visitor, invoke_api_callbacks);
627 visitor.Finalize(); 643 visitor.Finalize();
628 ProcessPeerReferents(); 644 ProcessWeakTables();
629 int64_t end = OS::GetCurrentTimeMicros(); 645 int64_t end = OS::GetCurrentTimeMicros();
630 heap_->RecordTime(kProcessToSpace, middle - start); 646 heap_->RecordTime(kProcessToSpace, middle - start);
631 heap_->RecordTime(kIterateWeaks, end - middle); 647 heap_->RecordTime(kIterateWeaks, end - middle);
632 Epilogue(isolate, invoke_api_callbacks); 648 Epilogue(isolate, invoke_api_callbacks);
633 649
634 if (FLAG_verify_after_gc) { 650 if (FLAG_verify_after_gc) {
635 OS::PrintErr("Verifying after Scavenge..."); 651 OS::PrintErr("Verifying after Scavenge...");
636 heap_->Verify(); 652 heap_->Verify();
637 OS::PrintErr(" done.\n"); 653 OS::PrintErr(" done.\n");
638 } 654 }
639 655
640 // Done scavenging. Reset the marker. 656 // Done scavenging. Reset the marker.
641 ASSERT(scavenging_); 657 ASSERT(scavenging_);
642 scavenging_ = false; 658 scavenging_ = false;
643 } 659 }
644 660
645 661
646 void Scavenger::WriteProtect(bool read_only) { 662 void Scavenger::WriteProtect(bool read_only) {
647 space_->Protect( 663 space_->Protect(
648 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite); 664 read_only ? VirtualMemory::kReadOnly : VirtualMemory::kReadWrite);
649 } 665 }
650 666
651 667
652 void Scavenger::SetPeer(RawObject* raw_obj, void* peer) {
653 if (peer == NULL) {
654 peer_table_.erase(raw_obj);
655 } else {
656 peer_table_[raw_obj] = peer;
657 }
658 }
659
660
661 void* Scavenger::GetPeer(RawObject* raw_obj) {
662 PeerTable::iterator it = peer_table_.find(raw_obj);
663 return (it == peer_table_.end()) ? NULL : it->second;
664 }
665
666
667 int64_t Scavenger::PeerCount() const {
668 return static_cast<int64_t>(peer_table_.size());
669 }
670
671 } // namespace dart 668 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/scavenger.h ('k') | runtime/vm/vm_sources.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698