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

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: code review (svenpanne) 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
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();
Michael Starzinger 2013/04/10 10:54:16 Isn't there a sort call to the retained_object_inf
marja 2013/04/10 13:14:51 Yes! Thanks for pointing that out.
580
581 // During the iteration, some of the elements of object_groups are
582 // deleted. This is done by moving surviving elements at the front of the list
583 // and deleting from the end. This index tracks where the next surviving
584 // element should be moved.
585 int surviving_element_ix = 0;
Michael Starzinger 2013/04/10 10:54:16 nit: Can we spell out the "index" in these variabl
marja 2013/04/10 13:14:51 Done.
586 int info_ix = 0; // For iterating retained_object_infos_.
587 int surviving_info_ix = 0;
588
589 UniqueId current_group_id;
590 size_t current_group_start = 0;
582 bool any_group_was_visited = false; 591 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 592
587 Object*** objects = entry->objects_; 593 for (int i = 0; i <= object_groups_.length(); ++i) {
588 bool group_should_be_visited = false; 594 if (i == 0)
589 for (size_t j = 0; j < entry->length_; j++) { 595 current_group_id = object_groups_[i].id;
590 Object* object = *objects[j]; 596 if (i == object_groups_.length() ||
591 if (object->IsHeapObject()) { 597 current_group_id != object_groups_[i].id) {
592 if (!can_skip(isolate_->heap(), &object)) { 598 // Group detected: objects in indices [current_group_start, i[.
593 group_should_be_visited = true; 599 bool group_should_be_visited = false;
594 break; 600 for (int j = current_group_start; j < i; ++j) {
601 Object* object = *(object_groups_[j].object);
602 if (object->IsHeapObject()) {
603 if (!can_skip(isolate_->heap(), &object)) {
604 group_should_be_visited = true;
605 break;
606 }
595 } 607 }
596 } 608 }
597 } 609 if (!group_should_be_visited) {
Michael Starzinger 2013/04/10 10:54:16 nit: Can we add an empty newline in front of this
marja 2013/04/10 13:14:51 Done.
598 610 for (int j = current_group_start; j < i; ++j)
599 if (!group_should_be_visited) { 611 object_groups_[surviving_element_ix++] = object_groups_[j];
600 object_groups_[last++] = entry; 612 } else {
601 continue; 613 // An object in the group requires visiting, so iterate over all
602 } 614 // objects in the group.
603 615 for (int j = current_group_start; j < i; ++j) {
604 // An object in the group requires visiting, so iterate over all 616 Object* object = *(object_groups_[j].object);
605 // objects in the group. 617 if (object->IsHeapObject()) {
606 for (size_t j = 0; j < entry->length_; ++j) { 618 v->VisitPointer(&object);
607 Object* object = *objects[j]; 619 any_group_was_visited = true;
608 if (object->IsHeapObject()) { 620 }
609 v->VisitPointer(&object); 621 }
610 any_group_was_visited = true; 622 }
623 if (info_ix < retained_object_infos_.length() &&
Michael Starzinger 2013/04/10 10:54:16 Likewise for this if.
marja 2013/04/10 13:14:51 Done.
624 retained_object_infos_[info_ix].id ==
625 object_groups_[current_group_start].id) {
626 // This object group has an associated GroupRetainedObjectInfo.
627 if (!group_should_be_visited) {
628 retained_object_infos_[surviving_info_ix++] =
629 retained_object_infos_[info_ix];
630 } else if (retained_object_infos_[info_ix].info != NULL) {
631 retained_object_infos_[info_ix].info->Dispose();
632 retained_object_infos_[info_ix].info = NULL;
633 }
634 ++info_ix;
635 }
636 if (i < object_groups_.length()) {
637 current_group_id = object_groups_[i].id;
638 current_group_start = i;
611 } 639 }
612 } 640 }
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 } 641 }
619 object_groups_.Rewind(last); 642 object_groups_.Rewind(surviving_element_ix);
643 retained_object_infos_.Rewind(surviving_info_ix);
620 return any_group_was_visited; 644 return any_group_was_visited;
621 } 645 }
622 646
623 647
624 bool GlobalHandles::PostGarbageCollectionProcessing( 648 bool GlobalHandles::PostGarbageCollectionProcessing(
625 GarbageCollector collector, GCTracer* tracer) { 649 GarbageCollector collector, GCTracer* tracer) {
626 // Process weak global handle callbacks. This must be done after the 650 // Process weak global handle callbacks. This must be done after the
627 // GC is completely done, because the callbacks may invoke arbitrary 651 // GC is completely done, because the callbacks may invoke arbitrary
628 // API functions. 652 // API functions.
629 ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC); 653 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) { 841 v8::RetainedObjectInfo* info) {
818 #ifdef DEBUG 842 #ifdef DEBUG
819 for (size_t i = 0; i < length; ++i) { 843 for (size_t i = 0; i < length; ++i) {
820 ASSERT(!Node::FromLocation(handles[i])->is_independent()); 844 ASSERT(!Node::FromLocation(handles[i])->is_independent());
821 } 845 }
822 #endif 846 #endif
823 if (length == 0) { 847 if (length == 0) {
824 if (info != NULL) info->Dispose(); 848 if (info != NULL) info->Dispose();
825 return; 849 return;
826 } 850 }
827 object_groups_.Add(ObjectGroup::New(handles, length, info)); 851 for (size_t i = 0; i < length; ++i) {
852 object_groups_.Add(
853 ObjectGroupConnection(UniqueId((intptr_t)handles[0]), handles[i]));
Michael Starzinger 2013/04/10 10:54:16 nit: Use "static_cast<intptr_t>" instead of the C-
marja 2013/04/10 13:14:51 Done.
854 }
855 retained_object_infos_.Add(
856 GroupRetainedObjectInfo(UniqueId((intptr_t)handles[0]), info));
Michael Starzinger 2013/04/10 10:54:16 Likewise.
marja 2013/04/10 13:14:51 Done.
828 } 857 }
829 858
830 859
860 void GlobalHandles::SetObjectGroupId(Object** handle,
861 UniqueId id) {
862 object_groups_.Add(ObjectGroupConnection(id, handle));
863 }
864
865
866 void GlobalHandles::SetRetainedObjectInfo(UniqueId id,
867 RetainedObjectInfo* info) {
868 retained_object_infos_.Add(GroupRetainedObjectInfo(id, info));
869 }
870
871
831 void GlobalHandles::AddImplicitReferences(HeapObject** parent, 872 void GlobalHandles::AddImplicitReferences(HeapObject** parent,
832 Object*** children, 873 Object*** children,
833 size_t length) { 874 size_t length) {
834 #ifdef DEBUG 875 #ifdef DEBUG
835 ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent()); 876 ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent());
836 for (size_t i = 0; i < length; ++i) { 877 for (size_t i = 0; i < length; ++i) {
837 ASSERT(!Node::FromLocation(children[i])->is_independent()); 878 ASSERT(!Node::FromLocation(children[i])->is_independent());
838 } 879 }
839 #endif 880 #endif
840 if (length == 0) return; 881 if (length == 0) return;
841 implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length)); 882 implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length));
842 } 883 }
843 884
844 885
845 void GlobalHandles::RemoveObjectGroups() { 886 void GlobalHandles::RemoveObjectGroups() {
846 for (int i = 0; i < object_groups_.length(); i++) { 887 object_groups_.Clear();
847 object_groups_.at(i)->Dispose(); 888 for (int i = 0; i < retained_object_infos_.length(); ++i) {
889 if (retained_object_infos_[i].info != NULL)
890 retained_object_infos_[i].info->Dispose();
848 } 891 }
849 object_groups_.Clear(); 892 retained_object_infos_.Clear();
850 } 893 }
851 894
852 895
853 void GlobalHandles::RemoveImplicitRefGroups() { 896 void GlobalHandles::RemoveImplicitRefGroups() {
854 for (int i = 0; i < implicit_ref_groups_.length(); i++) { 897 for (int i = 0; i < implicit_ref_groups_.length(); i++) {
855 implicit_ref_groups_.at(i)->Dispose(); 898 implicit_ref_groups_.at(i)->Dispose();
856 } 899 }
857 implicit_ref_groups_.Clear(); 900 implicit_ref_groups_.Clear();
858 } 901 }
859 902
860 903
861 void GlobalHandles::TearDown() { 904 void GlobalHandles::TearDown() {
862 // TODO(1428): invoke weak callbacks. 905 // TODO(1428): invoke weak callbacks.
863 } 906 }
864 907
865 908
866 } } // namespace v8::internal 909 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698