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

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: fix 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() { 39 GroupRetainedObjectInfo::~GroupRetainedObjectInfo() {
40 if (info_ != NULL) info_->Dispose();
41 } 40 }
42 41
43 42
44 class GlobalHandles::Node { 43 class GlobalHandles::Node {
45 public: 44 public:
46 // State transition diagram: 45 // State transition diagram:
47 // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE } 46 // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE }
48 enum State { 47 enum State {
49 FREE = 0, 48 FREE = 0,
50 NORMAL, // Normal global handle. 49 NORMAL, // Normal global handle.
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after
571 if ((node->is_independent() || node->is_partially_dependent()) && 570 if ((node->is_independent() || node->is_partially_dependent()) &&
572 node->IsWeakRetainer()) { 571 node->IsWeakRetainer()) {
573 v->VisitPointer(node->location()); 572 v->VisitPointer(node->location());
574 } 573 }
575 } 574 }
576 } 575 }
577 576
578 577
579 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v, 578 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v,
580 WeakSlotCallbackWithHeap can_skip) { 579 WeakSlotCallbackWithHeap can_skip) {
581 int last = 0; 580 if (object_groups_.length() == 0)
581 return false;
582
583 object_groups_.Sort();
584
585 // During the iteration, some of the elements of object_groups are
586 // deleted. This is done by moving surviving elements at the front of the list
587 // and deleting from the end. This index tracks where the next surviving
588 // element should be moved.
589 int surviving_element_ix = 0;
590 int info_ix = 0; // For iterating retained_object_infos_.
591 int surviving_info_ix = 0;
592
593 void* current_group_id = NULL;
594 size_t current_group_start = 0;
582 bool any_group_was_visited = false; 595 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 596
587 Object*** objects = entry->objects_; 597 for (int i = 0; i <= object_groups_.length(); ++i) {
588 bool group_should_be_visited = false; 598 if (i == 0)
589 for (size_t j = 0; j < entry->length_; j++) { 599 current_group_id = object_groups_[i].id;
590 Object* object = *objects[j]; 600 if (i == object_groups_.length() ||
591 if (object->IsHeapObject()) { 601 current_group_id != object_groups_[i].id) {
592 if (!can_skip(isolate_->heap(), &object)) { 602 // Group detected: objects in indices [current_group_start, i[.
593 group_should_be_visited = true; 603 bool group_should_be_visited = false;
594 break; 604 for (int j = current_group_start; j < i; ++j) {
605 Object* object = *(object_groups_[j].object);
606 if (object->IsHeapObject()) {
607 if (!can_skip(isolate_->heap(), &object)) {
608 group_should_be_visited = true;
609 break;
610 }
595 } 611 }
596 } 612 }
597 } 613 if (!group_should_be_visited) {
598 614 for (int j = current_group_start; j < i; ++j)
599 if (!group_should_be_visited) { 615 object_groups_[surviving_element_ix++] = object_groups_[j];
600 object_groups_[last++] = entry; 616 } else {
601 continue; 617 // An object in the group requires visiting, so iterate over all
602 } 618 // objects in the group.
603 619 for (int j = current_group_start; j < i; ++j) {
604 // An object in the group requires visiting, so iterate over all 620 Object* object = *(object_groups_[j].object);
605 // objects in the group. 621 if (object->IsHeapObject()) {
606 for (size_t j = 0; j < entry->length_; ++j) { 622 v->VisitPointer(&object);
607 Object* object = *objects[j]; 623 any_group_was_visited = true;
608 if (object->IsHeapObject()) { 624 }
609 v->VisitPointer(&object); 625 }
610 any_group_was_visited = true; 626 }
627 if (info_ix < retained_object_infos_.length() &&
628 retained_object_infos_[info_ix].id ==
629 object_groups_[current_group_start].id) {
630 // This object group has an associated GroupRetainedObjectInfo.
631 if (!group_should_be_visited) {
632 retained_object_infos_[surviving_info_ix++] =
633 retained_object_infos_[info_ix];
634 } else if (retained_object_infos_[info_ix].info != NULL) {
635 retained_object_infos_[info_ix].info->Dispose();
636 retained_object_infos_[info_ix].info = NULL;
637 }
638 ++info_ix;
639 }
640 if (i < object_groups_.length()) {
641 current_group_id = object_groups_[i].id;
642 current_group_start = i;
611 } 643 }
612 } 644 }
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 } 645 }
619 object_groups_.Rewind(last); 646 object_groups_.Rewind(surviving_element_ix);
647 retained_object_infos_.Rewind(surviving_info_ix);
620 return any_group_was_visited; 648 return any_group_was_visited;
621 } 649 }
622 650
623 651
624 bool GlobalHandles::PostGarbageCollectionProcessing( 652 bool GlobalHandles::PostGarbageCollectionProcessing(
625 GarbageCollector collector, GCTracer* tracer) { 653 GarbageCollector collector, GCTracer* tracer) {
626 // Process weak global handle callbacks. This must be done after the 654 // Process weak global handle callbacks. This must be done after the
627 // GC is completely done, because the callbacks may invoke arbitrary 655 // GC is completely done, because the callbacks may invoke arbitrary
628 // API functions. 656 // API functions.
629 ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC); 657 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) { 845 v8::RetainedObjectInfo* info) {
818 #ifdef DEBUG 846 #ifdef DEBUG
819 for (size_t i = 0; i < length; ++i) { 847 for (size_t i = 0; i < length; ++i) {
820 ASSERT(!Node::FromLocation(handles[i])->is_independent()); 848 ASSERT(!Node::FromLocation(handles[i])->is_independent());
821 } 849 }
822 #endif 850 #endif
823 if (length == 0) { 851 if (length == 0) {
824 if (info != NULL) info->Dispose(); 852 if (info != NULL) info->Dispose();
825 return; 853 return;
826 } 854 }
827 object_groups_.Add(ObjectGroup::New(handles, length, info)); 855 for (size_t i = 0; i < length; ++i)
856 object_groups_.Add(ObjectGroupConnection(handles[0], handles[i]));
857 retained_object_infos_.Add(GroupRetainedObjectInfo(handles[0], info));
828 } 858 }
829 859
830 860
861 void GlobalHandles::SetObjectGroupId(Object** handle,
862 void* id) {
863 object_groups_.Add(ObjectGroupConnection(id, handle));
864 }
865
866
867 void GlobalHandles::SetRetainedObjectInfo(void* id,
868 RetainedObjectInfo* info) {
869 retained_object_infos_.Add(GroupRetainedObjectInfo(id, info));
870 }
871
872
831 void GlobalHandles::AddImplicitReferences(HeapObject** parent, 873 void GlobalHandles::AddImplicitReferences(HeapObject** parent,
832 Object*** children, 874 Object*** children,
833 size_t length) { 875 size_t length) {
834 #ifdef DEBUG 876 #ifdef DEBUG
835 ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent()); 877 ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent());
836 for (size_t i = 0; i < length; ++i) { 878 for (size_t i = 0; i < length; ++i) {
837 ASSERT(!Node::FromLocation(children[i])->is_independent()); 879 ASSERT(!Node::FromLocation(children[i])->is_independent());
838 } 880 }
839 #endif 881 #endif
840 if (length == 0) return; 882 if (length == 0) return;
841 implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length)); 883 implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length));
842 } 884 }
843 885
844 886
845 void GlobalHandles::RemoveObjectGroups() { 887 void GlobalHandles::RemoveObjectGroups() {
846 for (int i = 0; i < object_groups_.length(); i++) { 888 object_groups_.Clear();
847 object_groups_.at(i)->Dispose(); 889 for (int i = 0; i < retained_object_infos_.length(); ++i) {
890 if (retained_object_infos_[i].info != NULL)
891 retained_object_infos_[i].info->Dispose();
848 } 892 }
849 object_groups_.Clear(); 893 retained_object_infos_.Clear();
850 } 894 }
851 895
852 896
853 void GlobalHandles::RemoveImplicitRefGroups() { 897 void GlobalHandles::RemoveImplicitRefGroups() {
854 for (int i = 0; i < implicit_ref_groups_.length(); i++) { 898 for (int i = 0; i < implicit_ref_groups_.length(); i++) {
855 implicit_ref_groups_.at(i)->Dispose(); 899 implicit_ref_groups_.at(i)->Dispose();
856 } 900 }
857 implicit_ref_groups_.Clear(); 901 implicit_ref_groups_.Clear();
858 } 902 }
859 903
860 904
861 void GlobalHandles::TearDown() { 905 void GlobalHandles::TearDown() {
862 // TODO(1428): invoke weak callbacks. 906 // TODO(1428): invoke weak callbacks.
863 } 907 }
864 908
865 909
866 } } // namespace v8::internal 910 } } // namespace v8::internal
OLDNEW
« src/global-handles.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