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

Side by Side Diff: src/heap.cc

Issue 6088012: Separate markbits from heap object map words into bitmaps. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/gc
Patch Set: profiler related code reenabled Created 9 years, 11 months 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-inl.h » ('j') | src/mark-compact.cc » ('J')
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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
208 bool Heap::HasBeenSetup() { 208 bool Heap::HasBeenSetup() {
209 return old_pointer_space_ != NULL && 209 return old_pointer_space_ != NULL &&
210 old_data_space_ != NULL && 210 old_data_space_ != NULL &&
211 code_space_ != NULL && 211 code_space_ != NULL &&
212 map_space_ != NULL && 212 map_space_ != NULL &&
213 cell_space_ != NULL && 213 cell_space_ != NULL &&
214 lo_space_ != NULL; 214 lo_space_ != NULL;
215 } 215 }
216 216
217 217
218 int Heap::GcSafeSizeOfOldObject(HeapObject* object) { 218 int Heap::GcSafeSizeOfOldObject(HeapObject* object) {
Erik Corry 2011/01/07 12:13:21 Shouldn't we just get rid of this alltogether?
219 ASSERT(!Heap::InNewSpace(object)); // Code only works for old objects. 219 return object->Size();
220 ASSERT(!MarkCompactCollector::are_map_pointers_encoded());
221 MapWord map_word = object->map_word();
222 map_word.ClearMark();
223 map_word.ClearOverflow();
224 return object->SizeFromMap(map_word.ToMap());
225 } 220 }
226 221
227 222
228 GarbageCollector Heap::SelectGarbageCollector(AllocationSpace space) { 223 GarbageCollector Heap::SelectGarbageCollector(AllocationSpace space) {
229 // Is global GC requested? 224 // Is global GC requested?
230 if (space != NEW_SPACE || FLAG_gc_global) { 225 if (space != NEW_SPACE || FLAG_gc_global) {
231 Counters::gc_compactor_caused_by_request.Increment(); 226 Counters::gc_compactor_caused_by_request.Increment();
232 return MARK_COMPACTOR; 227 return MARK_COMPACTOR;
233 } 228 }
234 229
(...skipping 4356 matching lines...) Expand 10 before | Expand all | Expand 10 after
4591 } 4586 }
4592 4587
4593 LOG(IntPtrTEvent("heap-capacity", Capacity())); 4588 LOG(IntPtrTEvent("heap-capacity", Capacity()));
4594 LOG(IntPtrTEvent("heap-available", Available())); 4589 LOG(IntPtrTEvent("heap-available", Available()));
4595 4590
4596 #ifdef ENABLE_LOGGING_AND_PROFILING 4591 #ifdef ENABLE_LOGGING_AND_PROFILING
4597 // This should be called only after initial objects have been created. 4592 // This should be called only after initial objects have been created.
4598 ProducerHeapProfile::Setup(); 4593 ProducerHeapProfile::Setup();
4599 #endif 4594 #endif
4600 4595
4596 if (!Marking::Setup()) return false;
4597
4601 return true; 4598 return true;
4602 } 4599 }
4603 4600
4604 4601
4605 void Heap::SetStackLimits() { 4602 void Heap::SetStackLimits() {
4606 // On 64 bit machines, pointers are generally out of range of Smis. We write 4603 // On 64 bit machines, pointers are generally out of range of Smis. We write
4607 // something that looks like an out of range Smi to the GC. 4604 // something that looks like an out of range Smi to the GC.
4608 4605
4609 // Set up the special root array entries containing the stack limits. 4606 // Set up the special root array entries containing the stack limits.
4610 // These are actually addresses, but the tag makes the GC ignore it. 4607 // These are actually addresses, but the tag makes the GC ignore it.
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
4665 delete cell_space_; 4662 delete cell_space_;
4666 cell_space_ = NULL; 4663 cell_space_ = NULL;
4667 } 4664 }
4668 4665
4669 if (lo_space_ != NULL) { 4666 if (lo_space_ != NULL) {
4670 lo_space_->TearDown(); 4667 lo_space_->TearDown();
4671 delete lo_space_; 4668 delete lo_space_;
4672 lo_space_ = NULL; 4669 lo_space_ = NULL;
4673 } 4670 }
4674 4671
4672 Marking::TearDown();
4673
4675 MemoryAllocator::TearDown(); 4674 MemoryAllocator::TearDown();
4676 } 4675 }
4677 4676
4678 4677
4679 void Heap::Shrink() { 4678 void Heap::Shrink() {
4680 // Try to shrink all paged spaces. 4679 // Try to shrink all paged spaces.
4681 PagedSpaces spaces; 4680 PagedSpaces spaces;
4682 for (PagedSpace* space = spaces.next(); space != NULL; space = spaces.next()) 4681 for (PagedSpace* space = spaces.next(); space != NULL; space = spaces.next())
4683 space->Shrink(); 4682 space->Shrink();
4684 } 4683 }
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
4898 } 4897 }
4899 4898
4900 4899
4901 class HeapObjectsFilter { 4900 class HeapObjectsFilter {
4902 public: 4901 public:
4903 virtual ~HeapObjectsFilter() {} 4902 virtual ~HeapObjectsFilter() {}
4904 virtual bool SkipObject(HeapObject* object) = 0; 4903 virtual bool SkipObject(HeapObject* object) = 0;
4905 }; 4904 };
4906 4905
4907 4906
4907 // Intrusive object marking uses least significant bit of
4908 // heap object's map word to mark objects.
4909 // Normally all map words have least significant bit set
4910 // because they contain tagged map pointer.
4911 // If the bit is not set object is marked.
4912 // All objects should be unmarked before resuming
4913 // JavaScript execution.
4914 class IntrusiveMarking {
4915 public:
4916 static bool IsMarked(HeapObject* object) {
4917 return (object->map_word().ToRawValue() & kNotMarkedBit) == 0;
4918 }
4919
4920 static void ClearMark(HeapObject* object) {
4921 uintptr_t map_word = object->map_word().ToRawValue();
4922 object->set_map_word(MapWord::FromRawValue(map_word | kNotMarkedBit));
4923 }
4924
4925 static void SetMark(HeapObject* object) {
4926 uintptr_t map_word = object->map_word().ToRawValue();
4927 object->set_map_word(MapWord::FromRawValue(map_word & ~kNotMarkedBit));
4928 }
4929
4930 private:
4931 static const uintptr_t kNotMarkedBit = 0x1;
4932 STATIC_ASSERT((kHeapObjectTag & kNotMarkedBit) != 0);
4933 };
4934
4908 class FreeListNodesFilter : public HeapObjectsFilter { 4935 class FreeListNodesFilter : public HeapObjectsFilter {
4909 public: 4936 public:
4910 FreeListNodesFilter() { 4937 FreeListNodesFilter() {
4911 MarkFreeListNodes(); 4938 MarkFreeListNodes();
4912 } 4939 }
4913 4940
4914 bool SkipObject(HeapObject* object) { 4941 bool SkipObject(HeapObject* object) {
4915 if (object->IsMarked()) { 4942 if (IntrusiveMarking::IsMarked(object)) {
4916 object->ClearMark(); 4943 IntrusiveMarking::ClearMark(object);
4917 return true; 4944 return true;
4918 } else { 4945 } else {
4919 return false; 4946 return false;
4920 } 4947 }
4921 } 4948 }
4922 4949
4923 private: 4950 private:
4924 void MarkFreeListNodes() { 4951 void MarkFreeListNodes() {
4925 Heap::old_pointer_space()->MarkFreeListNodes(); 4952 Heap::old_pointer_space()->MarkFreeListNodes();
4926 Heap::old_data_space()->MarkFreeListNodes(); 4953 Heap::old_data_space()->MarkFreeListNodes();
4927 MarkCodeSpaceFreeListNodes(); 4954 MarkCodeSpaceFreeListNodes();
4928 Heap::map_space()->MarkFreeListNodes(); 4955 Heap::map_space()->MarkFreeListNodes();
4929 Heap::cell_space()->MarkFreeListNodes(); 4956 Heap::cell_space()->MarkFreeListNodes();
4930 } 4957 }
4931 4958
4932 void MarkCodeSpaceFreeListNodes() { 4959 void MarkCodeSpaceFreeListNodes() {
4933 // For code space, using FreeListNode::IsFreeListNode is OK. 4960 // For code space, using FreeListNode::IsFreeListNode is OK.
4934 HeapObjectIterator iter(Heap::code_space()); 4961 HeapObjectIterator iter(Heap::code_space());
4935 for (HeapObject* obj = iter.next_object(); 4962 for (HeapObject* obj = iter.next_object();
4936 obj != NULL; 4963 obj != NULL;
4937 obj = iter.next_object()) { 4964 obj = iter.next_object()) {
4938 if (FreeListNode::IsFreeListNode(obj)) obj->SetMark(); 4965 if (FreeListNode::IsFreeListNode(obj)) {
4966 IntrusiveMarking::SetMark(obj);
4967 }
4939 } 4968 }
4940 } 4969 }
4941 4970
4942 AssertNoAllocation no_alloc; 4971 AssertNoAllocation no_alloc;
4943 }; 4972 };
4944 4973
4945 4974
4946 class UnreachableObjectsFilter : public HeapObjectsFilter { 4975 class UnreachableObjectsFilter : public HeapObjectsFilter {
4947 public: 4976 public:
4948 UnreachableObjectsFilter() { 4977 UnreachableObjectsFilter() {
4949 MarkUnreachableObjects(); 4978 MarkUnreachableObjects();
4950 } 4979 }
4951 4980
4952 bool SkipObject(HeapObject* object) { 4981 bool SkipObject(HeapObject* object) {
4953 if (object->IsMarked()) { 4982 if (IntrusiveMarking::IsMarked(object)) {
4954 object->ClearMark(); 4983 IntrusiveMarking::ClearMark(object);
4955 return true; 4984 return true;
4956 } else { 4985 } else {
4957 return false; 4986 return false;
4958 } 4987 }
4959 } 4988 }
4960 4989
4961 private: 4990 private:
4962 class UnmarkingVisitor : public ObjectVisitor { 4991 class UnmarkingVisitor : public ObjectVisitor {
4963 public: 4992 public:
4964 UnmarkingVisitor() : list_(10) {} 4993 UnmarkingVisitor() : list_(10) {}
4965 4994
4966 void VisitPointers(Object** start, Object** end) { 4995 void VisitPointers(Object** start, Object** end) {
4967 for (Object** p = start; p < end; p++) { 4996 for (Object** p = start; p < end; p++) {
4968 if (!(*p)->IsHeapObject()) continue; 4997 if (!(*p)->IsHeapObject()) continue;
4969 HeapObject* obj = HeapObject::cast(*p); 4998 HeapObject* obj = HeapObject::cast(*p);
4970 if (obj->IsMarked()) { 4999 if (IntrusiveMarking::IsMarked(obj)) {
4971 obj->ClearMark(); 5000 IntrusiveMarking::ClearMark(obj);
4972 list_.Add(obj); 5001 list_.Add(obj);
4973 } 5002 }
4974 } 5003 }
4975 } 5004 }
4976 5005
4977 bool can_process() { return !list_.is_empty(); } 5006 bool can_process() { return !list_.is_empty(); }
4978 5007
4979 void ProcessNext() { 5008 void ProcessNext() {
4980 HeapObject* obj = list_.RemoveLast(); 5009 HeapObject* obj = list_.RemoveLast();
4981 obj->Iterate(this); 5010 obj->Iterate(this);
4982 } 5011 }
4983 5012
4984 private: 5013 private:
4985 List<HeapObject*> list_; 5014 List<HeapObject*> list_;
4986 }; 5015 };
4987 5016
4988 void MarkUnreachableObjects() { 5017 void MarkUnreachableObjects() {
4989 HeapIterator iterator; 5018 HeapIterator iterator;
4990 for (HeapObject* obj = iterator.next(); 5019 for (HeapObject* obj = iterator.next();
4991 obj != NULL; 5020 obj != NULL;
4992 obj = iterator.next()) { 5021 obj = iterator.next()) {
4993 obj->SetMark(); 5022 IntrusiveMarking::SetMark(obj);
4994 } 5023 }
4995 UnmarkingVisitor visitor; 5024 UnmarkingVisitor visitor;
4996 Heap::IterateRoots(&visitor, VISIT_ONLY_STRONG); 5025 Heap::IterateRoots(&visitor, VISIT_ONLY_STRONG);
4997 while (visitor.can_process()) 5026 while (visitor.can_process())
4998 visitor.ProcessNext(); 5027 visitor.ProcessNext();
4999 } 5028 }
5000 5029
5001 AssertNoAllocation no_alloc; 5030 AssertNoAllocation no_alloc;
5002 }; 5031 };
5003 5032
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
5277 gc_count_(0), 5306 gc_count_(0),
5278 full_gc_count_(0), 5307 full_gc_count_(0),
5279 is_compacting_(false), 5308 is_compacting_(false),
5280 marked_count_(0), 5309 marked_count_(0),
5281 allocated_since_last_gc_(0), 5310 allocated_since_last_gc_(0),
5282 spent_in_mutator_(0), 5311 spent_in_mutator_(0),
5283 promoted_objects_size_(0) { 5312 promoted_objects_size_(0) {
5284 // These two fields reflect the state of the previous full collection. 5313 // These two fields reflect the state of the previous full collection.
5285 // Set them before they are changed by the collector. 5314 // Set them before they are changed by the collector.
5286 previous_has_compacted_ = MarkCompactCollector::HasCompacted(); 5315 previous_has_compacted_ = MarkCompactCollector::HasCompacted();
5287 previous_marked_count_ = MarkCompactCollector::previous_marked_count();
5288 if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return; 5316 if (!FLAG_trace_gc && !FLAG_print_cumulative_gc_stat) return;
5289 start_time_ = OS::TimeCurrentMillis(); 5317 start_time_ = OS::TimeCurrentMillis();
5290 start_size_ = Heap::SizeOfObjects(); 5318 start_size_ = Heap::SizeOfObjects();
5291 5319
5292 for (int i = 0; i < Scope::kNumberOfScopes; i++) { 5320 for (int i = 0; i < Scope::kNumberOfScopes; i++) {
5293 scopes_[i] = 0; 5321 scopes_[i] = 0;
5294 } 5322 }
5295 5323
5296 in_free_list_or_wasted_before_gc_ = CountTotalHolesSize(); 5324 in_free_list_or_wasted_before_gc_ = CountTotalHolesSize();
5297 5325
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
5500 void ExternalStringTable::TearDown() { 5528 void ExternalStringTable::TearDown() {
5501 new_space_strings_.Free(); 5529 new_space_strings_.Free();
5502 old_space_strings_.Free(); 5530 old_space_strings_.Free();
5503 } 5531 }
5504 5532
5505 5533
5506 List<Object*> ExternalStringTable::new_space_strings_; 5534 List<Object*> ExternalStringTable::new_space_strings_;
5507 List<Object*> ExternalStringTable::old_space_strings_; 5535 List<Object*> ExternalStringTable::old_space_strings_;
5508 5536
5509 } } // namespace v8::internal 5537 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/heap.h ('k') | src/heap-inl.h » ('j') | src/mark-compact.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698