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

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

Powered by Google App Engine
This is Rietveld 408576698