Chromium Code Reviews| 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 |