| 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 4096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4334 old_pointer_space_->Verify(&visitor); | 4337 old_pointer_space_->Verify(&visitor); |
| 4335 map_space_->Verify(&visitor); | 4338 map_space_->Verify(&visitor); |
| 4336 | 4339 |
| 4337 VerifyPointersVisitor no_dirty_regions_visitor; | 4340 VerifyPointersVisitor no_dirty_regions_visitor; |
| 4338 old_data_space_->Verify(&no_dirty_regions_visitor); | 4341 old_data_space_->Verify(&no_dirty_regions_visitor); |
| 4339 code_space_->Verify(&no_dirty_regions_visitor); | 4342 code_space_->Verify(&no_dirty_regions_visitor); |
| 4340 cell_space_->Verify(&no_dirty_regions_visitor); | 4343 cell_space_->Verify(&no_dirty_regions_visitor); |
| 4341 | 4344 |
| 4342 lo_space_->Verify(); | 4345 lo_space_->Verify(); |
| 4343 } | 4346 } |
| 4347 |
| 4344 #endif // DEBUG | 4348 #endif // DEBUG |
| 4345 | 4349 |
| 4346 | 4350 |
| 4347 MaybeObject* Heap::LookupSymbol(Vector<const char> string) { | 4351 MaybeObject* Heap::LookupSymbol(Vector<const char> string) { |
| 4348 Object* symbol = NULL; | 4352 Object* symbol = NULL; |
| 4349 Object* new_table; | 4353 Object* new_table; |
| 4350 { MaybeObject* maybe_new_table = | 4354 { MaybeObject* maybe_new_table = |
| 4351 symbol_table()->LookupSymbol(string, &symbol); | 4355 symbol_table()->LookupSymbol(string, &symbol); |
| 4352 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; | 4356 if (!maybe_new_table->ToObject(&new_table)) return maybe_new_table; |
| 4353 } | 4357 } |
| (...skipping 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4818 *stats->lo_space_size = lo_space_->Size(); | 4822 *stats->lo_space_size = lo_space_->Size(); |
| 4819 isolate_->global_handles()->RecordStats(stats); | 4823 isolate_->global_handles()->RecordStats(stats); |
| 4820 *stats->memory_allocator_size = isolate()->memory_allocator()->Size(); | 4824 *stats->memory_allocator_size = isolate()->memory_allocator()->Size(); |
| 4821 *stats->memory_allocator_capacity = | 4825 *stats->memory_allocator_capacity = |
| 4822 isolate()->memory_allocator()->Size() + | 4826 isolate()->memory_allocator()->Size() + |
| 4823 isolate()->memory_allocator()->Available(); | 4827 isolate()->memory_allocator()->Available(); |
| 4824 *stats->os_error = OS::GetLastError(); | 4828 *stats->os_error = OS::GetLastError(); |
| 4825 isolate()->memory_allocator()->Available(); | 4829 isolate()->memory_allocator()->Available(); |
| 4826 if (take_snapshot) { | 4830 if (take_snapshot) { |
| 4827 HeapIterator iterator; | 4831 HeapIterator iterator; |
| 4828 for (HeapObject* obj = iterator.Next(); | 4832 for (HeapObject* obj = iterator.next(); |
| 4829 obj != NULL; | 4833 obj != NULL; |
| 4830 obj = iterator.Next()) { | 4834 obj = iterator.next()) { |
| 4831 InstanceType type = obj->map()->instance_type(); | 4835 InstanceType type = obj->map()->instance_type(); |
| 4832 ASSERT(0 <= type && type <= LAST_TYPE); | 4836 ASSERT(0 <= type && type <= LAST_TYPE); |
| 4833 stats->objects_per_type[type]++; | 4837 stats->objects_per_type[type]++; |
| 4834 stats->size_per_type[type] += obj->Size(); | 4838 stats->size_per_type[type] += obj->Size(); |
| 4835 } | 4839 } |
| 4836 } | 4840 } |
| 4837 } | 4841 } |
| 4838 | 4842 |
| 4839 | 4843 |
| 4840 intptr_t Heap::PromotedSpaceSize() { | 4844 intptr_t Heap::PromotedSpaceSize() { |
| (...skipping 616 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5457 HeapObject* obj = list_.RemoveLast(); | 5461 HeapObject* obj = list_.RemoveLast(); |
| 5458 obj->Iterate(this); | 5462 obj->Iterate(this); |
| 5459 } | 5463 } |
| 5460 | 5464 |
| 5461 private: | 5465 private: |
| 5462 List<HeapObject*> list_; | 5466 List<HeapObject*> list_; |
| 5463 }; | 5467 }; |
| 5464 | 5468 |
| 5465 void MarkUnreachableObjects() { | 5469 void MarkUnreachableObjects() { |
| 5466 HeapIterator iterator; | 5470 HeapIterator iterator; |
| 5467 for (HeapObject* obj = iterator.Next(); | 5471 for (HeapObject* obj = iterator.next(); |
| 5468 obj != NULL; | 5472 obj != NULL; |
| 5469 obj = iterator.Next()) { | 5473 obj = iterator.next()) { |
| 5470 IntrusiveMarking::SetMark(obj); | 5474 IntrusiveMarking::SetMark(obj); |
| 5471 } | 5475 } |
| 5472 UnmarkingVisitor visitor; | 5476 UnmarkingVisitor visitor; |
| 5473 HEAP->IterateRoots(&visitor, VISIT_ALL); | 5477 HEAP->IterateRoots(&visitor, VISIT_ALL); |
| 5474 while (visitor.can_process()) | 5478 while (visitor.can_process()) |
| 5475 visitor.ProcessNext(); | 5479 visitor.ProcessNext(); |
| 5476 } | 5480 } |
| 5477 | 5481 |
| 5478 AssertNoAllocation no_alloc; | 5482 AssertNoAllocation no_alloc; |
| 5479 }; | 5483 }; |
| 5480 | 5484 |
| 5481 | 5485 |
| 5482 HeapIterator::HeapIterator() { | 5486 HeapIterator::HeapIterator() |
| 5487 : filtering_(HeapIterator::kNoFiltering), |
| 5488 filter_(NULL) { |
| 5483 Init(); | 5489 Init(); |
| 5484 } | 5490 } |
| 5485 | 5491 |
| 5492 |
| 5493 HeapIterator::HeapIterator(HeapIterator::HeapObjectsFiltering filtering) |
| 5494 : filtering_(filtering), |
| 5495 filter_(NULL) { |
| 5496 Init(); |
| 5497 } |
| 5498 |
| 5486 | 5499 |
| 5487 HeapIterator::~HeapIterator() { | 5500 HeapIterator::~HeapIterator() { |
| 5488 Shutdown(); | 5501 Shutdown(); |
| 5489 } | 5502 } |
| 5490 | 5503 |
| 5491 | 5504 |
| 5492 void HeapIterator::Init() { | 5505 void HeapIterator::Init() { |
| 5493 // Start the iteration. | 5506 // Start the iteration. |
| 5494 HEAP->EnsureHeapIsIterable(); | 5507 space_iterator_ = filtering_ == kNoFiltering ? new SpaceIterator : |
| 5495 space_iterator_ = new SpaceIterator(); | 5508 new SpaceIterator(Isolate::Current()->heap()-> |
| 5509 GcSafeSizeOfOldObjectFunction()); |
| 5510 switch (filtering_) { |
| 5511 case kFilterFreeListNodes: |
| 5512 // TODO(gc): Not handled. |
| 5513 break; |
| 5514 case kFilterUnreachable: |
| 5515 filter_ = new UnreachableObjectsFilter; |
| 5516 break; |
| 5517 default: |
| 5518 break; |
| 5519 } |
| 5496 object_iterator_ = space_iterator_->next(); | 5520 object_iterator_ = space_iterator_->next(); |
| 5497 } | 5521 } |
| 5498 | 5522 |
| 5499 | 5523 |
| 5500 void HeapIterator::Shutdown() { | 5524 void HeapIterator::Shutdown() { |
| 5525 #ifdef DEBUG |
| 5526 // Assert that in filtering mode we have iterated through all |
| 5527 // objects. Otherwise, heap will be left in an inconsistent state. |
| 5528 if (filtering_ != kNoFiltering) { |
| 5529 ASSERT(object_iterator_ == NULL); |
| 5530 } |
| 5531 #endif |
| 5501 // Make sure the last iterator is deallocated. | 5532 // Make sure the last iterator is deallocated. |
| 5502 delete space_iterator_; | 5533 delete space_iterator_; |
| 5503 space_iterator_ = NULL; | 5534 space_iterator_ = NULL; |
| 5504 object_iterator_ = NULL; | 5535 object_iterator_ = NULL; |
| 5536 delete filter_; |
| 5537 filter_ = NULL; |
| 5505 } | 5538 } |
| 5506 | 5539 |
| 5507 | 5540 |
| 5508 HeapObject* HeapIterator::Next() { | 5541 HeapObject* HeapIterator::next() { |
| 5542 if (filter_ == NULL) return NextObject(); |
| 5543 |
| 5544 HeapObject* obj = NextObject(); |
| 5545 while (obj != NULL && filter_->SkipObject(obj)) obj = NextObject(); |
| 5546 return obj; |
| 5547 } |
| 5548 |
| 5549 |
| 5550 HeapObject* HeapIterator::NextObject() { |
| 5509 // No iterator means we are done. | 5551 // No iterator means we are done. |
| 5510 if (object_iterator_ == NULL) return NULL; | 5552 if (object_iterator_ == NULL) return NULL; |
| 5511 | 5553 |
| 5512 if (HeapObject* obj = object_iterator_->next_object()) { | 5554 if (HeapObject* obj = object_iterator_->next_object()) { |
| 5513 // If the current iterator has more objects we are fine. | 5555 // If the current iterator has more objects we are fine. |
| 5514 return obj; | 5556 return obj; |
| 5515 } else { | 5557 } else { |
| 5516 // Go though the spaces looking for one that has objects. | 5558 // Go though the spaces looking for one that has objects. |
| 5517 while (space_iterator_->has_next()) { | 5559 while (space_iterator_->has_next()) { |
| 5518 object_iterator_ = space_iterator_->next(); | 5560 object_iterator_ = space_iterator_->next(); |
| 5519 if (HeapObject* obj = object_iterator_->next_object()) { | 5561 if (HeapObject* obj = object_iterator_->next_object()) { |
| 5520 return obj; | 5562 return obj; |
| 5521 } | 5563 } |
| 5522 } | 5564 } |
| 5523 } | 5565 } |
| 5524 // Done with the last space. | 5566 // Done with the last space. |
| 5525 object_iterator_ = NULL; | 5567 object_iterator_ = NULL; |
| 5526 return NULL; | 5568 return NULL; |
| 5527 } | 5569 } |
| 5528 | 5570 |
| 5529 | 5571 |
| 5530 void HeapIterator::Reset() { | 5572 void HeapIterator::reset() { |
| 5531 // Restart the iterator. | 5573 // Restart the iterator. |
| 5532 Shutdown(); | 5574 Shutdown(); |
| 5533 Init(); | 5575 Init(); |
| 5534 } | 5576 } |
| 5535 | 5577 |
| 5536 | 5578 |
| 5537 #if defined(DEBUG) || defined(LIVE_OBJECT_LIST) | 5579 #if defined(DEBUG) || defined(LIVE_OBJECT_LIST) |
| 5538 | 5580 |
| 5539 Object* const PathTracer::kAnyGlobalObject = reinterpret_cast<Object*>(NULL); | 5581 Object* const PathTracer::kAnyGlobalObject = reinterpret_cast<Object*>(NULL); |
| 5540 | 5582 |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6024 } | 6066 } |
| 6025 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); | 6067 isolate_->heap()->store_buffer()->Filter(MemoryChunk::ABOUT_TO_BE_FREED); |
| 6026 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { | 6068 for (chunk = chunks_queued_for_free_; chunk != NULL; chunk = next) { |
| 6027 next = chunk->next_chunk(); | 6069 next = chunk->next_chunk(); |
| 6028 isolate_->memory_allocator()->Free(chunk); | 6070 isolate_->memory_allocator()->Free(chunk); |
| 6029 } | 6071 } |
| 6030 chunks_queued_for_free_ = NULL; | 6072 chunks_queued_for_free_ = NULL; |
| 6031 } | 6073 } |
| 6032 | 6074 |
| 6033 } } // namespace v8::internal | 6075 } } // namespace v8::internal |
| OLD | NEW |