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

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: Fix Slava's comments 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
« 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 386 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 397
398 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING) 398 #if defined(DEBUG) || defined(ENABLE_LOGGING_AND_PROFILING)
399 ReportStatisticsBeforeGC(); 399 ReportStatisticsBeforeGC();
400 #endif 400 #endif
401 } 401 }
402 402
403 intptr_t Heap::SizeOfObjects() { 403 intptr_t Heap::SizeOfObjects() {
404 intptr_t total = 0; 404 intptr_t total = 0;
405 AllSpaces spaces; 405 AllSpaces spaces;
406 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) { 406 for (Space* space = spaces.next(); space != NULL; space = spaces.next()) {
407 total += space->Size(); 407 total += space->SizeOfObjects();
408 } 408 }
409 return total; 409 return total;
410 } 410 }
411 411
412 void Heap::GarbageCollectionEpilogue() { 412 void Heap::GarbageCollectionEpilogue() {
413 #ifdef DEBUG 413 #ifdef DEBUG
414 allow_allocation(true); 414 allow_allocation(true);
415 ZapFromSpace(); 415 ZapFromSpace();
416 416
417 if (FLAG_verify_heap) { 417 if (FLAG_verify_heap) {
(...skipping 3983 matching lines...) Expand 10 before | Expand all | Expand 10 after
4401 *stats->map_space_capacity = map_space_->Capacity(); 4401 *stats->map_space_capacity = map_space_->Capacity();
4402 *stats->cell_space_size = cell_space_->Size(); 4402 *stats->cell_space_size = cell_space_->Size();
4403 *stats->cell_space_capacity = cell_space_->Capacity(); 4403 *stats->cell_space_capacity = cell_space_->Capacity();
4404 *stats->lo_space_size = lo_space_->Size(); 4404 *stats->lo_space_size = lo_space_->Size();
4405 GlobalHandles::RecordStats(stats); 4405 GlobalHandles::RecordStats(stats);
4406 *stats->memory_allocator_size = MemoryAllocator::Size(); 4406 *stats->memory_allocator_size = MemoryAllocator::Size();
4407 *stats->memory_allocator_capacity = 4407 *stats->memory_allocator_capacity =
4408 MemoryAllocator::Size() + MemoryAllocator::Available(); 4408 MemoryAllocator::Size() + MemoryAllocator::Available();
4409 *stats->os_error = OS::GetLastError(); 4409 *stats->os_error = OS::GetLastError();
4410 if (take_snapshot) { 4410 if (take_snapshot) {
4411 HeapIterator iterator; 4411 HeapIterator iterator(HeapIterator::kPreciseFiltering);
4412 for (HeapObject* obj = iterator.next(); 4412 for (HeapObject* obj = iterator.next();
4413 obj != NULL; 4413 obj != NULL;
4414 obj = iterator.next()) { 4414 obj = iterator.next()) {
4415 // Note: snapshot won't be precise because IsFreeListNode returns true
4416 // for any bytearray.
4417 if (FreeListNode::IsFreeListNode(obj)) continue;
4418 InstanceType type = obj->map()->instance_type(); 4415 InstanceType type = obj->map()->instance_type();
4419 ASSERT(0 <= type && type <= LAST_TYPE); 4416 ASSERT(0 <= type && type <= LAST_TYPE);
4420 stats->objects_per_type[type]++; 4417 stats->objects_per_type[type]++;
4421 stats->size_per_type[type] += obj->Size(); 4418 stats->size_per_type[type] += obj->Size();
4422 } 4419 }
4423 } 4420 }
4424 } 4421 }
4425 4422
4426 4423
4427 intptr_t Heap::PromotedSpaceSize() { 4424 intptr_t Heap::PromotedSpaceSize() {
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
4762 case OLD_DATA_SPACE: 4759 case OLD_DATA_SPACE:
4763 return Heap::old_data_space(); 4760 return Heap::old_data_space();
4764 case CODE_SPACE: 4761 case CODE_SPACE:
4765 return Heap::code_space(); 4762 return Heap::code_space();
4766 default: 4763 default:
4767 return NULL; 4764 return NULL;
4768 } 4765 }
4769 } 4766 }
4770 4767
4771 4768
4772 SpaceIterator::SpaceIterator() : current_space_(FIRST_SPACE), iterator_(NULL) { 4769 SpaceIterator::SpaceIterator()
4770 : current_space_(FIRST_SPACE),
4771 iterator_(NULL),
4772 size_func_(NULL) {
4773 } 4773 }
4774 4774
4775 4775
4776 SpaceIterator::SpaceIterator(HeapObjectCallback size_func)
4777 : current_space_(FIRST_SPACE),
4778 iterator_(NULL),
4779 size_func_(size_func) {
4780 }
4781
4782
4776 SpaceIterator::~SpaceIterator() { 4783 SpaceIterator::~SpaceIterator() {
4777 // Delete active iterator if any. 4784 // Delete active iterator if any.
4778 delete iterator_; 4785 delete iterator_;
4779 } 4786 }
4780 4787
4781 4788
4782 bool SpaceIterator::has_next() { 4789 bool SpaceIterator::has_next() {
4783 // Iterate until no more spaces. 4790 // Iterate until no more spaces.
4784 return current_space_ != LAST_SPACE; 4791 return current_space_ != LAST_SPACE;
4785 } 4792 }
(...skipping 14 matching lines...) Expand all
4800 return CreateIterator(); 4807 return CreateIterator();
4801 } 4808 }
4802 4809
4803 4810
4804 // Create an iterator for the space to iterate. 4811 // Create an iterator for the space to iterate.
4805 ObjectIterator* SpaceIterator::CreateIterator() { 4812 ObjectIterator* SpaceIterator::CreateIterator() {
4806 ASSERT(iterator_ == NULL); 4813 ASSERT(iterator_ == NULL);
4807 4814
4808 switch (current_space_) { 4815 switch (current_space_) {
4809 case NEW_SPACE: 4816 case NEW_SPACE:
4810 iterator_ = new SemiSpaceIterator(Heap::new_space()); 4817 iterator_ = new SemiSpaceIterator(Heap::new_space(), size_func_);
4811 break; 4818 break;
4812 case OLD_POINTER_SPACE: 4819 case OLD_POINTER_SPACE:
4813 iterator_ = new HeapObjectIterator(Heap::old_pointer_space()); 4820 iterator_ = new HeapObjectIterator(Heap::old_pointer_space(), size_func_);
4814 break; 4821 break;
4815 case OLD_DATA_SPACE: 4822 case OLD_DATA_SPACE:
4816 iterator_ = new HeapObjectIterator(Heap::old_data_space()); 4823 iterator_ = new HeapObjectIterator(Heap::old_data_space(), size_func_);
4817 break; 4824 break;
4818 case CODE_SPACE: 4825 case CODE_SPACE:
4819 iterator_ = new HeapObjectIterator(Heap::code_space()); 4826 iterator_ = new HeapObjectIterator(Heap::code_space(), size_func_);
4820 break; 4827 break;
4821 case MAP_SPACE: 4828 case MAP_SPACE:
4822 iterator_ = new HeapObjectIterator(Heap::map_space()); 4829 iterator_ = new HeapObjectIterator(Heap::map_space(), size_func_);
4823 break; 4830 break;
4824 case CELL_SPACE: 4831 case CELL_SPACE:
4825 iterator_ = new HeapObjectIterator(Heap::cell_space()); 4832 iterator_ = new HeapObjectIterator(Heap::cell_space(), size_func_);
4826 break; 4833 break;
4827 case LO_SPACE: 4834 case LO_SPACE:
4828 iterator_ = new LargeObjectIterator(Heap::lo_space()); 4835 iterator_ = new LargeObjectIterator(Heap::lo_space(), size_func_);
4829 break; 4836 break;
4830 } 4837 }
4831 4838
4832 // Return the newly allocated iterator; 4839 // Return the newly allocated iterator;
4833 ASSERT(iterator_ != NULL); 4840 ASSERT(iterator_ != NULL);
4834 return iterator_; 4841 return iterator_;
4835 } 4842 }
4836 4843
4837 4844
4838 HeapIterator::HeapIterator() { 4845 class FreeListNodesFilter {
4846 public:
4847 FreeListNodesFilter() {
4848 MarkFreeListNodes();
4849 }
4850
4851 inline bool IsFreeListNode(HeapObject* object) {
4852 if (object->IsMarked()) {
4853 object->ClearMark();
4854 return true;
4855 } else {
4856 return false;
4857 }
4858 }
4859
4860 private:
4861 void MarkFreeListNodes() {
4862 Heap::old_pointer_space()->MarkFreeListNodes();
4863 Heap::old_data_space()->MarkFreeListNodes();
4864 MarkCodeSpaceFreeListNodes();
4865 Heap::map_space()->MarkFreeListNodes();
4866 Heap::cell_space()->MarkFreeListNodes();
4867 }
4868
4869 void MarkCodeSpaceFreeListNodes() {
4870 // For code space, using FreeListNode::IsFreeListNode is OK.
4871 HeapObjectIterator iter(Heap::code_space());
4872 for (HeapObject* obj = iter.next_object();
4873 obj != NULL;
4874 obj = iter.next_object()) {
4875 if (FreeListNode::IsFreeListNode(obj)) obj->SetMark();
4876 }
4877 }
4878
4879 AssertNoAllocation no_alloc;
4880 };
4881
4882
4883 HeapIterator::HeapIterator()
4884 : filtering_(HeapIterator::kNoFiltering),
4885 filter_(NULL) {
4839 Init(); 4886 Init();
4840 } 4887 }
4841 4888
4889
4890 HeapIterator::HeapIterator(HeapIterator::FreeListNodesFiltering filtering)
4891 : filtering_(filtering),
4892 filter_(NULL) {
4893 Init();
4894 }
4895
4842 4896
4843 HeapIterator::~HeapIterator() { 4897 HeapIterator::~HeapIterator() {
4844 Shutdown(); 4898 Shutdown();
4845 } 4899 }
4846 4900
4847 4901
4848 void HeapIterator::Init() { 4902 void HeapIterator::Init() {
4849 // Start the iteration. 4903 // Start the iteration.
4850 space_iterator_ = new SpaceIterator(); 4904 if (filtering_ == kPreciseFiltering) {
4905 filter_ = new FreeListNodesFilter;
4906 space_iterator_ =
4907 new SpaceIterator(MarkCompactCollector::SizeOfMarkedObject);
4908 } else {
4909 space_iterator_ = new SpaceIterator;
4910 }
4851 object_iterator_ = space_iterator_->next(); 4911 object_iterator_ = space_iterator_->next();
4852 } 4912 }
4853 4913
4854 4914
4855 void HeapIterator::Shutdown() { 4915 void HeapIterator::Shutdown() {
4916 #ifdef DEBUG
4917 // Assert that in precise mode we have iterated through all
4918 // objects. Otherwise, heap will be left in an inconsistent state.
4919 if (filtering_ == kPreciseFiltering) {
4920 ASSERT(object_iterator_ == NULL);
4921 }
4922 #endif
4856 // Make sure the last iterator is deallocated. 4923 // Make sure the last iterator is deallocated.
4857 delete space_iterator_; 4924 delete space_iterator_;
4858 space_iterator_ = NULL; 4925 space_iterator_ = NULL;
4859 object_iterator_ = NULL; 4926 object_iterator_ = NULL;
4927 delete filter_;
4928 filter_ = NULL;
4860 } 4929 }
4861 4930
4862 4931
4863 HeapObject* HeapIterator::next() { 4932 HeapObject* HeapIterator::next() {
4933 if (filter_ == NULL) return NextObject();
4934
4935 HeapObject* obj = NextObject();
4936 while (obj != NULL && filter_->IsFreeListNode(obj)) obj = NextObject();
4937 return obj;
4938 }
4939
4940
4941 HeapObject* HeapIterator::NextObject() {
4864 // No iterator means we are done. 4942 // No iterator means we are done.
4865 if (object_iterator_ == NULL) return NULL; 4943 if (object_iterator_ == NULL) return NULL;
4866 4944
4867 if (HeapObject* obj = object_iterator_->next_object()) { 4945 if (HeapObject* obj = object_iterator_->next_object()) {
4868 // If the current iterator has more objects we are fine. 4946 // If the current iterator has more objects we are fine.
4869 return obj; 4947 return obj;
4870 } else { 4948 } else {
4871 // Go though the spaces looking for one that has objects. 4949 // Go though the spaces looking for one that has objects.
4872 while (space_iterator_->has_next()) { 4950 while (space_iterator_->has_next()) {
4873 object_iterator_ = space_iterator_->next(); 4951 object_iterator_ = space_iterator_->next();
(...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after
5295 void ExternalStringTable::TearDown() { 5373 void ExternalStringTable::TearDown() {
5296 new_space_strings_.Free(); 5374 new_space_strings_.Free();
5297 old_space_strings_.Free(); 5375 old_space_strings_.Free();
5298 } 5376 }
5299 5377
5300 5378
5301 List<Object*> ExternalStringTable::new_space_strings_; 5379 List<Object*> ExternalStringTable::new_space_strings_;
5302 List<Object*> ExternalStringTable::old_space_strings_; 5380 List<Object*> ExternalStringTable::old_space_strings_;
5303 5381
5304 } } // namespace v8::internal 5382 } } // 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