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

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: fixed 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 }
46
47
44 class GlobalHandles::Node { 48 class GlobalHandles::Node {
45 public: 49 public:
46 // State transition diagram: 50 // State transition diagram:
47 // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE } 51 // FREE -> NORMAL <-> WEAK -> PENDING -> NEAR_DEATH -> { NORMAL, WEAK, FREE }
48 enum State { 52 enum State {
49 FREE = 0, 53 FREE = 0,
50 NORMAL, // Normal global handle. 54 NORMAL, // Normal global handle.
51 WEAK, // Flagged as weak but not yet finalized. 55 WEAK, // Flagged as weak but not yet finalized.
52 PENDING, // Has been recognized as only reachable by weak handles. 56 PENDING, // Has been recognized as only reachable by weak handles.
53 NEAR_DEATH // Callback has informed the handle is near death. 57 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); 435 DISALLOW_COPY_AND_ASSIGN(NodeIterator);
432 }; 436 };
433 437
434 438
435 GlobalHandles::GlobalHandles(Isolate* isolate) 439 GlobalHandles::GlobalHandles(Isolate* isolate)
436 : isolate_(isolate), 440 : isolate_(isolate),
437 number_of_global_handles_(0), 441 number_of_global_handles_(0),
438 first_block_(NULL), 442 first_block_(NULL),
439 first_used_block_(NULL), 443 first_used_block_(NULL),
440 first_free_(NULL), 444 first_free_(NULL),
441 post_gc_processing_count_(0) {} 445 post_gc_processing_count_(0),
446 object_groups_(new List<ObjectGroupConnection>()) {}
442 447
443 448
444 GlobalHandles::~GlobalHandles() { 449 GlobalHandles::~GlobalHandles() {
445 NodeBlock* block = first_block_; 450 NodeBlock* block = first_block_;
446 while (block != NULL) { 451 while (block != NULL) {
447 NodeBlock* tmp = block->next(); 452 NodeBlock* tmp = block->next();
448 delete block; 453 delete block;
449 block = tmp; 454 block = tmp;
450 } 455 }
451 first_block_ = NULL; 456 first_block_ = NULL;
457 delete object_groups_;
452 } 458 }
453 459
454 460
455 Handle<Object> GlobalHandles::Create(Object* value) { 461 Handle<Object> GlobalHandles::Create(Object* value) {
456 isolate_->counters()->global_handles()->Increment(); 462 isolate_->counters()->global_handles()->Increment();
457 number_of_global_handles_++; 463 number_of_global_handles_++;
458 if (first_free_ == NULL) { 464 if (first_free_ == NULL) {
459 first_block_ = new NodeBlock(first_block_); 465 first_block_ = new NodeBlock(first_block_);
460 first_block_->PutNodesOnFreeList(&first_free_); 466 first_block_->PutNodesOnFreeList(&first_free_);
461 } 467 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
568 for (int i = 0; i < new_space_nodes_.length(); ++i) { 574 for (int i = 0; i < new_space_nodes_.length(); ++i) {
569 Node* node = new_space_nodes_[i]; 575 Node* node = new_space_nodes_[i];
570 ASSERT(node->is_in_new_space_list()); 576 ASSERT(node->is_in_new_space_list());
571 if ((node->is_independent() || node->is_partially_dependent()) && 577 if ((node->is_independent() || node->is_partially_dependent()) &&
572 node->IsWeakRetainer()) { 578 node->IsWeakRetainer()) {
573 v->VisitPointer(node->location()); 579 v->VisitPointer(node->location());
574 } 580 }
575 } 581 }
576 } 582 }
577 583
578
579 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v, 584 bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v,
580 WeakSlotCallbackWithHeap can_skip) { 585 WeakSlotCallbackWithHeap can_skip) {
581 int last = 0; 586 if (object_groups_->length() == 0)
587 return false;
588
589 object_groups_->Sort();
590 // Stores information about unvisited object groups for later use.
591 List<ObjectGroupConnection>* new_object_groups =
592 new List<ObjectGroupConnection>();
593
594 void* current_group_id = NULL;
595 size_t current_group_start = 0;
582 bool any_group_was_visited = false; 596 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 597
587 Object*** objects = entry->objects_; 598 for (int i = 0; i <= object_groups_->length(); ++i) {
588 bool group_should_be_visited = false; 599 if (i == 0)
589 for (size_t j = 0; j < entry->length_; j++) { 600 current_group_id = object_groups_->at(i).id;
590 Object* object = *objects[j]; 601 if (i == object_groups_->length() ||
591 if (object->IsHeapObject()) { 602 current_group_id != object_groups_->at(i).id) {
592 if (!can_skip(isolate_->heap(), &object)) { 603 // Group detected: objects in indices [current_group_start, i[.
593 group_should_be_visited = true; 604 bool group_should_be_visited = false;
594 break; 605 for (int j = current_group_start; j < i; ++j) {
606 Object* object = *(object_groups_->at(j).object);
607 if (object->IsHeapObject()) {
608 if (!can_skip(isolate_->heap(), &object)) {
609 group_should_be_visited = true;
610 break;
611 }
595 } 612 }
596 } 613 }
597 } 614 if (!group_should_be_visited) {
598 615 for (int j = current_group_start; j < i; ++j)
599 if (!group_should_be_visited) { 616 new_object_groups->Add(object_groups_->at(j));
Michael Starzinger 2013/04/09 14:18:40 It would be good if we could get by with an in-pla
marja 2013/04/09 16:46:51 Done.
600 object_groups_[last++] = entry; 617 } else {
601 continue; 618 // An object in the group requires visiting, so iterate over all
602 } 619 // objects in the group.
603 620 for (int j = current_group_start; j < i; ++j) {
604 // An object in the group requires visiting, so iterate over all 621 Object* object = *(object_groups_->at(j).object);
605 // objects in the group. 622 if (object->IsHeapObject()) {
606 for (size_t j = 0; j < entry->length_; ++j) { 623 v->VisitPointer(&object);
607 Object* object = *objects[j]; 624 any_group_was_visited = true;
608 if (object->IsHeapObject()) { 625 }
609 v->VisitPointer(&object); 626 }
610 any_group_was_visited = true; 627 }
628 if (i < object_groups_->length()) {
629 current_group_id = object_groups_->at(i).id;
630 current_group_start = i;
611 } 631 }
612 } 632 }
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 } 633 }
619 object_groups_.Rewind(last); 634 delete object_groups_;
635 object_groups_ = new_object_groups;
620 return any_group_was_visited; 636 return any_group_was_visited;
621 } 637 }
622 638
623 639
624 bool GlobalHandles::PostGarbageCollectionProcessing( 640 bool GlobalHandles::PostGarbageCollectionProcessing(
625 GarbageCollector collector, GCTracer* tracer) { 641 GarbageCollector collector, GCTracer* tracer) {
626 // Process weak global handle callbacks. This must be done after the 642 // Process weak global handle callbacks. This must be done after the
627 // GC is completely done, because the callbacks may invoke arbitrary 643 // GC is completely done, because the callbacks may invoke arbitrary
628 // API functions. 644 // API functions.
629 ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC); 645 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) { 833 v8::RetainedObjectInfo* info) {
818 #ifdef DEBUG 834 #ifdef DEBUG
819 for (size_t i = 0; i < length; ++i) { 835 for (size_t i = 0; i < length; ++i) {
820 ASSERT(!Node::FromLocation(handles[i])->is_independent()); 836 ASSERT(!Node::FromLocation(handles[i])->is_independent());
821 } 837 }
822 #endif 838 #endif
823 if (length == 0) { 839 if (length == 0) {
824 if (info != NULL) info->Dispose(); 840 if (info != NULL) info->Dispose();
825 return; 841 return;
826 } 842 }
827 object_groups_.Add(ObjectGroup::New(handles, length, info)); 843 for (size_t i = 0; i < length; ++i)
844 object_groups_->Add(ObjectGroupConnection(handles[0], handles[i]));
845 retained_object_infos_.Add(GroupRetainedObjectInfo(handles[0], info));
828 } 846 }
829 847
830 848
849 void GlobalHandles::SetObjectGroupId(Object** handle,
850 void* id) {
851 object_groups_->Add(ObjectGroupConnection(id, handle));
852 }
853
854
855 void GlobalHandles::SetRetainedObjectInfo(void* id,
856 RetainedObjectInfo* info) {
857 retained_object_infos_.Add(GroupRetainedObjectInfo(id, info));
858 }
859
860
831 void GlobalHandles::AddImplicitReferences(HeapObject** parent, 861 void GlobalHandles::AddImplicitReferences(HeapObject** parent,
832 Object*** children, 862 Object*** children,
833 size_t length) { 863 size_t length) {
834 #ifdef DEBUG 864 #ifdef DEBUG
835 ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent()); 865 ASSERT(!Node::FromLocation(BitCast<Object**>(parent))->is_independent());
836 for (size_t i = 0; i < length; ++i) { 866 for (size_t i = 0; i < length; ++i) {
837 ASSERT(!Node::FromLocation(children[i])->is_independent()); 867 ASSERT(!Node::FromLocation(children[i])->is_independent());
838 } 868 }
839 #endif 869 #endif
840 if (length == 0) return; 870 if (length == 0) return;
841 implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length)); 871 implicit_ref_groups_.Add(ImplicitRefGroup::New(parent, children, length));
842 } 872 }
843 873
874 List<ObjectGroup*>* GlobalHandles::object_groups() {
Michael Starzinger 2013/04/09 14:18:40 This transferal of ownership of the structure look
marja 2013/04/09 16:46:51 I couldn't wrap my head around how to transfer the
875 List<ObjectGroup*>* to_return = new List<ObjectGroup*>();
876
877 object_groups_->Sort();
878 retained_object_infos_.Sort();
879 int retained_object_infos_ix = 0;
880
881 void* current_group_id = NULL;
882 size_t current_group_start = 0;
883
884 for (int i = 0; i <= object_groups_->length(); ++i) {
885 if (i == 0)
886 current_group_id = object_groups_->at(i).id;
887 if (i == object_groups_->length() ||
888 current_group_id != object_groups_->at(i).id) {
889 // Group detected: objects in indices [current_group_start, i[.
890 ObjectGroup* group = new ObjectGroup();
891 if (retained_object_infos_ix < retained_object_infos_.length() &&
892 retained_object_infos_[retained_object_infos_ix].id ==
893 object_groups_->at(current_group_start).id) {
894 // Transfer the ownership of info.
895 group->info = retained_object_infos_[retained_object_infos_ix].info;
896 retained_object_infos_[retained_object_infos_ix].info = NULL;
897 ++retained_object_infos_ix;
898 }
899 for (int j = current_group_start; j < i; ++j)
900 group->objects.Add(object_groups_->at(j).object);
901 to_return->Add(group);
902 }
903 if (i < object_groups_->length()) {
904 current_group_id = object_groups_->at(i).id;
905 current_group_start = i;
906 }
907 }
908 return to_return;
909 }
844 910
845 void GlobalHandles::RemoveObjectGroups() { 911 void GlobalHandles::RemoveObjectGroups() {
846 for (int i = 0; i < object_groups_.length(); i++) { 912 object_groups_->Clear();
847 object_groups_.at(i)->Dispose(); 913 for (int i = 0; i < retained_object_infos_.length(); ++i) {
914 if (retained_object_infos_[i].info != NULL)
915 retained_object_infos_[i].info->Dispose();
848 } 916 }
849 object_groups_.Clear(); 917 retained_object_infos_.Clear();
850 } 918 }
851 919
852 920
853 void GlobalHandles::RemoveImplicitRefGroups() { 921 void GlobalHandles::RemoveImplicitRefGroups() {
854 for (int i = 0; i < implicit_ref_groups_.length(); i++) { 922 for (int i = 0; i < implicit_ref_groups_.length(); i++) {
855 implicit_ref_groups_.at(i)->Dispose(); 923 implicit_ref_groups_.at(i)->Dispose();
856 } 924 }
857 implicit_ref_groups_.Clear(); 925 implicit_ref_groups_.Clear();
858 } 926 }
859 927
860 928
861 void GlobalHandles::TearDown() { 929 void GlobalHandles::TearDown() {
862 // TODO(1428): invoke weak callbacks. 930 // TODO(1428): invoke weak callbacks.
863 } 931 }
864 932
865 933
866 } } // namespace v8::internal 934 } } // 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