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

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

Issue 14007008: New GC APIs, try 2. (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: . 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 14 matching lines...) Expand all
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
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 // v8::internal::List is inefficient even for small number of elements, if we
36 // don't assign any initial capacity.
37 #define OBJECT_GROUP_CONNECTIONS_CAPACITY 20
Michael Starzinger 2013/04/22 11:34:51 Make this a "static const int kObjectGroupConntect
marja 2013/04/22 13:49:07 Done.
38
35 namespace v8 { 39 namespace v8 {
36 namespace internal { 40 namespace internal {
37 41
38 42
39 ObjectGroup::~ObjectGroup() { 43 ObjectGroup::~ObjectGroup() {
40 if (info_ != NULL) info_->Dispose(); 44 if (info != NULL) info->Dispose();
45 delete[] objects;
41 } 46 }
42 47
43 48
49 ImplicitRefGroup::~ImplicitRefGroup() {
50 delete[] children;
51 }
52
53
44 class GlobalHandles::Node { 54 class GlobalHandles::Node {
45 public: 55 public:
46 // State transition diagram: 56 // State transition diagram:
47 // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE } 57 // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE }
48 enum State { 58 enum State {
49 FREE = 0, 59 FREE = 0,
50 NORMAL, // Normal global handle. 60 NORMAL, // Normal global handle.
51 WEAK, // Flagged as weak but not yet finalized. 61 WEAK, // Flagged as weak but not yet finalized.
52 PENDING, // Has been recognized as only reachable by weak handles. 62 PENDING, // Has been recognized as only reachable by weak handles.
53 NEAR_DEATH // Callback has informed the handle is near death. 63 NEAR_DEATH // Callback has informed the handle is near death.
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 DISALLOW_COPY_AND_ASSIGN(NodeIterator); 441 DISALLOW_COPY_AND_ASSIGN(NodeIterator);
432 }; 442 };
433 443
434 444
435 GlobalHandles::GlobalHandles(Isolate* isolate) 445 GlobalHandles::GlobalHandles(Isolate* isolate)
436 : isolate_(isolate), 446 : isolate_(isolate),
437 number_of_global_handles_(0), 447 number_of_global_handles_(0),
438 first_block_(NULL), 448 first_block_(NULL),
439 first_used_block_(NULL), 449 first_used_block_(NULL),
440 first_free_(NULL), 450 first_free_(NULL),
441 post_gc_processing_count_(0) {} 451 post_gc_processing_count_(0),
452 object_group_connections_(OBJECT_GROUP_CONNECTIONS_CAPACITY) {}
442 453
443 454
444 GlobalHandles::~GlobalHandles() { 455 GlobalHandles::~GlobalHandles() {
445 NodeBlock* block = first_block_; 456 NodeBlock* block = first_block_;
446 while (block != NULL) { 457 while (block != NULL) {
447 NodeBlock* tmp = block->next(); 458 NodeBlock* tmp = block->next();
448 delete block; 459 delete block;
449 block = tmp; 460 block = tmp;
450 } 461 }
451 first_block_ = NULL; 462 first_block_ = NULL;
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 if ((node->is_independent() || node->is_partially_dependent()) && 582 if ((node->is_independent() || node->is_partially_dependent()) &&
572 node->IsWeakRetainer()) { 583 node->IsWeakRetainer()) {
573 v->VisitPointer(node->location()); 584 v->VisitPointer(node->location());
574 } 585 }
575 } 586 }
576 } 587 }
577 588
578 589
579 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v, 590 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v,
580 WeakSlotCallbackWithHeap can_skip) { 591 WeakSlotCallbackWithHeap can_skip) {
592 ComputeObjectGroupsAndImplicitReferences();
581 int last = 0; 593 int last = 0;
582 bool any_group_was_visited = false; 594 bool any_group_was_visited = false;
583 for (int i = 0; i < object_groups_.length(); i++) { 595 for (int i = 0; i < object_groups_.length(); i++) {
584 ObjectGroup* entry = object_groups_.at(i); 596 ObjectGroup* entry = object_groups_.at(i);
585 ASSERT(entry != NULL); 597 ASSERT(entry != NULL);
586 598
587 Object*** objects = entry->objects_; 599 Object*** objects = entry->objects;
588 bool group_should_be_visited = false; 600 bool group_should_be_visited = false;
589 for (size_t j = 0; j < entry->length_; j++) { 601 for (size_t j = 0; j < entry->length; j++) {
590 Object* object = *objects[j]; 602 Object* object = *objects[j];
591 if (object->IsHeapObject()) { 603 if (object->IsHeapObject()) {
592 if (!can_skip(isolate_->heap(), &object)) { 604 if (!can_skip(isolate_->heap(), &object)) {
593 group_should_be_visited = true; 605 group_should_be_visited = true;
594 break; 606 break;
595 } 607 }
596 } 608 }
597 } 609 }
598 610
599 if (!group_should_be_visited) { 611 if (!group_should_be_visited) {
600 object_groups_[last++] = entry; 612 object_groups_[last++] = entry;
601 continue; 613 continue;
602 } 614 }
603 615
604 // An object in the group requires visiting, so iterate over all 616 // An object in the group requires visiting, so iterate over all
605 // objects in the group. 617 // objects in the group.
606 for (size_t j = 0; j < entry->length_; ++j) { 618 for (size_t j = 0; j < entry->length; ++j) {
607 Object* object = *objects[j]; 619 Object* object = *objects[j];
608 if (object->IsHeapObject()) { 620 if (object->IsHeapObject()) {
609 v->VisitPointer(&object); 621 v->VisitPointer(&object);
610 any_group_was_visited = true; 622 any_group_was_visited = true;
611 } 623 }
612 } 624 }
613 625
614 // Once the entire group has been iterated over, set the object 626 // Once the entire group has been iterated over, set the object
615 // group to NULL so it won't be processed again. 627 // group to NULL so it won't be processed again.
616 entry->Dispose(); 628 delete entry;
617 object_groups_.at(i) = NULL; 629 object_groups_.at(i) = NULL;
618 } 630 }
619 object_groups_.Rewind(last); 631 object_groups_.Rewind(last);
620 return any_group_was_visited; 632 return any_group_was_visited;
621 } 633 }
622 634
623 635
624 bool GlobalHandles::PostGarbageCollectionProcessing( 636 bool GlobalHandles::PostGarbageCollectionProcessing(
625 GarbageCollector collector, GCTracer* tracer) { 637 GarbageCollector collector, GCTracer* tracer) {
626 // Process weak global handle callbacks. This must be done after the 638 // Process weak global handle callbacks. This must be done after the
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
817 v8::RetainedObjectInfo* info) { 829 v8::RetainedObjectInfo* info) {
818 #ifdef DEBUG 830 #ifdef DEBUG
819 for (size_t i = 0; i < length; ++i) { 831 for (size_t i = 0; i < length; ++i) {
820 ASSERT(!Node::FromLocation(handles[i])->is_independent()); 832 ASSERT(!Node::FromLocation(handles[i])->is_independent());
821 } 833 }
822 #endif 834 #endif
823 if (length == 0) { 835 if (length == 0) {
824 if (info != NULL) info->Dispose(); 836 if (info != NULL) info->Dispose();
825 return; 837 return;
826 } 838 }
827 object_groups_.Add(ObjectGroup::New(handles, length, info)); 839 ObjectGroup* group = new ObjectGroup(length);
840 for (size_t i = 0; i < length; ++i)
841 group->objects[i] = handles[i];
842 group->info = info;
843 object_groups_.Add(group);
828 } 844 }
829 845
830 846
847 void GlobalHandles::SetObjectGroupId(Object** handle,
848 UniqueId id) {
849 object_group_connections_.Add(ObjectGroupConnection(id, handle));
850 }
851
852
853 void GlobalHandles::SetRetainedObjectInfo(UniqueId id,
854 RetainedObjectInfo* info) {
855 retainer_infos_.Add(ObjectGroupRetainerInfo(id, info));
856 }
857
858
831 void GlobalHandles::AddImplicitReferences(HeapObject** parent, 859 void GlobalHandles::AddImplicitReferences(HeapObject** parent,
832 Object*** children, 860 Object*** children,
833 size_t length) { 861 size_t length) {
834 #ifdef DEBUG 862 #ifdef DEBUG
835 ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent()); 863 ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent());
836 for (size_t i = 0; i < length; ++i) { 864 for (size_t i = 0; i < length; ++i) {
837 ASSERT(!Node::FromLocation(children[i])->is_independent()); 865 ASSERT(!Node::FromLocation(children[i])->is_independent());
838 } 866 }
839 #endif 867 #endif
840 if (length == 0) return; 868 if (length == 0) return;
841 implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length)); 869 ImplicitRefGroup* group = new ImplicitRefGroup(parent, length);
870 for (size_t i = 0; i < length; ++i)
871 group->children[i] = children[i];
872 implicit_ref_groups_.Add(group);
873 }
874
875
876 void GlobalHandles::AddImplicitReference(UniqueId id, Object** child) {
877 ASSERT(!Node::FromLocation(child)->is_independent());
878 implicit_ref_connections_.Add(ObjectGroupConnection(id, child));
842 } 879 }
843 880
844 881
845 void GlobalHandles::RemoveObjectGroups() { 882 void GlobalHandles::RemoveObjectGroups() {
846 for (int i = 0; i < object_groups_.length(); i++) { 883 for (int i = 0; i < object_groups_.length(); i++)
847 object_groups_.at(i)->Dispose(); 884 delete object_groups_.at(i);
848 }
849 object_groups_.Clear(); 885 object_groups_.Clear();
886 for (int i = 0; i < retainer_infos_.length(); ++i)
887 retainer_infos_[i].info->Dispose();
888 retainer_infos_.Clear();
889 object_group_connections_.Clear();
890 object_group_connections_.Initialize(OBJECT_GROUP_CONNECTIONS_CAPACITY);
850 } 891 }
851 892
852 893
853 void GlobalHandles::RemoveImplicitRefGroups() { 894 void GlobalHandles::RemoveImplicitRefGroups() {
854 for (int i = 0; i < implicit_ref_groups_.length(); i++) { 895 for (int i = 0; i < implicit_ref_groups_.length(); i++) {
855 implicit_ref_groups_.at(i)->Dispose(); 896 delete implicit_ref_groups_.at(i);
856 } 897 }
857 implicit_ref_groups_.Clear(); 898 implicit_ref_groups_.Clear();
899 implicit_ref_connections_.Clear();
858 } 900 }
859 901
860 902
861 void GlobalHandles::TearDown() { 903 void GlobalHandles::TearDown() {
862 // TODO(1428): invoke weak callbacks. 904 // TODO(1428): invoke weak callbacks.
863 } 905 }
864 906
907 void GlobalHandles::ComputeObjectGroupsAndImplicitReferences() {
908 if (object_group_connections_.length() == 0) {
909 for (int i = 0; i < retainer_infos_.length(); ++i)
910 retainer_infos_[i].info->Dispose();
911 retainer_infos_.Clear();
912 implicit_ref_connections_.Clear();
913 return;
914 }
915
916 object_group_connections_.Sort();
917 retainer_infos_.Sort();
918 implicit_ref_connections_.Sort();
919
920 int info_index = 0; // For iterating retainer_infos_.
921 UniqueId current_group_id(0);
922 int current_group_start = 0;
923
924 int current_implicit_refs_start = 0;
925 int current_implicit_refs_end = 0;
926 for (int i = 0; i <= object_group_connections_.length(); ++i) {
927 if (i == 0)
928 current_group_id = object_group_connections_[i].id;
929 if (i == object_group_connections_.length() ||
930 current_group_id != object_group_connections_[i].id) {
931 // Group detected: objects in indices [current_group_start, i[.
932
933 // Find out which implicit references are related to this group. (We want
934 // to ignore object groups which only have 1 object, but that object is
935 // needed as a representative object for the implicit refrerence group.)
936 while (current_implicit_refs_start < implicit_ref_connections_.length() &&
937 implicit_ref_connections_[current_implicit_refs_start].id <
938 current_group_id)
939 ++current_implicit_refs_start;
940 current_implicit_refs_end = current_implicit_refs_start;
941 while (current_implicit_refs_end < implicit_ref_connections_.length() &&
942 implicit_ref_connections_[current_implicit_refs_end].id ==
943 current_group_id)
944 ++current_implicit_refs_end;
945
946 if (current_implicit_refs_end > current_implicit_refs_start) {
947 // Find a representative object for the implicit references.
948 HeapObject** representative = NULL;
949 for (int j = current_group_start; j < i; ++j) {
950 Object** object = object_group_connections_[j].object;
951 if ((*object)->IsHeapObject()) {
952 representative = reinterpret_cast<HeapObject**>(object);
953 break;
954 }
955 }
956 if (representative) {
957 ImplicitRefGroup* group = new ImplicitRefGroup(
958 representative,
959 current_implicit_refs_end - current_implicit_refs_start);
960 for (int j = current_implicit_refs_start;
961 j < current_implicit_refs_end;
962 ++j) {
963 group->children[j - current_implicit_refs_start] =
964 implicit_ref_connections_[j].object;
965 }
966 implicit_ref_groups_.Add(group);
967 }
968 current_implicit_refs_start = current_implicit_refs_end;
969 }
970
971 // Find a RetainedObjectInfo for the group.
972 RetainedObjectInfo* info = NULL;
973 while (info_index < retainer_infos_.length() &&
974 retainer_infos_[info_index].id < current_group_id) {
975 retainer_infos_[info_index].info->Dispose();
976 ++info_index;
977 }
978 if (info_index < retainer_infos_.length() &&
979 retainer_infos_[info_index].id == current_group_id) {
980 // This object group has an associated ObjectGroupRetainerInfo.
981 info = retainer_infos_[info_index].info;
982 ++info_index;
983 }
984
985 // Ignore groups which only contain one object.
986 if (i > current_group_start + 1) {
987 ObjectGroup* group = new ObjectGroup(i - current_group_start);
988 for (int j = current_group_start; j < i; ++j) {
989 group->objects[j - current_group_start] =
990 object_group_connections_[j].object;
991 }
992 group->info = info;
993 object_groups_.Add(group);
994 } else if (info) {
995 info->Dispose();
996 }
997
998 if (i < object_group_connections_.length()) {
999 current_group_id = object_group_connections_[i].id;
1000 current_group_start = i;
1001 }
1002 }
1003 }
1004 object_group_connections_.Clear();
1005 object_group_connections_.Initialize(OBJECT_GROUP_CONNECTIONS_CAPACITY);
1006 retainer_infos_.Clear();
1007 implicit_ref_connections_.Clear();
1008 }
1009
865 1010
866 } } // namespace v8::internal 1011 } } // namespace v8::internal
OLDNEW
« include/v8.h ('K') | « 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