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 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |