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

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

Issue 352763002: Grow heap slower if GC freed many global handles. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add comment Created 6 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « src/global-handles.h ('k') | src/heap.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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/api.h" 7 #include "src/api.h"
8 #include "src/global-handles.h" 8 #include "src/global-handles.h"
9 9
10 #include "src/vm-state-inl.h" 10 #include "src/vm-state-inl.h"
(...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after
604 // Once the entire group has been iterated over, set the object 604 // Once the entire group has been iterated over, set the object
605 // group to NULL so it won't be processed again. 605 // group to NULL so it won't be processed again.
606 delete entry; 606 delete entry;
607 object_groups_.at(i) = NULL; 607 object_groups_.at(i) = NULL;
608 } 608 }
609 object_groups_.Rewind(last); 609 object_groups_.Rewind(last);
610 return any_group_was_visited; 610 return any_group_was_visited;
611 } 611 }
612 612
613 613
614 bool GlobalHandles::PostGarbageCollectionProcessing( 614 int GlobalHandles::PostGarbageCollectionProcessing(
615 GarbageCollector collector, GCTracer* tracer) { 615 GarbageCollector collector, GCTracer* tracer) {
616 // Process weak global handle callbacks. This must be done after the 616 // Process weak global handle callbacks. This must be done after the
617 // GC is completely done, because the callbacks may invoke arbitrary 617 // GC is completely done, because the callbacks may invoke arbitrary
618 // API functions. 618 // API functions.
619 ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC); 619 ASSERT(isolate_->heap()->gc_state() == Heap::NOT_IN_GC);
620 const int initial_post_gc_processing_count = ++post_gc_processing_count_; 620 const int initial_post_gc_processing_count = ++post_gc_processing_count_;
621 bool next_gc_likely_to_collect_more = false; 621 int freed_nodes = 0;
622 if (collector == SCAVENGER) { 622 if (collector == SCAVENGER) {
623 for (int i = 0; i < new_space_nodes_.length(); ++i) { 623 for (int i = 0; i < new_space_nodes_.length(); ++i) {
624 Node* node = new_space_nodes_[i]; 624 Node* node = new_space_nodes_[i];
625 ASSERT(node->is_in_new_space_list()); 625 ASSERT(node->is_in_new_space_list());
626 if (!node->IsRetainer()) { 626 if (!node->IsRetainer()) {
627 // Free nodes do not have weak callbacks. Do not use them to compute 627 // Free nodes do not have weak callbacks. Do not use them to compute
628 // the next_gc_likely_to_collect_more. 628 // the freed_nodes.
629 continue; 629 continue;
630 } 630 }
631 // Skip dependent handles. Their weak callbacks might expect to be 631 // Skip dependent handles. Their weak callbacks might expect to be
632 // called between two global garbage collection callbacks which 632 // called between two global garbage collection callbacks which
633 // are not called for minor collections. 633 // are not called for minor collections.
634 if (!node->is_independent() && !node->is_partially_dependent()) { 634 if (!node->is_independent() && !node->is_partially_dependent()) {
635 continue; 635 continue;
636 } 636 }
637 node->clear_partially_dependent(); 637 node->clear_partially_dependent();
638 if (node->PostGarbageCollectionProcessing(isolate_)) { 638 if (node->PostGarbageCollectionProcessing(isolate_)) {
639 if (initial_post_gc_processing_count != post_gc_processing_count_) { 639 if (initial_post_gc_processing_count != post_gc_processing_count_) {
640 // Weak callback triggered another GC and another round of 640 // Weak callback triggered another GC and another round of
641 // PostGarbageCollection processing. The current node might 641 // PostGarbageCollection processing. The current node might
642 // have been deleted in that round, so we need to bail out (or 642 // have been deleted in that round, so we need to bail out (or
643 // restart the processing). 643 // restart the processing).
644 return next_gc_likely_to_collect_more; 644 return freed_nodes;
645 } 645 }
646 } 646 }
647 if (!node->IsRetainer()) { 647 if (!node->IsRetainer()) {
648 next_gc_likely_to_collect_more = true; 648 freed_nodes++;
649 } 649 }
650 } 650 }
651 } else { 651 } else {
652 for (NodeIterator it(this); !it.done(); it.Advance()) { 652 for (NodeIterator it(this); !it.done(); it.Advance()) {
653 if (!it.node()->IsRetainer()) { 653 if (!it.node()->IsRetainer()) {
654 // Free nodes do not have weak callbacks. Do not use them to compute 654 // Free nodes do not have weak callbacks. Do not use them to compute
655 // the next_gc_likely_to_collect_more. 655 // the freed_nodes.
656 continue; 656 continue;
657 } 657 }
658 it.node()->clear_partially_dependent(); 658 it.node()->clear_partially_dependent();
659 if (it.node()->PostGarbageCollectionProcessing(isolate_)) { 659 if (it.node()->PostGarbageCollectionProcessing(isolate_)) {
660 if (initial_post_gc_processing_count != post_gc_processing_count_) { 660 if (initial_post_gc_processing_count != post_gc_processing_count_) {
661 // See the comment above. 661 // See the comment above.
662 return next_gc_likely_to_collect_more; 662 return freed_nodes;
663 } 663 }
664 } 664 }
665 if (!it.node()->IsRetainer()) { 665 if (!it.node()->IsRetainer()) {
666 next_gc_likely_to_collect_more = true; 666 freed_nodes++;
667 } 667 }
668 } 668 }
669 } 669 }
670 // Update the list of new space nodes. 670 // Update the list of new space nodes.
671 int last = 0; 671 int last = 0;
672 for (int i = 0; i < new_space_nodes_.length(); ++i) { 672 for (int i = 0; i < new_space_nodes_.length(); ++i) {
673 Node* node = new_space_nodes_[i]; 673 Node* node = new_space_nodes_[i];
674 ASSERT(node->is_in_new_space_list()); 674 ASSERT(node->is_in_new_space_list());
675 if (node->IsRetainer()) { 675 if (node->IsRetainer()) {
676 if (isolate_->heap()->InNewSpace(node->object())) { 676 if (isolate_->heap()->InNewSpace(node->object())) {
677 new_space_nodes_[last++] = node; 677 new_space_nodes_[last++] = node;
678 tracer->increment_nodes_copied_in_new_space(); 678 tracer->increment_nodes_copied_in_new_space();
679 } else { 679 } else {
680 node->set_in_new_space_list(false); 680 node->set_in_new_space_list(false);
681 tracer->increment_nodes_promoted(); 681 tracer->increment_nodes_promoted();
682 } 682 }
683 } else { 683 } else {
684 node->set_in_new_space_list(false); 684 node->set_in_new_space_list(false);
685 tracer->increment_nodes_died_in_new_space(); 685 tracer->increment_nodes_died_in_new_space();
686 } 686 }
687 } 687 }
688 new_space_nodes_.Rewind(last); 688 new_space_nodes_.Rewind(last);
689 return next_gc_likely_to_collect_more; 689 return freed_nodes;
690 } 690 }
691 691
692 692
693 void GlobalHandles::IterateStrongRoots(ObjectVisitor* v) { 693 void GlobalHandles::IterateStrongRoots(ObjectVisitor* v) {
694 for (NodeIterator it(this); !it.done(); it.Advance()) { 694 for (NodeIterator it(this); !it.done(); it.Advance()) {
695 if (it.node()->IsStrongRetainer()) { 695 if (it.node()->IsStrongRetainer()) {
696 v->VisitPointer(it.node()->location()); 696 v->VisitPointer(it.node()->location());
697 } 697 }
698 } 698 }
699 } 699 }
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
1064 ASSERT_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]); 1064 ASSERT_EQ(isolate->heap()->the_hole_value(), blocks_[block][offset]);
1065 blocks_[block][offset] = object; 1065 blocks_[block][offset] = object;
1066 if (isolate->heap()->InNewSpace(object)) { 1066 if (isolate->heap()->InNewSpace(object)) {
1067 new_space_indices_.Add(size_); 1067 new_space_indices_.Add(size_);
1068 } 1068 }
1069 *index = size_++; 1069 *index = size_++;
1070 } 1070 }
1071 1071
1072 1072
1073 } } // namespace v8::internal 1073 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/global-handles.h ('k') | src/heap.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698