| 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 4453 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4464 *stats->map_space_capacity = map_space_->Capacity(); | 4464 *stats->map_space_capacity = map_space_->Capacity(); |
| 4465 *stats->cell_space_size = cell_space_->Size(); | 4465 *stats->cell_space_size = cell_space_->Size(); |
| 4466 *stats->cell_space_capacity = cell_space_->Capacity(); | 4466 *stats->cell_space_capacity = cell_space_->Capacity(); |
| 4467 *stats->lo_space_size = lo_space_->Size(); | 4467 *stats->lo_space_size = lo_space_->Size(); |
| 4468 GlobalHandles::RecordStats(stats); | 4468 GlobalHandles::RecordStats(stats); |
| 4469 *stats->memory_allocator_size = MemoryAllocator::Size(); | 4469 *stats->memory_allocator_size = MemoryAllocator::Size(); |
| 4470 *stats->memory_allocator_capacity = | 4470 *stats->memory_allocator_capacity = |
| 4471 MemoryAllocator::Size() + MemoryAllocator::Available(); | 4471 MemoryAllocator::Size() + MemoryAllocator::Available(); |
| 4472 *stats->os_error = OS::GetLastError(); | 4472 *stats->os_error = OS::GetLastError(); |
| 4473 if (take_snapshot) { | 4473 if (take_snapshot) { |
| 4474 HeapIterator iterator(HeapIterator::kPreciseFiltering); | 4474 HeapIterator iterator(HeapIterator::kFilterFreeListNodes); |
| 4475 for (HeapObject* obj = iterator.next(); | 4475 for (HeapObject* obj = iterator.next(); |
| 4476 obj != NULL; | 4476 obj != NULL; |
| 4477 obj = iterator.next()) { | 4477 obj = iterator.next()) { |
| 4478 InstanceType type = obj->map()->instance_type(); | 4478 InstanceType type = obj->map()->instance_type(); |
| 4479 ASSERT(0 <= type && type <= LAST_TYPE); | 4479 ASSERT(0 <= type && type <= LAST_TYPE); |
| 4480 stats->objects_per_type[type]++; | 4480 stats->objects_per_type[type]++; |
| 4481 stats->size_per_type[type] += obj->Size(); | 4481 stats->size_per_type[type] += obj->Size(); |
| 4482 } | 4482 } |
| 4483 } | 4483 } |
| 4484 } | 4484 } |
| (...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4898 iterator_ = new LargeObjectIterator(Heap::lo_space(), size_func_); | 4898 iterator_ = new LargeObjectIterator(Heap::lo_space(), size_func_); |
| 4899 break; | 4899 break; |
| 4900 } | 4900 } |
| 4901 | 4901 |
| 4902 // Return the newly allocated iterator; | 4902 // Return the newly allocated iterator; |
| 4903 ASSERT(iterator_ != NULL); | 4903 ASSERT(iterator_ != NULL); |
| 4904 return iterator_; | 4904 return iterator_; |
| 4905 } | 4905 } |
| 4906 | 4906 |
| 4907 | 4907 |
| 4908 class FreeListNodesFilter { | 4908 class HeapObjectsFilter { |
| 4909 public: |
| 4910 virtual ~HeapObjectsFilter() {} |
| 4911 virtual bool SkipObject(HeapObject* object) = 0; |
| 4912 }; |
| 4913 |
| 4914 |
| 4915 class FreeListNodesFilter : public HeapObjectsFilter { |
| 4909 public: | 4916 public: |
| 4910 FreeListNodesFilter() { | 4917 FreeListNodesFilter() { |
| 4911 MarkFreeListNodes(); | 4918 MarkFreeListNodes(); |
| 4912 } | 4919 } |
| 4913 | 4920 |
| 4914 inline bool IsFreeListNode(HeapObject* object) { | 4921 bool SkipObject(HeapObject* object) { |
| 4915 if (object->IsMarked()) { | 4922 if (object->IsMarked()) { |
| 4916 object->ClearMark(); | 4923 object->ClearMark(); |
| 4917 return true; | 4924 return true; |
| 4918 } else { | 4925 } else { |
| 4919 return false; | 4926 return false; |
| 4920 } | 4927 } |
| 4921 } | 4928 } |
| 4922 | 4929 |
| 4923 private: | 4930 private: |
| 4924 void MarkFreeListNodes() { | 4931 void MarkFreeListNodes() { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4936 obj != NULL; | 4943 obj != NULL; |
| 4937 obj = iter.next_object()) { | 4944 obj = iter.next_object()) { |
| 4938 if (FreeListNode::IsFreeListNode(obj)) obj->SetMark(); | 4945 if (FreeListNode::IsFreeListNode(obj)) obj->SetMark(); |
| 4939 } | 4946 } |
| 4940 } | 4947 } |
| 4941 | 4948 |
| 4942 AssertNoAllocation no_alloc; | 4949 AssertNoAllocation no_alloc; |
| 4943 }; | 4950 }; |
| 4944 | 4951 |
| 4945 | 4952 |
| 4953 class UnreachableObjectsFilter : public HeapObjectsFilter { |
| 4954 public: |
| 4955 UnreachableObjectsFilter() { |
| 4956 MarkUnreachableObjects(); |
| 4957 } |
| 4958 |
| 4959 bool SkipObject(HeapObject* object) { |
| 4960 if (object->IsMarked()) { |
| 4961 object->ClearMark(); |
| 4962 return true; |
| 4963 } else { |
| 4964 return false; |
| 4965 } |
| 4966 } |
| 4967 |
| 4968 private: |
| 4969 class UnmarkingVisitor : public ObjectVisitor { |
| 4970 public: |
| 4971 UnmarkingVisitor() : list_(10) {} |
| 4972 |
| 4973 void VisitPointers(Object** start, Object** end) { |
| 4974 for (Object** p = start; p < end; p++) { |
| 4975 if (!(*p)->IsHeapObject()) continue; |
| 4976 HeapObject* obj = HeapObject::cast(*p); |
| 4977 if (obj->IsMarked()) { |
| 4978 obj->ClearMark(); |
| 4979 list_.Add(obj); |
| 4980 } |
| 4981 } |
| 4982 } |
| 4983 |
| 4984 bool can_process() { return !list_.is_empty(); } |
| 4985 |
| 4986 void ProcessNext() { |
| 4987 HeapObject* obj = list_.RemoveLast(); |
| 4988 obj->Iterate(this); |
| 4989 } |
| 4990 |
| 4991 private: |
| 4992 List<HeapObject*> list_; |
| 4993 }; |
| 4994 |
| 4995 void MarkUnreachableObjects() { |
| 4996 HeapIterator iterator; |
| 4997 for (HeapObject* obj = iterator.next(); |
| 4998 obj != NULL; |
| 4999 obj = iterator.next()) { |
| 5000 obj->SetMark(); |
| 5001 } |
| 5002 UnmarkingVisitor visitor; |
| 5003 Heap::IterateRoots(&visitor, VISIT_ONLY_STRONG); |
| 5004 while (visitor.can_process()) |
| 5005 visitor.ProcessNext(); |
| 5006 } |
| 5007 |
| 5008 AssertNoAllocation no_alloc; |
| 5009 }; |
| 5010 |
| 5011 |
| 4946 HeapIterator::HeapIterator() | 5012 HeapIterator::HeapIterator() |
| 4947 : filtering_(HeapIterator::kNoFiltering), | 5013 : filtering_(HeapIterator::kNoFiltering), |
| 4948 filter_(NULL) { | 5014 filter_(NULL) { |
| 4949 Init(); | 5015 Init(); |
| 4950 } | 5016 } |
| 4951 | 5017 |
| 4952 | 5018 |
| 4953 HeapIterator::HeapIterator(HeapIterator::FreeListNodesFiltering filtering) | 5019 HeapIterator::HeapIterator(HeapIterator::HeapObjectsFiltering filtering) |
| 4954 : filtering_(filtering), | 5020 : filtering_(filtering), |
| 4955 filter_(NULL) { | 5021 filter_(NULL) { |
| 4956 Init(); | 5022 Init(); |
| 4957 } | 5023 } |
| 4958 | 5024 |
| 4959 | 5025 |
| 4960 HeapIterator::~HeapIterator() { | 5026 HeapIterator::~HeapIterator() { |
| 4961 Shutdown(); | 5027 Shutdown(); |
| 4962 } | 5028 } |
| 4963 | 5029 |
| 4964 | 5030 |
| 4965 void HeapIterator::Init() { | 5031 void HeapIterator::Init() { |
| 4966 // Start the iteration. | 5032 // Start the iteration. |
| 4967 if (filtering_ == kPreciseFiltering) { | 5033 space_iterator_ = filtering_ == kNoFiltering ? new SpaceIterator : |
| 4968 filter_ = new FreeListNodesFilter; | 5034 new SpaceIterator(MarkCompactCollector::SizeOfMarkedObject); |
| 4969 space_iterator_ = | 5035 switch (filtering_) { |
| 4970 new SpaceIterator(MarkCompactCollector::SizeOfMarkedObject); | 5036 case kFilterFreeListNodes: |
| 4971 } else { | 5037 filter_ = new FreeListNodesFilter; |
| 4972 space_iterator_ = new SpaceIterator; | 5038 break; |
| 5039 case kFilterUnreachable: |
| 5040 filter_ = new UnreachableObjectsFilter; |
| 5041 break; |
| 5042 default: |
| 5043 break; |
| 4973 } | 5044 } |
| 4974 object_iterator_ = space_iterator_->next(); | 5045 object_iterator_ = space_iterator_->next(); |
| 4975 } | 5046 } |
| 4976 | 5047 |
| 4977 | 5048 |
| 4978 void HeapIterator::Shutdown() { | 5049 void HeapIterator::Shutdown() { |
| 4979 #ifdef DEBUG | 5050 #ifdef DEBUG |
| 4980 // Assert that in precise mode we have iterated through all | 5051 // Assert that in filtering mode we have iterated through all |
| 4981 // objects. Otherwise, heap will be left in an inconsistent state. | 5052 // objects. Otherwise, heap will be left in an inconsistent state. |
| 4982 if (filtering_ == kPreciseFiltering) { | 5053 if (filtering_ != kNoFiltering) { |
| 4983 ASSERT(object_iterator_ == NULL); | 5054 ASSERT(object_iterator_ == NULL); |
| 4984 } | 5055 } |
| 4985 #endif | 5056 #endif |
| 4986 // Make sure the last iterator is deallocated. | 5057 // Make sure the last iterator is deallocated. |
| 4987 delete space_iterator_; | 5058 delete space_iterator_; |
| 4988 space_iterator_ = NULL; | 5059 space_iterator_ = NULL; |
| 4989 object_iterator_ = NULL; | 5060 object_iterator_ = NULL; |
| 4990 delete filter_; | 5061 delete filter_; |
| 4991 filter_ = NULL; | 5062 filter_ = NULL; |
| 4992 } | 5063 } |
| 4993 | 5064 |
| 4994 | 5065 |
| 4995 HeapObject* HeapIterator::next() { | 5066 HeapObject* HeapIterator::next() { |
| 4996 if (filter_ == NULL) return NextObject(); | 5067 if (filter_ == NULL) return NextObject(); |
| 4997 | 5068 |
| 4998 HeapObject* obj = NextObject(); | 5069 HeapObject* obj = NextObject(); |
| 4999 while (obj != NULL && filter_->IsFreeListNode(obj)) obj = NextObject(); | 5070 while (obj != NULL && filter_->SkipObject(obj)) obj = NextObject(); |
| 5000 return obj; | 5071 return obj; |
| 5001 } | 5072 } |
| 5002 | 5073 |
| 5003 | 5074 |
| 5004 HeapObject* HeapIterator::NextObject() { | 5075 HeapObject* HeapIterator::NextObject() { |
| 5005 // No iterator means we are done. | 5076 // No iterator means we are done. |
| 5006 if (object_iterator_ == NULL) return NULL; | 5077 if (object_iterator_ == NULL) return NULL; |
| 5007 | 5078 |
| 5008 if (HeapObject* obj = object_iterator_->next_object()) { | 5079 if (HeapObject* obj = object_iterator_->next_object()) { |
| 5009 // If the current iterator has more objects we are fine. | 5080 // If the current iterator has more objects we are fine. |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5436 void ExternalStringTable::TearDown() { | 5507 void ExternalStringTable::TearDown() { |
| 5437 new_space_strings_.Free(); | 5508 new_space_strings_.Free(); |
| 5438 old_space_strings_.Free(); | 5509 old_space_strings_.Free(); |
| 5439 } | 5510 } |
| 5440 | 5511 |
| 5441 | 5512 |
| 5442 List<Object*> ExternalStringTable::new_space_strings_; | 5513 List<Object*> ExternalStringTable::new_space_strings_; |
| 5443 List<Object*> ExternalStringTable::old_space_strings_; | 5514 List<Object*> ExternalStringTable::old_space_strings_; |
| 5444 | 5515 |
| 5445 } } // namespace v8::internal | 5516 } } // namespace v8::internal |
| OLD | NEW |