| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 217 return old_pointer_space_ != NULL && | 217 return old_pointer_space_ != NULL && |
| 218 old_data_space_ != NULL && | 218 old_data_space_ != NULL && |
| 219 code_space_ != NULL && | 219 code_space_ != NULL && |
| 220 map_space_ != NULL && | 220 map_space_ != NULL && |
| 221 cell_space_ != NULL && | 221 cell_space_ != NULL && |
| 222 lo_space_ != NULL; | 222 lo_space_ != NULL; |
| 223 } | 223 } |
| 224 | 224 |
| 225 | 225 |
| 226 int Heap::GcSafeSizeOfOldObject(HeapObject* object) { | 226 int Heap::GcSafeSizeOfOldObject(HeapObject* object) { |
| 227 return object->Size(); | 227 if (IntrusiveMarking::IsMarked(object)) { |
| 228 return IntrusiveMarking::SizeOfMarkedObject(object); |
| 229 } |
| 230 return object->SizeFromMap(object->map()); |
| 228 } | 231 } |
| 229 | 232 |
| 230 | 233 |
| 231 GarbageCollector Heap::SelectGarbageCollector(AllocationSpace space) { | 234 GarbageCollector Heap::SelectGarbageCollector(AllocationSpace space) { |
| 232 // Is global GC requested? | 235 // Is global GC requested? |
| 233 if (space != NEW_SPACE || FLAG_gc_global) { | 236 if (space != NEW_SPACE || FLAG_gc_global) { |
| 234 isolate_->counters()->gc_compactor_caused_by_request()->Increment(); | 237 isolate_->counters()->gc_compactor_caused_by_request()->Increment(); |
| 235 return MARK_COMPACTOR; | 238 return MARK_COMPACTOR; |
| 236 } | 239 } |
| 237 | 240 |
| (...skipping 3872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4110 (size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : OLD_POINTER_SPACE; | 4113 (size > MaxObjectSizeInPagedSpace()) ? LO_SPACE : OLD_POINTER_SPACE; |
| 4111 Object* result; | 4114 Object* result; |
| 4112 { MaybeObject* maybe_result = Allocate(map, space); | 4115 { MaybeObject* maybe_result = Allocate(map, space); |
| 4113 if (!maybe_result->ToObject(&result)) return maybe_result; | 4116 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 4114 } | 4117 } |
| 4115 Struct::cast(result)->InitializeBody(size); | 4118 Struct::cast(result)->InitializeBody(size); |
| 4116 return result; | 4119 return result; |
| 4117 } | 4120 } |
| 4118 | 4121 |
| 4119 | 4122 |
| 4123 bool Heap::IsHeapIterable() { |
| 4124 return (!old_pointer_space()->was_swept_conservatively() && |
| 4125 !old_data_space()->was_swept_conservatively()); |
| 4126 } |
| 4127 |
| 4128 |
| 4120 void Heap::EnsureHeapIsIterable() { | 4129 void Heap::EnsureHeapIsIterable() { |
| 4121 ASSERT(IsAllocationAllowed()); | 4130 ASSERT(IsAllocationAllowed()); |
| 4122 if (old_pointer_space()->was_swept_conservatively() || | 4131 if (!IsHeapIterable()) { |
| 4123 old_data_space()->was_swept_conservatively()) { | |
| 4124 CollectAllGarbage(kMakeHeapIterableMask); | 4132 CollectAllGarbage(kMakeHeapIterableMask); |
| 4125 } | 4133 } |
| 4126 ASSERT(!old_pointer_space()->was_swept_conservatively()); | 4134 ASSERT(IsHeapIterable()); |
| 4127 ASSERT(!old_data_space()->was_swept_conservatively()); | |
| 4128 } | 4135 } |
| 4129 | 4136 |
| 4130 | 4137 |
| 4131 bool Heap::IdleNotification() { | 4138 bool Heap::IdleNotification() { |
| 4132 static const int kIdlesBeforeScavenge = 4; | 4139 static const int kIdlesBeforeScavenge = 4; |
| 4133 static const int kIdlesBeforeMarkSweep = 7; | 4140 static const int kIdlesBeforeMarkSweep = 7; |
| 4134 static const int kIdlesBeforeMarkCompact = 8; | 4141 static const int kIdlesBeforeMarkCompact = 8; |
| 4135 static const int kMaxIdleCount = kIdlesBeforeMarkCompact + 1; | 4142 static const int kMaxIdleCount = kIdlesBeforeMarkCompact + 1; |
| 4136 static const unsigned int kGCsBetweenCleanup = 4; | 4143 static const unsigned int kGCsBetweenCleanup = 4; |
| 4137 | 4144 |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4334 old_pointer_space_->Verify(&visitor); | 4341 old_pointer_space_->Verify(&visitor); |
| 4335 map_space_->Verify(&visitor); | 4342 map_space_->Verify(&visitor); |
| 4336 | 4343 |
| 4337 VerifyPointersVisitor no_dirty_regions_visitor; | 4344 VerifyPointersVisitor no_dirty_regions_visitor; |
| 4338 old_data_space_->Verify(&no_dirty_regions_visitor); | 4345 old_data_space_->Verify(&no_dirty_regions_visitor); |
| 4339 code_space_->Verify(&no_dirty_regions_visitor); | 4346 code_space_->Verify(&no_dirty_regions_visitor); |
| 4340 cell_space_->Verify(&no_dirty_regions_visitor); | 4347 cell_space_->Verify(&no_dirty_regions_visitor); |
| 4341 | 4348 |
| 4342 lo_space_->Verify(); | 4349 lo_space_->Verify(); |
| 4343 } | 4350 } |
| 4351 |
| 4344 #endif // DEBUG | 4352 #endif // DEBUG |
| 4345 | 4353 |
| 4346 | 4354 |
| 4347 MaybeObject* Heap::LookupSymbol(Vector<const char> string) { | 4355 MaybeObject* Heap::LookupSymbol(Vector<const char> string) { |
| 4348 Object* symbol = NULL; | 4356 Object* symbol = NULL; |
| 4349 Object* new_table; | 4357 Object* new_table; |
| 4350 { MaybeObject* maybe_new_table = | 4358 { MaybeObject* maybe_new_table = |
| 4351 symbol_table()->LookupSymbol(string, &symbol); | 4359 symbol_table()->LookupSymbol(string, &symbol); |
| 4352 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; | 4360 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; |
| 4353 } | 4361 } |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4818 *stats->lo_space_size = lo_space_->Size(); | 4826 *stats->lo_space_size = lo_space_->Size(); |
| 4819 isolate_->global_handles()->RecordStats(stats); | 4827 isolate_->global_handles()->RecordStats(stats); |
| 4820 *stats->memory_allocator_size = isolate()->memory_allocator()->Size(); | 4828 *stats->memory_allocator_size = isolate()->memory_allocator()->Size(); |
| 4821 *stats->memory_allocator_capacity = | 4829 *stats->memory_allocator_capacity = |
| 4822 isolate()->memory_allocator()->Size() + | 4830 isolate()->memory_allocator()->Size() + |
| 4823 isolate()->memory_allocator()->Available(); | 4831 isolate()->memory_allocator()->Available(); |
| 4824 *stats->os_error = OS::GetLastError(); | 4832 *stats->os_error = OS::GetLastError(); |
| 4825 isolate()->memory_allocator()->Available(); | 4833 isolate()->memory_allocator()->Available(); |
| 4826 if (take_snapshot) { | 4834 if (take_snapshot) { |
| 4827 HeapIterator iterator; | 4835 HeapIterator iterator; |
| 4828 for (HeapObject* obj = iterator.Next(); | 4836 for (HeapObject* obj = iterator.next(); |
| 4829 obj != NULL; | 4837 obj != NULL; |
| 4830 obj = iterator.Next()) { | 4838 obj = iterator.next()) { |
| 4831 InstanceType type = obj->map()->instance_type(); | 4839 InstanceType type = obj->map()->instance_type(); |
| 4832 ASSERT(0 <= type && type <= LAST_TYPE); | 4840 ASSERT(0 <= type && type <= LAST_TYPE); |
| 4833 stats->objects_per_type[type]++; | 4841 stats->objects_per_type[type]++; |
| 4834 stats->size_per_type[type] += obj->Size(); | 4842 stats->size_per_type[type] += obj->Size(); |
| 4835 } | 4843 } |
| 4836 } | 4844 } |
| 4837 } | 4845 } |
| 4838 | 4846 |
| 4839 | 4847 |
| 4840 intptr_t Heap::PromotedSpaceSize() { | 4848 intptr_t Heap::PromotedSpaceSize() { |
| (...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5457 HeapObject* obj = list_.RemoveLast(); | 5465 HeapObject* obj = list_.RemoveLast(); |
| 5458 obj->Iterate(this); | 5466 obj->Iterate(this); |
| 5459 } | 5467 } |
| 5460 | 5468 |
| 5461 private: | 5469 private: |
| 5462 List<HeapObject*> list_; | 5470 List<HeapObject*> list_; |
| 5463 }; | 5471 }; |
| 5464 | 5472 |
| 5465 void MarkUnreachableObjects() { | 5473 void MarkUnreachableObjects() { |
| 5466 HeapIterator iterator; | 5474 HeapIterator iterator; |
| 5467 for (HeapObject* obj = iterator.Next(); | 5475 for (HeapObject* obj = iterator.next(); |
| 5468 obj != NULL; | 5476 obj != NULL; |
| 5469 obj = iterator.Next()) { | 5477 obj = iterator.next()) { |
| 5470 IntrusiveMarking::SetMark(obj); | 5478 IntrusiveMarking::SetMark(obj); |
| 5471 } | 5479 } |
| 5472 UnmarkingVisitor visitor; | 5480 UnmarkingVisitor visitor; |
| 5473 HEAP->IterateRoots(&visitor, VISIT_ALL); | 5481 HEAP->IterateRoots(&visitor, VISIT_ALL); |
| 5474 while (visitor.can_process()) | 5482 while (visitor.can_process()) |
| 5475 visitor.ProcessNext(); | 5483 visitor.ProcessNext(); |
| 5476 } | 5484 } |
| 5477 | 5485 |
| 5478 AssertNoAllocation no_alloc; | 5486 AssertNoAllocation no_alloc; |
| 5479 }; | 5487 }; |
| 5480 | 5488 |
| 5481 | 5489 |
| 5482 HeapIterator::HeapIterator() { | 5490 HeapIterator::HeapIterator() |
| 5491 : filtering_(HeapIterator::kNoFiltering), |
| 5492 filter_(NULL) { |
| 5483 Init(); | 5493 Init(); |
| 5484 } | 5494 } |
| 5485 | 5495 |
| 5496 |
| 5497 HeapIterator::HeapIterator(HeapIterator::HeapObjectsFiltering filtering) |
| 5498 : filtering_(filtering), |
| 5499 filter_(NULL) { |
| 5500 Init(); |
| 5501 } |
| 5502 |
| 5486 | 5503 |
| 5487 HeapIterator::~HeapIterator() { | 5504 HeapIterator::~HeapIterator() { |
| 5488 Shutdown(); | 5505 Shutdown(); |
| 5489 } | 5506 } |
| 5490 | 5507 |
| 5491 | 5508 |
| 5492 void HeapIterator::Init() { | 5509 void HeapIterator::Init() { |
| 5493 // Start the iteration. | 5510 // Start the iteration. |
| 5494 HEAP->EnsureHeapIsIterable(); | 5511 space_iterator_ = filtering_ == kNoFiltering ? new SpaceIterator : |
| 5495 space_iterator_ = new SpaceIterator(); | 5512 new SpaceIterator(Isolate::Current()->heap()-> |
| 5513 GcSafeSizeOfOldObjectFunction()); |
| 5514 switch (filtering_) { |
| 5515 case kFilterFreeListNodes: |
| 5516 // TODO(gc): Not handled. |
| 5517 break; |
| 5518 case kFilterUnreachable: |
| 5519 filter_ = new UnreachableObjectsFilter; |
| 5520 break; |
| 5521 default: |
| 5522 break; |
| 5523 } |
| 5496 object_iterator_ = space_iterator_->next(); | 5524 object_iterator_ = space_iterator_->next(); |
| 5497 } | 5525 } |
| 5498 | 5526 |
| 5499 | 5527 |
| 5500 void HeapIterator::Shutdown() { | 5528 void HeapIterator::Shutdown() { |
| 5529 #ifdef DEBUG |
| 5530 // Assert that in filtering mode we have iterated through all |
| 5531 // objects. Otherwise, heap will be left in an inconsistent state. |
| 5532 if (filtering_ != kNoFiltering) { |
| 5533 ASSERT(object_iterator_ == NULL); |
| 5534 } |
| 5535 #endif |
| 5501 // Make sure the last iterator is deallocated. | 5536 // Make sure the last iterator is deallocated. |
| 5502 delete space_iterator_; | 5537 delete space_iterator_; |
| 5503 space_iterator_ = NULL; | 5538 space_iterator_ = NULL; |
| 5504 object_iterator_ = NULL; | 5539 object_iterator_ = NULL; |
| 5540 delete filter_; |
| 5541 filter_ = NULL; |
| 5505 } | 5542 } |
| 5506 | 5543 |
| 5507 | 5544 |
| 5508 HeapObject* HeapIterator::Next() { | 5545 HeapObject* HeapIterator::next() { |
| 5546 if (filter_ == NULL) return NextObject(); |
| 5547 |
| 5548 HeapObject* obj = NextObject(); |
| 5549 while (obj != NULL && filter_->SkipObject(obj)) obj = NextObject(); |
| 5550 return obj; |
| 5551 } |
| 5552 |
| 5553 |
| 5554 HeapObject* HeapIterator::NextObject() { |
| 5509 // No iterator means we are done. | 5555 // No iterator means we are done. |
| 5510 if (object_iterator_ == NULL) return NULL; | 5556 if (object_iterator_ == NULL) return NULL; |
| 5511 | 5557 |
| 5512 if (HeapObject* obj = object_iterator_->next_object()) { | 5558 if (HeapObject* obj = object_iterator_->next_object()) { |
| 5513 // If the current iterator has more objects we are fine. | 5559 // If the current iterator has more objects we are fine. |
| 5514 return obj; | 5560 return obj; |
| 5515 } else { | 5561 } else { |
| 5516 // Go though the spaces looking for one that has objects. | 5562 // Go though the spaces looking for one that has objects. |
| 5517 while (space_iterator_->has_next()) { | 5563 while (space_iterator_->has_next()) { |
| 5518 object_iterator_ = space_iterator_->next(); | 5564 object_iterator_ = space_iterator_->next(); |
| 5519 if (HeapObject* obj = object_iterator_->next_object()) { | 5565 if (HeapObject* obj = object_iterator_->next_object()) { |
| 5520 return obj; | 5566 return obj; |
| 5521 } | 5567 } |
| 5522 } | 5568 } |
| 5523 } | 5569 } |
| 5524 // Done with the last space. | 5570 // Done with the last space. |
| 5525 object_iterator_ = NULL; | 5571 object_iterator_ = NULL; |
| 5526 return NULL; | 5572 return NULL; |
| 5527 } | 5573 } |
| 5528 | 5574 |
| 5529 | 5575 |
| 5530 void HeapIterator::Reset() { | 5576 void HeapIterator::reset() { |
| 5531 // Restart the iterator. | 5577 // Restart the iterator. |
| 5532 Shutdown(); | 5578 Shutdown(); |
| 5533 Init(); | 5579 Init(); |
| 5534 } | 5580 } |
| 5535 | 5581 |
| 5536 | 5582 |
| 5537 #if defined(DEBUG) || defined(LIVE_OBJECT_LIST) | 5583 #if defined(DEBUG) || defined(LIVE_OBJECT_LIST) |
| 5538 | 5584 |
| 5539 Object* const PathTracer::kAnyGlobalObject = reinterpret_cast<Object*>(NULL); | 5585 Object* const PathTracer::kAnyGlobalObject = reinterpret_cast<Object*>(NULL); |
| 5540 | 5586 |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6024 } | 6070 } |
| 6025 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); | 6071 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); |
| 6026 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { | 6072 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |
| 6027 next = chunk->next_chunk(); | 6073 next = chunk->next_chunk(); |
| 6028 isolate_->memory_allocator()->Free(chunk); | 6074 isolate_->memory_allocator()->Free(chunk); |
| 6029 } | 6075 } |
| 6030 chunks_queued_for_free_ = NULL; | 6076 chunks_queued_for_free_ = NULL; |
| 6031 } | 6077 } |
| 6032 | 6078 |
| 6033 } } // namespace v8::internal | 6079 } } // namespace v8::internal |
| OLD | NEW |