| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |