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