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

Side by Side Diff: src/heap.cc

Issue 4888001: Provide more accurate results about used heap size via GetHeapStatistics. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Aligned sizes reported by Heap::SizeOfObjects and HeapIterator with free nodes filtering Created 10 years, 1 month 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
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 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
388 388
389 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) 389 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
390 ReportStatisticsBeforeGC(); 390 ReportStatisticsBeforeGC();
391 #endif 391 #endif
392 } 392 }
393 393
394 intptr_t Heap::SizeOfObjects() { 394 intptr_t Heap::SizeOfObjects() {
395 intptr_t total = 0; 395 intptr_t total = 0;
396 AllSpaces spaces; 396 AllSpaces spaces;
397 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { 397 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
398 total += space->Size(); 398 total += space->SizeOfObjects();
399 } 399 }
400 return total; 400 return total;
401 } 401 }
402 402
403 void Heap::GarbageCollectionEpilogue() { 403 void Heap::GarbageCollectionEpilogue() {
404 #ifdef DEBUG 404 #ifdef DEBUG
405 allow_allocation(true); 405 allow_allocation(true);
406 ZapFromSpace(); 406 ZapFromSpace();
407 407
408 if (FLAG_verify_heap) { 408 if (FLAG_verify_heap) {
(...skipping 3983 matching lines...) Expand 10 before | Expand all | Expand 10 after
4392 *stats->map_space_capacity = map_space_->Capacity(); 4392 *stats->map_space_capacity = map_space_->Capacity();
4393 *stats->cell_space_size = cell_space_->Size(); 4393 *stats->cell_space_size = cell_space_->Size();
4394 *stats->cell_space_capacity = cell_space_->Capacity(); 4394 *stats->cell_space_capacity = cell_space_->Capacity();
4395 *stats->lo_space_size = lo_space_->Size(); 4395 *stats->lo_space_size = lo_space_->Size();
4396 GlobalHandles::RecordStats(stats); 4396 GlobalHandles::RecordStats(stats);
4397 *stats->memory_allocator_size = MemoryAllocator::Size(); 4397 *stats->memory_allocator_size = MemoryAllocator::Size();
4398 *stats->memory_allocator_capacity = 4398 *stats->memory_allocator_capacity =
4399 MemoryAllocator::Size() + MemoryAllocator::Available(); 4399 MemoryAllocator::Size() + MemoryAllocator::Available();
4400 *stats->os_error = OS::GetLastError(); 4400 *stats->os_error = OS::GetLastError();
4401 if (take_snapshot) { 4401 if (take_snapshot) {
4402 HeapIterator iterator; 4402 HeapIterator iterator(HeapIterator::kPreciseFiltering);
4403 for (HeapObject* obj = iterator.next(); 4403 for (HeapObject* obj = iterator.next();
4404 obj != NULL; 4404 obj != NULL;
4405 obj = iterator.next()) { 4405 obj = iterator.next()) {
4406 // Note: snapshot won't be precise because IsFreeListNode returns true
4407 // for any bytearray.
4408 if (FreeListNode::IsFreeListNode(obj)) continue;
antonm 2010/11/13 17:37:51 thank you very much!
4409 InstanceType type = obj->map()->instance_type(); 4406 InstanceType type = obj->map()->instance_type();
4410 ASSERT(0 <= type && type <= LAST_TYPE); 4407 ASSERT(0 <= type && type <= LAST_TYPE);
4411 stats->objects_per_type[type]++; 4408 stats->objects_per_type[type]++;
4412 stats->size_per_type[type] += obj->Size(); 4409 stats->size_per_type[type] += obj->Size();
4413 } 4410 }
4414 } 4411 }
4415 } 4412 }
4416 4413
4417 4414
4418 intptr_t Heap::PromotedSpaceSize() { 4415 intptr_t Heap::PromotedSpaceSize() {
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
4753 case OLD_DATA_SPACE: 4750 case OLD_DATA_SPACE:
4754 return Heap::old_data_space(); 4751 return Heap::old_data_space();
4755 case CODE_SPACE: 4752 case CODE_SPACE:
4756 return Heap::code_space(); 4753 return Heap::code_space();
4757 default: 4754 default:
4758 return NULL; 4755 return NULL;
4759 } 4756 }
4760 } 4757 }
4761 4758
4762 4759
4763 SpaceIterator::SpaceIterator() : current_space_(FIRST_SPACE), iterator_(NULL) { 4760 SpaceIterator::SpaceIterator()
4761 : current_space_(FIRST_SPACE),
4762 iterator_(NULL),
4763 size_func_(NULL) {
4764 } 4764 }
4765 4765
4766 4766
4767 SpaceIterator::SpaceIterator(HeapObjectCallback size_func)
4768 : current_space_(FIRST_SPACE),
4769 iterator_(NULL),
4770 size_func_(size_func) {
4771 }
4772
4773
4767 SpaceIterator::~SpaceIterator() { 4774 SpaceIterator::~SpaceIterator() {
4768 // Delete active iterator if any. 4775 // Delete active iterator if any.
4769 delete iterator_; 4776 delete iterator_;
4770 } 4777 }
4771 4778
4772 4779
4773 bool SpaceIterator::has_next() { 4780 bool SpaceIterator::has_next() {
4774 // Iterate until no more spaces. 4781 // Iterate until no more spaces.
4775 return current_space_ != LAST_SPACE; 4782 return current_space_ != LAST_SPACE;
4776 } 4783 }
(...skipping 14 matching lines...) Expand all
4791 return CreateIterator(); 4798 return CreateIterator();
4792 } 4799 }
4793 4800
4794 4801
4795 // Create an iterator for the space to iterate. 4802 // Create an iterator for the space to iterate.
4796 ObjectIterator* SpaceIterator::CreateIterator() { 4803 ObjectIterator* SpaceIterator::CreateIterator() {
4797 ASSERT(iterator_ == NULL); 4804 ASSERT(iterator_ == NULL);
4798 4805
4799 switch (current_space_) { 4806 switch (current_space_) {
4800 case NEW_SPACE: 4807 case NEW_SPACE:
4801 iterator_ = new SemiSpaceIterator(Heap::new_space()); 4808 iterator_ = new SemiSpaceIterator(Heap::new_space(), size_func_);
4802 break; 4809 break;
4803 case OLD_POINTER_SPACE: 4810 case OLD_POINTER_SPACE:
4804 iterator_ = new HeapObjectIterator(Heap::old_pointer_space()); 4811 iterator_ = new HeapObjectIterator(Heap::old_pointer_space(), size_func_);
4805 break; 4812 break;
4806 case OLD_DATA_SPACE: 4813 case OLD_DATA_SPACE:
4807 iterator_ = new HeapObjectIterator(Heap::old_data_space()); 4814 iterator_ = new HeapObjectIterator(Heap::old_data_space(), size_func_);
4808 break; 4815 break;
4809 case CODE_SPACE: 4816 case CODE_SPACE:
4810 iterator_ = new HeapObjectIterator(Heap::code_space()); 4817 iterator_ = new HeapObjectIterator(Heap::code_space(), size_func_);
4811 break; 4818 break;
4812 case MAP_SPACE: 4819 case MAP_SPACE:
4813 iterator_ = new HeapObjectIterator(Heap::map_space()); 4820 iterator_ = new HeapObjectIterator(Heap::map_space(), size_func_);
4814 break; 4821 break;
4815 case CELL_SPACE: 4822 case CELL_SPACE:
4816 iterator_ = new HeapObjectIterator(Heap::cell_space()); 4823 iterator_ = new HeapObjectIterator(Heap::cell_space(), size_func_);
4817 break; 4824 break;
4818 case LO_SPACE: 4825 case LO_SPACE:
4819 iterator_ = new LargeObjectIterator(Heap::lo_space()); 4826 iterator_ = new LargeObjectIterator(Heap::lo_space(), size_func_);
4820 break; 4827 break;
4821 } 4828 }
4822 4829
4823 // Return the newly allocated iterator; 4830 // Return the newly allocated iterator;
4824 ASSERT(iterator_ != NULL); 4831 ASSERT(iterator_ != NULL);
4825 return iterator_; 4832 return iterator_;
4826 } 4833 }
4827 4834
4828 4835
4829 HeapIterator::HeapIterator() { 4836 class FreeListNodesFilter : public Malloced {
4837 public:
4838 FreeListNodesFilter() {
4839 MarkFreeListNodes();
4840 }
4841
4842 inline bool IsFreeListNode(HeapObject* object) {
4843 if (object->IsMarked()) {
4844 object->ClearMark();
4845 return true;
4846 } else {
4847 return false;
4848 }
4849 }
4850
4851 static int ObjectSize(HeapObject* object) {
4852 bool marked = object->IsMarked();
antonm 2010/11/13 17:37:51 MapWord might be the right abstraction for this co
mnaganov (inactive) 2010/11/13 19:05:30 Hm. Not sure how using MapWord will help. HeapObje
4853 if (marked)
antonm 2010/11/13 17:37:51 nit: either on a single line or in braces, please
mnaganov (inactive) 2010/11/13 19:05:30 Done.
4854 object->ClearMark();
4855 int size = object->Size();
4856 if (marked)
antonm 2010/11/13 17:37:51 ditto
mnaganov (inactive) 2010/11/13 19:05:30 Done.
4857 object->SetMark();
4858 return size;
4859 }
4860
4861 private:
4862 void MarkFreeListNodes() {
4863 Heap::old_pointer_space()->MarkFreeListNodes();
4864 Heap::old_data_space()->MarkFreeListNodes();
4865 MarkCodeSpaceFreeListNodes();
4866 Heap::map_space()->MarkFreeListNodes();
4867 Heap::cell_space()->MarkFreeListNodes();
4868 }
4869
4870 void MarkCodeSpaceFreeListNodes() {
4871 // For code space, using FreeListNode::IsFreeListNode is OK.
4872 ObjectIterator* iter = new HeapObjectIterator(Heap::code_space());
antonm 2010/11/13 17:37:51 why you need to malloc iterator? can you allocate
mnaganov (inactive) 2010/11/13 19:05:30 Not sure. It is a descendant of the class Malloced
4873 for (HeapObject* obj = iter->next_object();
4874 obj != NULL;
4875 obj = iter->next_object()) {
4876 if (FreeListNode::IsFreeListNode(obj))
antonm 2010/11/13 17:37:51 ditto for braces
mnaganov (inactive) 2010/11/13 19:05:30 Done.
4877 obj->SetMark();
4878 }
4879 delete iter;
4880 }
4881 };
4882
4883
4884 HeapIterator::HeapIterator()
4885 : filtering_(HeapIterator::kNoFiltering),
4886 filter_(NULL) {
4830 Init(); 4887 Init();
4831 } 4888 }
4832 4889
4890
4891 HeapIterator::HeapIterator(HeapIterator::FreeListNodesFiltering filtering)
4892 : filtering_(filtering),
4893 filter_(NULL) {
4894 Init();
4895 }
4896
4833 4897
4834 HeapIterator::~HeapIterator() { 4898 HeapIterator::~HeapIterator() {
4835 Shutdown(); 4899 Shutdown();
4836 } 4900 }
4837 4901
4838 4902
4839 void HeapIterator::Init() { 4903 void HeapIterator::Init() {
4840 // Start the iteration. 4904 // Start the iteration.
4841 space_iterator_ = new SpaceIterator(); 4905 if (filtering_ == kPreciseFiltering) {
4906 filter_ = new FreeListNodesFilter();
antonm 2010/11/13 17:37:51 looks like new trend is to omit () for ctors with
mnaganov (inactive) 2010/11/13 19:05:30 Done.
4907 space_iterator_ = new SpaceIterator(FreeListNodesFilter::ObjectSize);
4908 } else {
4909 space_iterator_ = new SpaceIterator();
antonm 2010/11/13 17:37:51 ditto
mnaganov (inactive) 2010/11/13 19:05:30 Done.
4910 }
4842 object_iterator_ = space_iterator_->next(); 4911 object_iterator_ = space_iterator_->next();
4843 } 4912 }
4844 4913
4845 4914
4846 void HeapIterator::Shutdown() { 4915 void HeapIterator::Shutdown() {
4847 // Make sure the last iterator is deallocated. 4916 // Make sure the last iterator is deallocated.
4848 delete space_iterator_; 4917 delete space_iterator_;
4849 space_iterator_ = NULL; 4918 space_iterator_ = NULL;
4850 object_iterator_ = NULL; 4919 object_iterator_ = NULL;
4920 delete filter_;
4921 filter_ = NULL;
4851 } 4922 }
4852 4923
4853 4924
4854 HeapObject* HeapIterator::next() { 4925 HeapObject* HeapIterator::next() {
4926 if (filter_ == NULL)
antonm 2010/11/13 17:37:51 ditto for braces (here and below)
mnaganov (inactive) 2010/11/13 19:05:30 Done.
4927 return NextObject();
4928
4929 HeapObject* obj = NextObject();
4930 while (obj != NULL && filter_->IsFreeListNode(obj))
4931 obj = NextObject();
4932 return obj;
4933 }
4934
4935
4936 HeapObject* HeapIterator::NextObject() {
4855 // No iterator means we are done. 4937 // No iterator means we are done.
4856 if (object_iterator_ == NULL) return NULL; 4938 if (object_iterator_ == NULL) return NULL;
4857 4939
4858 if (HeapObject* obj = object_iterator_->next_object()) { 4940 if (HeapObject* obj = object_iterator_->next_object()) {
4859 // If the current iterator has more objects we are fine. 4941 // If the current iterator has more objects we are fine.
4860 return obj; 4942 return obj;
4861 } else { 4943 } else {
4862 // Go though the spaces looking for one that has objects. 4944 // Go though the spaces looking for one that has objects.
4863 while (space_iterator_->has_next()) { 4945 while (space_iterator_->has_next()) {
4864 object_iterator_ = space_iterator_->next(); 4946 object_iterator_ = space_iterator_->next();
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
5286 void ExternalStringTable::TearDown() { 5368 void ExternalStringTable::TearDown() {
5287 new_space_strings_.Free(); 5369 new_space_strings_.Free();
5288 old_space_strings_.Free(); 5370 old_space_strings_.Free();
5289 } 5371 }
5290 5372
5291 5373
5292 List<Object*> ExternalStringTable::new_space_strings_; 5374 List<Object*> ExternalStringTable::new_space_strings_;
5293 List<Object*> ExternalStringTable::old_space_strings_; 5375 List<Object*> ExternalStringTable::old_space_strings_;
5294 5376
5295 } } // namespace v8::internal 5377 } } // namespace v8::internal
OLDNEW
« src/heap.h ('K') | « src/heap.h ('k') | src/heap-profiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698