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

Side by Side Diff: src/heap.cc

Issue 6014004: Implement HeapIterator that skips over unreachable objects. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 10 years 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/heap.h ('k') | src/heap-profiler.cc » ('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 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 4465 matching lines...) Expand 10 before | Expand all | Expand 10 after
4476 *stats->map_space_capacity = map_space_->Capacity(); 4476 *stats->map_space_capacity = map_space_->Capacity();
4477 *stats->cell_space_size = cell_space_->Size(); 4477 *stats->cell_space_size = cell_space_->Size();
4478 *stats->cell_space_capacity = cell_space_->Capacity(); 4478 *stats->cell_space_capacity = cell_space_->Capacity();
4479 *stats->lo_space_size = lo_space_->Size(); 4479 *stats->lo_space_size = lo_space_->Size();
4480 GlobalHandles::RecordStats(stats); 4480 GlobalHandles::RecordStats(stats);
4481 *stats->memory_allocator_size = MemoryAllocator::Size(); 4481 *stats->memory_allocator_size = MemoryAllocator::Size();
4482 *stats->memory_allocator_capacity = 4482 *stats->memory_allocator_capacity =
4483 MemoryAllocator::Size() + MemoryAllocator::Available(); 4483 MemoryAllocator::Size() + MemoryAllocator::Available();
4484 *stats->os_error = OS::GetLastError(); 4484 *stats->os_error = OS::GetLastError();
4485 if (take_snapshot) { 4485 if (take_snapshot) {
4486 HeapIterator iterator(HeapIterator::kPreciseFiltering); 4486 HeapIterator iterator(HeapIterator::kFilterFreeListNodes);
4487 for (HeapObject* obj = iterator.next(); 4487 for (HeapObject* obj = iterator.next();
4488 obj != NULL; 4488 obj != NULL;
4489 obj = iterator.next()) { 4489 obj = iterator.next()) {
4490 InstanceType type = obj->map()->instance_type(); 4490 InstanceType type = obj->map()->instance_type();
4491 ASSERT(0 <= type && type <= LAST_TYPE); 4491 ASSERT(0 <= type && type <= LAST_TYPE);
4492 stats->objects_per_type[type]++; 4492 stats->objects_per_type[type]++;
4493 stats->size_per_type[type] += obj->Size(); 4493 stats->size_per_type[type] += obj->Size();
4494 } 4494 }
4495 } 4495 }
4496 } 4496 }
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
4910 iterator_ = new LargeObjectIterator(Heap::lo_space(), size_func_); 4910 iterator_ = new LargeObjectIterator(Heap::lo_space(), size_func_);
4911 break; 4911 break;
4912 } 4912 }
4913 4913
4914 // Return the newly allocated iterator; 4914 // Return the newly allocated iterator;
4915 ASSERT(iterator_ != NULL); 4915 ASSERT(iterator_ != NULL);
4916 return iterator_; 4916 return iterator_;
4917 } 4917 }
4918 4918
4919 4919
4920 class FreeListNodesFilter { 4920 class HeapObjectsFilter {
4921 public:
4922 virtual ~HeapObjectsFilter() {}
4923 virtual bool SkipObject(HeapObject* object) = 0;
4924 };
4925
4926
4927 class FreeListNodesFilter : public HeapObjectsFilter {
4921 public: 4928 public:
4922 FreeListNodesFilter() { 4929 FreeListNodesFilter() {
4923 MarkFreeListNodes(); 4930 MarkFreeListNodes();
4924 } 4931 }
4925 4932
4926 inline bool IsFreeListNode(HeapObject* object) { 4933 bool SkipObject(HeapObject* object) {
4927 if (object->IsMarked()) { 4934 if (object->IsMarked()) {
4928 object->ClearMark(); 4935 object->ClearMark();
4929 return true; 4936 return true;
4930 } else { 4937 } else {
4931 return false; 4938 return false;
4932 } 4939 }
4933 } 4940 }
4934 4941
4935 private: 4942 private:
4936 void MarkFreeListNodes() { 4943 void MarkFreeListNodes() {
(...skipping 11 matching lines...) Expand all
4948 obj != NULL; 4955 obj != NULL;
4949 obj = iter.next_object()) { 4956 obj = iter.next_object()) {
4950 if (FreeListNode::IsFreeListNode(obj)) obj->SetMark(); 4957 if (FreeListNode::IsFreeListNode(obj)) obj->SetMark();
4951 } 4958 }
4952 } 4959 }
4953 4960
4954 AssertNoAllocation no_alloc; 4961 AssertNoAllocation no_alloc;
4955 }; 4962 };
4956 4963
4957 4964
4965 class UnreachableObjectsFilter : public HeapObjectsFilter {
Søren Thygesen Gjesse 2010/12/21 09:04:44 Regarding the marking of unreachable objects - can
mnaganov (inactive) 2010/12/21 10:48:00 The problem is: once an object is marked, it doesn
4966 public:
4967 UnreachableObjectsFilter() {
4968 MarkUnreachableObjects();
4969 }
4970
4971 bool SkipObject(HeapObject* object) {
4972 if (object->IsMarked()) {
4973 object->ClearMark();
4974 return true;
4975 } else {
4976 return false;
4977 }
4978 }
4979
4980 private:
4981 class UnmarkingVisitor : public ObjectVisitor {
4982 public:
4983 UnmarkingVisitor() : list_(10) {}
4984
4985 void VisitPointers(Object** start, Object** end) {
4986 for (Object** p = start; p < end; p++) {
4987 if (!(*p)->IsHeapObject()) continue;
4988 HeapObject* obj = HeapObject::cast(*p);
4989 if (obj->IsMarked()) {
4990 obj->ClearMark();
4991 list_.Add(obj);
4992 }
4993 }
4994 }
4995
4996 bool can_process() { return !list_.is_empty(); }
4997
4998 void ProcessNext() {
4999 HeapObject* obj = list_.RemoveLast();
5000 obj->Iterate(this);
5001 }
5002
5003 private:
5004 List<HeapObject*> list_;
5005 };
5006
5007 void MarkUnreachableObjects() {
5008 HeapIterator iterator;
5009 for (HeapObject* obj = iterator.next();
5010 obj != NULL;
5011 obj = iterator.next()) {
5012 obj->SetMark();
5013 }
5014 UnmarkingVisitor visitor;
5015 Heap::IterateRoots(&visitor, VISIT_ONLY_STRONG);
5016 while (visitor.can_process())
5017 visitor.ProcessNext();
5018 }
5019
5020 AssertNoAllocation no_alloc;
5021 };
5022
5023
4958 HeapIterator::HeapIterator() 5024 HeapIterator::HeapIterator()
4959 : filtering_(HeapIterator::kNoFiltering), 5025 : filtering_(HeapIterator::kNoFiltering),
4960 filter_(NULL) { 5026 filter_(NULL) {
4961 Init(); 5027 Init();
4962 } 5028 }
4963 5029
4964 5030
4965 HeapIterator::HeapIterator(HeapIterator::FreeListNodesFiltering filtering) 5031 HeapIterator::HeapIterator(HeapIterator::HeapObjectsFiltering filtering)
4966 : filtering_(filtering), 5032 : filtering_(filtering),
4967 filter_(NULL) { 5033 filter_(NULL) {
4968 Init(); 5034 Init();
4969 } 5035 }
4970 5036
4971 5037
4972 HeapIterator::~HeapIterator() { 5038 HeapIterator::~HeapIterator() {
4973 Shutdown(); 5039 Shutdown();
4974 } 5040 }
4975 5041
4976 5042
4977 void HeapIterator::Init() { 5043 void HeapIterator::Init() {
4978 // Start the iteration. 5044 // Start the iteration.
4979 if (filtering_ == kPreciseFiltering) { 5045 space_iterator_ = filtering_ == kNoFiltering ? new SpaceIterator :
4980 filter_ = new FreeListNodesFilter; 5046 new SpaceIterator(MarkCompactCollector::SizeOfMarkedObject);
4981 space_iterator_ = 5047 switch (filtering_) {
4982 new SpaceIterator(MarkCompactCollector::SizeOfMarkedObject); 5048 case kFilterFreeListNodes:
4983 } else { 5049 filter_ = new FreeListNodesFilter;
4984 space_iterator_ = new SpaceIterator; 5050 break;
5051 case kFilterUnreachable:
5052 filter_ = new UnreachableObjectsFilter;
5053 break;
5054 default:
5055 break;
4985 } 5056 }
4986 object_iterator_ = space_iterator_->next(); 5057 object_iterator_ = space_iterator_->next();
4987 } 5058 }
4988 5059
4989 5060
4990 void HeapIterator::Shutdown() { 5061 void HeapIterator::Shutdown() {
4991 #ifdef DEBUG 5062 #ifdef DEBUG
4992 // Assert that in precise mode we have iterated through all 5063 // Assert that in filtering mode we have iterated through all
4993 // objects. Otherwise, heap will be left in an inconsistent state. 5064 // objects. Otherwise, heap will be left in an inconsistent state.
4994 if (filtering_ == kPreciseFiltering) { 5065 if (filtering_ != kNoFiltering) {
4995 ASSERT(object_iterator_ == NULL); 5066 ASSERT(object_iterator_ == NULL);
4996 } 5067 }
4997 #endif 5068 #endif
4998 // Make sure the last iterator is deallocated. 5069 // Make sure the last iterator is deallocated.
4999 delete space_iterator_; 5070 delete space_iterator_;
5000 space_iterator_ = NULL; 5071 space_iterator_ = NULL;
5001 object_iterator_ = NULL; 5072 object_iterator_ = NULL;
5002 delete filter_; 5073 delete filter_;
5003 filter_ = NULL; 5074 filter_ = NULL;
5004 } 5075 }
5005 5076
5006 5077
5007 HeapObject* HeapIterator::next() { 5078 HeapObject* HeapIterator::next() {
5008 if (filter_ == NULL) return NextObject(); 5079 if (filter_ == NULL) return NextObject();
5009 5080
5010 HeapObject* obj = NextObject(); 5081 HeapObject* obj = NextObject();
5011 while (obj != NULL && filter_->IsFreeListNode(obj)) obj = NextObject(); 5082 while (obj != NULL && filter_->SkipObject(obj)) obj = NextObject();
5012 return obj; 5083 return obj;
5013 } 5084 }
5014 5085
5015 5086
5016 HeapObject* HeapIterator::NextObject() { 5087 HeapObject* HeapIterator::NextObject() {
5017 // No iterator means we are done. 5088 // No iterator means we are done.
5018 if (object_iterator_ == NULL) return NULL; 5089 if (object_iterator_ == NULL) return NULL;
5019 5090
5020 if (HeapObject* obj = object_iterator_->next_object()) { 5091 if (HeapObject* obj = object_iterator_->next_object()) {
5021 // If the current iterator has more objects we are fine. 5092 // If the current iterator has more objects we are fine.
(...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after
5448 void ExternalStringTable::TearDown() { 5519 void ExternalStringTable::TearDown() {
5449 new_space_strings_.Free(); 5520 new_space_strings_.Free();
5450 old_space_strings_.Free(); 5521 old_space_strings_.Free();
5451 } 5522 }
5452 5523
5453 5524
5454 List<Object*> ExternalStringTable::new_space_strings_; 5525 List<Object*> ExternalStringTable::new_space_strings_;
5455 List<Object*> ExternalStringTable::old_space_strings_; 5526 List<Object*> ExternalStringTable::old_space_strings_;
5456 5527
5457 } } // namespace v8::internal 5528 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.h ('k') | src/heap-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698