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

Side by Side Diff: src/global-handles.cc

Issue 13786002: [WIP] New GC related APIs. (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: use old testing machinery Created 7 years, 8 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
« no previous file with comments | « src/global-handles.h ('k') | src/heap-snapshot-generator.cc » ('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 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 18 matching lines...) Expand all
29 29
30 #include "api.h" 30 #include "api.h"
31 #include "global-handles.h" 31 #include "global-handles.h"
32 32
33 #include "vm-state-inl.h" 33 #include "vm-state-inl.h"
34 34
35 namespace v8 { 35 namespace v8 {
36 namespace internal { 36 namespace internal {
37 37
38 38
39 ObjectGroup::~ObjectGroup() {
40 if (info_ != NULL) info_->Dispose();
41 }
42
43
44 class GlobalHandles::Node { 39 class GlobalHandles::Node {
45 public: 40 public:
46 // State transition diagram: 41 // State transition diagram:
47 // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE } 42 // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE }
48 enum State { 43 enum State {
49 FREE = 0, 44 FREE = 0,
50 NORMAL, // Normal global handle. 45 NORMAL, // Normal global handle.
51 WEAK, // Flagged as weak but not yet finalized. 46 WEAK, // Flagged as weak but not yet finalized.
52 PENDING, // Has been recognized as only reachable by weak handles. 47 PENDING, // Has been recognized as only reachable by weak handles.
53 NEAR_DEATH // Callback has informed the handle is near death. 48 NEAR_DEATH // Callback has informed the handle is near death.
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 if ((node->is_independent() || node->is_partially_dependent()) && 566 if ((node->is_independent() || node->is_partially_dependent()) &&
572 node->IsWeakRetainer()) { 567 node->IsWeakRetainer()) {
573 v->VisitPointer(node->location()); 568 v->VisitPointer(node->location());
574 } 569 }
575 } 570 }
576 } 571 }
577 572
578 573
579 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v, 574 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v,
580 WeakSlotCallbackWithHeap can_skip) { 575 WeakSlotCallbackWithHeap can_skip) {
581 int last = 0; 576 if (object_groups_.length() == 0)
577 return false;
578
579 object_groups_.Sort();
580 retainer_infos_.Sort();
581
582 // During the iteration, some of the elements of object_groups are
583 // deleted. This is done by moving surviving elements at the front of the list
584 // and deleting from the end. This index tracks where the next surviving
585 // element should be moved.
586 int surviving_element_index = 0;
587 int info_index = 0; // For iterating retainer_infos_.
588 int surviving_info_index = 0;
589
590 UniqueId current_group_id(0);
591 size_t current_group_start = 0;
582 bool any_group_was_visited = false; 592 bool any_group_was_visited = false;
583 for (int i = 0; i < object_groups_.length(); i++) {
584 ObjectGroup* entry = object_groups_.at(i);
585 ASSERT(entry != NULL);
586 593
587 Object*** objects = entry->objects_; 594 for (int i = 0; i <= object_groups_.length(); ++i) {
588 bool group_should_be_visited = false; 595 if (i == 0)
589 for (size_t j = 0; j < entry->length_; j++) { 596 current_group_id = object_groups_[i].id;
590 Object* object = *objects[j]; 597 if (i == object_groups_.length() ||
591 if (object->IsHeapObject()) { 598 current_group_id != object_groups_[i].id) {
592 if (!can_skip(isolate_->heap(), &object)) { 599 // Group detected: objects in indices [current_group_start, i[.
593 group_should_be_visited = true; 600 bool group_should_be_visited = false;
594 break; 601 for (int j = current_group_start; j < i; ++j) {
602 Object* object = *(object_groups_[j].object);
603 if (object->IsHeapObject()) {
604 if (!can_skip(isolate_->heap(), &object)) {
605 group_should_be_visited = true;
606 break;
607 }
595 } 608 }
596 } 609 }
597 }
598 610
599 if (!group_should_be_visited) { 611 if (!group_should_be_visited) {
600 object_groups_[last++] = entry; 612 for (int j = current_group_start; j < i; ++j)
601 continue; 613 object_groups_[surviving_element_index++] = object_groups_[j];
602 } 614 } else {
615 // An object in the group requires visiting, so iterate over all
616 // objects in the group.
617 for (int j = current_group_start; j < i; ++j) {
618 Object* object = *(object_groups_[j].object);
619 if (object->IsHeapObject()) {
620 v->VisitPointer(&object);
621 any_group_was_visited = true;
622 }
623 }
624 }
603 625
604 // An object in the group requires visiting, so iterate over all 626 if (info_index < retainer_infos_.length() &&
605 // objects in the group. 627 retainer_infos_[info_index].id ==
606 for (size_t j = 0; j < entry->length_; ++j) { 628 object_groups_[current_group_start].id) {
607 Object* object = *objects[j]; 629 // This object group has an associated ObjectGroupRetainerInfo.
608 if (object->IsHeapObject()) { 630 if (!group_should_be_visited) {
609 v->VisitPointer(&object); 631 retainer_infos_[surviving_info_index++] =
610 any_group_was_visited = true; 632 retainer_infos_[info_index];
633 } else if (retainer_infos_[info_index].info != NULL) {
634 retainer_infos_[info_index].info->Dispose();
635 retainer_infos_[info_index].info = NULL;
636 }
637 ++info_index;
638 }
639 if (i < object_groups_.length()) {
640 current_group_id = object_groups_[i].id;
641 current_group_start = i;
611 } 642 }
612 } 643 }
613
614 // Once the entire group has been iterated over, set the object
615 // group to NULL so it won't be processed again.
616 entry->Dispose();
617 object_groups_.at(i) = NULL;
618 } 644 }
619 object_groups_.Rewind(last); 645 object_groups_.Rewind(surviving_element_index);
646 retainer_infos_.Rewind(surviving_info_index);
620 return any_group_was_visited; 647 return any_group_was_visited;
621 } 648 }
622 649
623 650
624 bool GlobalHandles::PostGarbageCollectionProcessing( 651 bool GlobalHandles::PostGarbageCollectionProcessing(
625 GarbageCollector collector, GCTracer* tracer) { 652 GarbageCollector collector, GCTracer* tracer) {
626 // Process weak global handle callbacks. This must be done after the 653 // Process weak global handle callbacks. This must be done after the
627 // GC is completely done, because the callbacks may invoke arbitrary 654 // GC is completely done, because the callbacks may invoke arbitrary
628 // API functions. 655 // API functions.
629 ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC); 656 ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC);
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 v8::RetainedObjectInfo* info) { 844 v8::RetainedObjectInfo* info) {
818 #ifdef DEBUG 845 #ifdef DEBUG
819 for (size_t i = 0; i < length; ++i) { 846 for (size_t i = 0; i < length; ++i) {
820 ASSERT(!Node::FromLocation(handles[i])->is_independent()); 847 ASSERT(!Node::FromLocation(handles[i])->is_independent());
821 } 848 }
822 #endif 849 #endif
823 if (length == 0) { 850 if (length == 0) {
824 if (info != NULL) info->Dispose(); 851 if (info != NULL) info->Dispose();
825 return; 852 return;
826 } 853 }
827 object_groups_.Add(ObjectGroup::New(handles, length, info)); 854 for (size_t i = 0; i < length; ++i) {
855 object_groups_.Add(ObjectGroupConnection(
856 UniqueId(reinterpret_cast<intptr_t>(handles[0])), handles[i]));
857 }
858 retainer_infos_.Add(ObjectGroupRetainerInfo(
859 UniqueId(reinterpret_cast<intptr_t>(handles[0])), info));
860 }
861
862 void GlobalHandles::SetObjectGroupId(Object** handle,
863 UniqueId id) {
864 object_groups_.Add(ObjectGroupConnection(id, handle));
828 } 865 }
829 866
830 867
868 void GlobalHandles::SetRetainedObjectInfo(UniqueId id,
869 RetainedObjectInfo* info) {
870 retainer_infos_.Add(ObjectGroupRetainerInfo(id, info));
871 }
872
873
831 void GlobalHandles::AddImplicitReferences(HeapObject** parent, 874 void GlobalHandles::AddImplicitReferences(HeapObject** parent,
832 Object*** children, 875 Object*** children,
833 size_t length) { 876 size_t length) {
834 #ifdef DEBUG 877 #ifdef DEBUG
835 ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent()); 878 ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent());
836 for (size_t i = 0; i < length; ++i) { 879 for (size_t i = 0; i < length; ++i) {
837 ASSERT(!Node::FromLocation(children[i])->is_independent()); 880 ASSERT(!Node::FromLocation(children[i])->is_independent());
838 } 881 }
839 #endif 882 #endif
840 if (length == 0) return; 883 if (length == 0) return;
841 implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length)); 884 implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length));
842 } 885 }
843 886
844 887
845 void GlobalHandles::RemoveObjectGroups() { 888 void GlobalHandles::RemoveObjectGroups() {
846 for (int i = 0; i < object_groups_.length(); i++) { 889 object_groups_.Clear();
847 object_groups_.at(i)->Dispose(); 890 for (int i = 0; i < retainer_infos_.length(); ++i) {
891 if (retainer_infos_[i].info != NULL)
892 retainer_infos_[i].info->Dispose();
848 } 893 }
849 object_groups_.Clear(); 894 retainer_infos_.Clear();
850 } 895 }
851 896
852 897
853 void GlobalHandles::RemoveImplicitRefGroups() { 898 void GlobalHandles::RemoveImplicitRefGroups() {
854 for (int i = 0; i < implicit_ref_groups_.length(); i++) { 899 for (int i = 0; i < implicit_ref_groups_.length(); i++) {
855 implicit_ref_groups_.at(i)->Dispose(); 900 implicit_ref_groups_.at(i)->Dispose();
856 } 901 }
857 implicit_ref_groups_.Clear(); 902 implicit_ref_groups_.Clear();
858 } 903 }
859 904
860 905
861 void GlobalHandles::TearDown() { 906 void GlobalHandles::TearDown() {
862 // TODO(1428): invoke weak callbacks. 907 // TODO(1428): invoke weak callbacks.
863 } 908 }
864 909
865 910
866 } } // namespace v8::internal 911 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/global-handles.h ('k') | src/heap-snapshot-generator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698