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

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: 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 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 } 41 }
42 42
43 43
44 GroupRetainedObjectInfo::~GroupRetainedObjectInfo() {
45 if (info != NULL)
46 info->Dispose();
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_groups_(new List<ObjectGroupConnection>()) {}
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;
459 delete object_groups_;
452 } 460 }
453 461
454 462
455 Handle<Object> GlobalHandles::Create(Object* value) { 463 Handle<Object> GlobalHandles::Create(Object* value) {
456 isolate_->counters()->global_handles()->Increment(); 464 isolate_->counters()->global_handles()->Increment();
457 number_of_global_handles_++; 465 number_of_global_handles_++;
458 if (first_free_ == NULL) { 466 if (first_free_ == NULL) {
459 first_block_ = new NodeBlock(first_block_); 467 first_block_ = new NodeBlock(first_block_);
460 first_block_->PutNodesOnFreeList(&first_free_); 468 first_block_->PutNodesOnFreeList(&first_free_);
461 } 469 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 for (int i = 0; i < new_space_nodes_.length(); ++i) { 576 for (int i = 0; i < new_space_nodes_.length(); ++i) {
569 Node* node = new_space_nodes_[i]; 577 Node* node = new_space_nodes_[i];
570 ASSERT(node->is_in_new_space_list()); 578 ASSERT(node->is_in_new_space_list());
571 if ((node->is_independent() || node->is_partially_dependent()) && 579 if ((node->is_independent() || node->is_partially_dependent()) &&
572 node->IsWeakRetainer()) { 580 node->IsWeakRetainer()) {
573 v->VisitPointer(node->location()); 581 v->VisitPointer(node->location());
574 } 582 }
575 } 583 }
576 } 584 }
577 585
578
579 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v, 586 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v,
580 WeakSlotCallbackWithHeap can_skip) { 587 WeakSlotCallbackWithHeap can_skip) {
581 int last = 0; 588 if (object_groups_->length() == 0)
589 return false;
590
591 object_groups_->Sort();
592 // Stores information about unvisited object groups for later use.
593 List<ObjectGroupConnection>* new_object_groups =
594 new List<ObjectGroupConnection>();
595
596 void* current_group_id = NULL;
597 size_t current_group_start = 0;
582 bool any_group_was_visited = false; 598 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 599
587 Object*** objects = entry->objects_; 600 for (int i = 0; i <= object_groups_->length(); ++i) {
588 bool group_should_be_visited = false; 601 if (i == 0)
589 for (size_t j = 0; j < entry->length_; j++) { 602 current_group_id = object_groups_->at(i).id;
590 Object* object = *objects[j]; 603 if (i == object_groups_->length() ||
591 if (object->IsHeapObject()) { 604 current_group_id != object_groups_->at(i).id) {
592 if (!can_skip(isolate_->heap(), &object)) { 605 // Group detected: objects in indices [current_group_start, i[.
593 group_should_be_visited = true; 606 bool group_should_be_visited = false;
594 break; 607 for (int j = current_group_start; j < i; ++j) {
608 Object* object = *(object_groups_->at(j).object);
609 if (object->IsHeapObject()) {
610 if (!can_skip(isolate_->heap(), &object)) {
611 group_should_be_visited = true;
612 break;
613 }
595 } 614 }
596 } 615 }
597 } 616 if (!group_should_be_visited) {
598 617 for (int j = current_group_start; j < i; ++j)
599 if (!group_should_be_visited) { 618 new_object_groups->Add(object_groups_->at(j));
600 object_groups_[last++] = entry; 619 } else {
601 continue; 620 // An object in the group requires visiting, so iterate over all
602 } 621 // objects in the group.
603 622 for (int j = current_group_start; j < i; ++j) {
604 // An object in the group requires visiting, so iterate over all 623 Object* object = *(object_groups_->at(j).object);
605 // objects in the group. 624 if (object->IsHeapObject()) {
606 for (size_t j = 0; j < entry->length_; ++j) { 625 v->VisitPointer(&object);
607 Object* object = *objects[j]; 626 any_group_was_visited = true;
608 if (object->IsHeapObject()) { 627 }
609 v->VisitPointer(&object); 628 }
610 any_group_was_visited = true; 629 }
630 if (i < object_groups_->length()) {
631 current_group_id = object_groups_->at(i).id;
632 current_group_start = i;
611 } 633 }
612 } 634 }
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 } 635 }
619 object_groups_.Rewind(last); 636 delete object_groups_;
637 object_groups_ = new_object_groups;
620 return any_group_was_visited; 638 return any_group_was_visited;
621 } 639 }
622 640
623 641
624 bool GlobalHandles::PostGarbageCollectionProcessing( 642 bool GlobalHandles::PostGarbageCollectionProcessing(
625 GarbageCollector collector, GCTracer* tracer) { 643 GarbageCollector collector, GCTracer* tracer) {
626 // Process weak global handle callbacks. This must be done after the 644 // Process weak global handle callbacks. This must be done after the
627 // GC is completely done, because the callbacks may invoke arbitrary 645 // GC is completely done, because the callbacks may invoke arbitrary
628 // API functions. 646 // API functions.
629 ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC); 647 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) { 835 v8::RetainedObjectInfo* info) {
818 #ifdef DEBUG 836 #ifdef DEBUG
819 for (size_t i = 0; i < length; ++i) { 837 for (size_t i = 0; i < length; ++i) {
820 ASSERT(!Node::FromLocation(handles[i])->is_independent()); 838 ASSERT(!Node::FromLocation(handles[i])->is_independent());
821 } 839 }
822 #endif 840 #endif
823 if (length == 0) { 841 if (length == 0) {
824 if (info != NULL) info->Dispose(); 842 if (info != NULL) info->Dispose();
825 return; 843 return;
826 } 844 }
827 object_groups_.Add(ObjectGroup::New(handles, length, info)); 845 for (size_t i = 0; i < length; ++i)
846 object_groups_->Add(ObjectGroupConnection(handles[0], handles[i]));
847 retained_object_infos_.Add(GroupRetainedObjectInfo(handles[0], info));
828 } 848 }
829 849
830 850
851 void GlobalHandles::SetObjectGroupId(Object** handle,
852 void* id) {
853 object_groups_->Add(ObjectGroupConnection(id, handle));
854 }
855
856
857 void GlobalHandles::SetRetainedObjectInfo(void* id,
858 RetainedObjectInfo* info) {
859 retained_object_infos_.Add(GroupRetainedObjectInfo(id, info));
860 }
861
862
831 void GlobalHandles::AddImplicitReferences(HeapObject** parent, 863 void GlobalHandles::AddImplicitReferences(HeapObject** parent,
832 Object*** children, 864 Object*** children,
833 size_t length) { 865 size_t length) {
834 #ifdef DEBUG 866 #ifdef DEBUG
835 ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent()); 867 ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent());
836 for (size_t i = 0; i < length; ++i) { 868 for (size_t i = 0; i < length; ++i) {
837 ASSERT(!Node::FromLocation(children[i])->is_independent()); 869 ASSERT(!Node::FromLocation(children[i])->is_independent());
838 } 870 }
839 #endif 871 #endif
840 if (length == 0) return; 872 if (length == 0) return;
841 implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length)); 873 implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length));
842 } 874 }
843 875
876 List<ObjectGroup*>* GlobalHandles::object_groups() {
877 List<ObjectGroup*>* to_return = new List<ObjectGroup*>();
878
879 object_groups_->Sort();
880 retained_object_infos_.Sort();
881 int retained_object_infos_ix = 0;
882
883 void* current_group_id = NULL;
884 size_t current_group_start = 0;
885
886 for (int i = 0; i <= object_groups_->length(); ++i) {
887 if (i == 0)
888 current_group_id = object_groups_->at(i).id;
889 if (i == object_groups_->length() ||
890 current_group_id != object_groups_->at(i).id) {
891 // Group detected: objects in indices [current_group_start, i[.
892 ObjectGroup* group = new ObjectGroup();
893 if (retained_object_infos_ix < retained_object_infos_.length() &&
894 retained_object_infos_[retained_object_infos_ix].id ==
895 object_groups_->at(current_group_start).id) {
896 // Transfer the ownership of info.
897 group->info = retained_object_infos_[retained_object_infos_ix].info;
898 retained_object_infos_[retained_object_infos_ix].info = NULL;
899 ++retained_object_infos_ix;
900 }
901 for (int j = current_group_start; j < i; ++j)
902 group->objects.Add(object_groups_->at(j).object);
903 to_return->Add(group);
904 }
905 if (i < object_groups_->length()) {
906 current_group_id = object_groups_->at(i).id;
907 current_group_start = i;
908 }
909 }
910 return to_return;
911 }
844 912
845 void GlobalHandles::RemoveObjectGroups() { 913 void GlobalHandles::RemoveObjectGroups() {
846 for (int i = 0; i < object_groups_.length(); i++) { 914 object_groups_->Clear();
847 object_groups_.at(i)->Dispose(); 915 retained_object_infos_.Clear();
848 }
849 object_groups_.Clear();
850 } 916 }
851 917
852 918
853 void GlobalHandles::RemoveImplicitRefGroups() { 919 void GlobalHandles::RemoveImplicitRefGroups() {
854 for (int i = 0; i < implicit_ref_groups_.length(); i++) { 920 for (int i = 0; i < implicit_ref_groups_.length(); i++) {
855 implicit_ref_groups_.at(i)->Dispose(); 921 implicit_ref_groups_.at(i)->Dispose();
856 } 922 }
857 implicit_ref_groups_.Clear(); 923 implicit_ref_groups_.Clear();
858 } 924 }
859 925
860 926
861 void GlobalHandles::TearDown() { 927 void GlobalHandles::TearDown() {
862 // TODO(1428): invoke weak callbacks. 928 // TODO(1428): invoke weak callbacks.
863 } 929 }
864 930
865 931
866 } } // namespace v8::internal 932 } } // 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