| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/heap/heap.h" | 5 #include "src/heap/heap.h" |
| 6 | 6 |
| 7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
| 8 #include "src/api.h" | 8 #include "src/api.h" |
| 9 #include "src/ast/scopeinfo.h" | 9 #include "src/ast/scopeinfo.h" |
| 10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 108 remembered_unmapped_pages_index_(0), | 108 remembered_unmapped_pages_index_(0), |
| 109 #ifdef DEBUG | 109 #ifdef DEBUG |
| 110 allocation_timeout_(0), | 110 allocation_timeout_(0), |
| 111 #endif // DEBUG | 111 #endif // DEBUG |
| 112 old_generation_allocation_limit_(initial_old_generation_size_), | 112 old_generation_allocation_limit_(initial_old_generation_size_), |
| 113 old_gen_exhausted_(false), | 113 old_gen_exhausted_(false), |
| 114 optimize_for_memory_usage_(false), | 114 optimize_for_memory_usage_(false), |
| 115 inline_allocation_disabled_(false), | 115 inline_allocation_disabled_(false), |
| 116 total_regexp_code_generated_(0), | 116 total_regexp_code_generated_(0), |
| 117 tracer_(nullptr), | 117 tracer_(nullptr), |
| 118 embedder_heap_tracer_(nullptr), | |
| 119 high_survival_rate_period_length_(0), | 118 high_survival_rate_period_length_(0), |
| 120 promoted_objects_size_(0), | 119 promoted_objects_size_(0), |
| 121 promotion_ratio_(0), | 120 promotion_ratio_(0), |
| 122 semi_space_copied_object_size_(0), | 121 semi_space_copied_object_size_(0), |
| 123 previous_semi_space_copied_object_size_(0), | 122 previous_semi_space_copied_object_size_(0), |
| 124 semi_space_copied_rate_(0), | 123 semi_space_copied_rate_(0), |
| 125 nodes_died_in_new_space_(0), | 124 nodes_died_in_new_space_(0), |
| 126 nodes_copied_in_new_space_(0), | 125 nodes_copied_in_new_space_(0), |
| 127 nodes_promoted_(0), | 126 nodes_promoted_(0), |
| 128 maximum_size_scavenges_(0), | 127 maximum_size_scavenges_(0), |
| (...skipping 1418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1547 return heap->InNewSpace(*p) && | 1546 return heap->InNewSpace(*p) && |
| 1548 !HeapObject::cast(*p)->map_word().IsForwardingAddress(); | 1547 !HeapObject::cast(*p)->map_word().IsForwardingAddress(); |
| 1549 } | 1548 } |
| 1550 | 1549 |
| 1551 | 1550 |
| 1552 static bool IsUnmodifiedHeapObject(Object** p) { | 1551 static bool IsUnmodifiedHeapObject(Object** p) { |
| 1553 Object* object = *p; | 1552 Object* object = *p; |
| 1554 if (object->IsSmi()) return false; | 1553 if (object->IsSmi()) return false; |
| 1555 HeapObject* heap_object = HeapObject::cast(object); | 1554 HeapObject* heap_object = HeapObject::cast(object); |
| 1556 if (!object->IsJSObject()) return false; | 1555 if (!object->IsJSObject()) return false; |
| 1557 Object* obj_constructor = (JSObject::cast(object))->map()->GetConstructor(); | 1556 JSObject* js_object = JSObject::cast(object); |
| 1558 if (!obj_constructor->IsJSFunction()) return false; | 1557 if (!js_object->WasConstructedFromApiFunction()) return false; |
| 1559 JSFunction* constructor = JSFunction::cast(obj_constructor); | 1558 JSFunction* constructor = |
| 1560 if (!constructor->shared()->IsApiFunction()) return false; | 1559 JSFunction::cast(js_object->map()->GetConstructor()); |
| 1561 if (constructor != nullptr && | 1560 |
| 1562 constructor->initial_map() == heap_object->map()) { | 1561 return constructor->initial_map() == heap_object->map(); |
| 1563 return true; | |
| 1564 } | |
| 1565 return false; | |
| 1566 } | 1562 } |
| 1567 | 1563 |
| 1568 | 1564 |
| 1569 void PromotionQueue::Initialize() { | 1565 void PromotionQueue::Initialize() { |
| 1570 // The last to-space page may be used for promotion queue. On promotion | 1566 // The last to-space page may be used for promotion queue. On promotion |
| 1571 // conflict, we use the emergency stack. | 1567 // conflict, we use the emergency stack. |
| 1572 DCHECK((Page::kPageSize - MemoryChunk::kBodyOffset) % (2 * kPointerSize) == | 1568 DCHECK((Page::kPageSize - MemoryChunk::kBodyOffset) % (2 * kPointerSize) == |
| 1573 0); | 1569 0); |
| 1574 front_ = rear_ = | 1570 front_ = rear_ = |
| 1575 reinterpret_cast<struct Entry*>(heap_->new_space()->ToSpaceEnd()); | 1571 reinterpret_cast<struct Entry*>(heap_->new_space()->ToSpaceEnd()); |
| (...skipping 2006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3582 | 3578 |
| 3583 AllocationResult Heap::CopyJSObject(JSObject* source, AllocationSite* site) { | 3579 AllocationResult Heap::CopyJSObject(JSObject* source, AllocationSite* site) { |
| 3584 // Make the clone. | 3580 // Make the clone. |
| 3585 Map* map = source->map(); | 3581 Map* map = source->map(); |
| 3586 | 3582 |
| 3587 // We can only clone regexps, normal objects, api objects or arrays. Copying | 3583 // We can only clone regexps, normal objects, api objects or arrays. Copying |
| 3588 // anything else will break invariants. | 3584 // anything else will break invariants. |
| 3589 CHECK(map->instance_type() == JS_REGEXP_TYPE || | 3585 CHECK(map->instance_type() == JS_REGEXP_TYPE || |
| 3590 map->instance_type() == JS_OBJECT_TYPE || | 3586 map->instance_type() == JS_OBJECT_TYPE || |
| 3591 map->instance_type() == JS_ARRAY_TYPE || | 3587 map->instance_type() == JS_ARRAY_TYPE || |
| 3588 map->instance_type() == JS_API_OBJECT_TYPE || |
| 3592 map->instance_type() == JS_SPECIAL_API_OBJECT_TYPE); | 3589 map->instance_type() == JS_SPECIAL_API_OBJECT_TYPE); |
| 3593 | 3590 |
| 3594 int object_size = map->instance_size(); | 3591 int object_size = map->instance_size(); |
| 3595 HeapObject* clone = nullptr; | 3592 HeapObject* clone = nullptr; |
| 3596 | 3593 |
| 3597 DCHECK(site == NULL || AllocationSite::CanTrack(map->instance_type())); | 3594 DCHECK(site == NULL || AllocationSite::CanTrack(map->instance_type())); |
| 3598 | 3595 |
| 3599 int adjusted_object_size = | 3596 int adjusted_object_size = |
| 3600 site != NULL ? object_size + AllocationMemento::kSize : object_size; | 3597 site != NULL ? object_size + AllocationMemento::kSize : object_size; |
| 3601 AllocationResult allocation = AllocateRaw(adjusted_object_size, NEW_SPACE); | 3598 AllocationResult allocation = AllocateRaw(adjusted_object_size, NEW_SPACE); |
| (...skipping 1776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5378 #ifdef DEBUG | 5375 #ifdef DEBUG |
| 5379 // All pages right after bootstrapping must be marked as never-evacuate. | 5376 // All pages right after bootstrapping must be marked as never-evacuate. |
| 5380 PagedSpaces spaces(this); | 5377 PagedSpaces spaces(this); |
| 5381 for (PagedSpace* s = spaces.next(); s != NULL; s = spaces.next()) { | 5378 for (PagedSpace* s = spaces.next(); s != NULL; s = spaces.next()) { |
| 5382 PageIterator it(s); | 5379 PageIterator it(s); |
| 5383 while (it.has_next()) CHECK(it.next()->NeverEvacuate()); | 5380 while (it.has_next()) CHECK(it.next()->NeverEvacuate()); |
| 5384 } | 5381 } |
| 5385 #endif // DEBUG | 5382 #endif // DEBUG |
| 5386 } | 5383 } |
| 5387 | 5384 |
| 5385 void Heap::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) { |
| 5386 mark_compact_collector()->SetEmbedderHeapTracer(tracer); |
| 5387 } |
| 5388 |
| 5389 bool Heap::UsingEmbedderHeapTracer() { |
| 5390 return mark_compact_collector()->embedder_heap_tracer(); |
| 5391 } |
| 5392 |
| 5393 void Heap::TracePossibleWrapper(JSObject* js_object) { |
| 5394 DCHECK(js_object->WasConstructedFromApiFunction()); |
| 5395 if (js_object->GetInternalFieldCount() >= 2 && |
| 5396 js_object->GetInternalField(0) != undefined_value() && |
| 5397 js_object->GetInternalField(1) != undefined_value()) { |
| 5398 mark_compact_collector()->wrappers_to_trace().push_back( |
| 5399 std::pair<void*, void*>( |
| 5400 reinterpret_cast<void*>(js_object->GetInternalField(0)), |
| 5401 reinterpret_cast<void*>(js_object->GetInternalField(1)))); |
| 5402 } |
| 5403 } |
| 5404 |
| 5388 void Heap::RegisterExternallyReferencedObject(Object** object) { | 5405 void Heap::RegisterExternallyReferencedObject(Object** object) { |
| 5389 DCHECK(mark_compact_collector()->in_use()); | 5406 DCHECK(mark_compact_collector()->in_use()); |
| 5390 HeapObject* heap_object = HeapObject::cast(*object); | 5407 HeapObject* heap_object = HeapObject::cast(*object); |
| 5391 DCHECK(Contains(heap_object)); | 5408 DCHECK(Contains(heap_object)); |
| 5392 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); | 5409 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); |
| 5393 mark_compact_collector()->MarkObject(heap_object, mark_bit); | 5410 mark_compact_collector()->MarkObject(heap_object, mark_bit); |
| 5394 } | 5411 } |
| 5395 | 5412 |
| 5396 void Heap::TearDown() { | 5413 void Heap::TearDown() { |
| 5397 #ifdef VERIFY_HEAP | 5414 #ifdef VERIFY_HEAP |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5553 DCHECK(callback != NULL); | 5570 DCHECK(callback != NULL); |
| 5554 for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { | 5571 for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { |
| 5555 if (gc_epilogue_callbacks_[i].callback == callback) { | 5572 if (gc_epilogue_callbacks_[i].callback == callback) { |
| 5556 gc_epilogue_callbacks_.Remove(i); | 5573 gc_epilogue_callbacks_.Remove(i); |
| 5557 return; | 5574 return; |
| 5558 } | 5575 } |
| 5559 } | 5576 } |
| 5560 UNREACHABLE(); | 5577 UNREACHABLE(); |
| 5561 } | 5578 } |
| 5562 | 5579 |
| 5563 void Heap::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) { | |
| 5564 DCHECK_NOT_NULL(tracer); | |
| 5565 CHECK_NULL(embedder_heap_tracer_); | |
| 5566 embedder_heap_tracer_ = tracer; | |
| 5567 } | |
| 5568 | |
| 5569 // TODO(ishell): Find a better place for this. | 5580 // TODO(ishell): Find a better place for this. |
| 5570 void Heap::AddWeakObjectToCodeDependency(Handle<HeapObject> obj, | 5581 void Heap::AddWeakObjectToCodeDependency(Handle<HeapObject> obj, |
| 5571 Handle<DependentCode> dep) { | 5582 Handle<DependentCode> dep) { |
| 5572 DCHECK(!InNewSpace(*obj)); | 5583 DCHECK(!InNewSpace(*obj)); |
| 5573 DCHECK(!InNewSpace(*dep)); | 5584 DCHECK(!InNewSpace(*dep)); |
| 5574 Handle<WeakHashTable> table(weak_object_to_code_table(), isolate()); | 5585 Handle<WeakHashTable> table(weak_object_to_code_table(), isolate()); |
| 5575 table = WeakHashTable::Put(table, obj, dep); | 5586 table = WeakHashTable::Put(table, obj, dep); |
| 5576 if (*table != weak_object_to_code_table()) | 5587 if (*table != weak_object_to_code_table()) |
| 5577 set_weak_object_to_code_table(*table); | 5588 set_weak_object_to_code_table(*table); |
| 5578 DCHECK_EQ(*dep, LookupWeakObjectToCodeDependency(obj)); | 5589 DCHECK_EQ(*dep, LookupWeakObjectToCodeDependency(obj)); |
| (...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6453 } | 6464 } |
| 6454 | 6465 |
| 6455 | 6466 |
| 6456 // static | 6467 // static |
| 6457 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6468 int Heap::GetStaticVisitorIdForMap(Map* map) { |
| 6458 return StaticVisitorBase::GetVisitorId(map); | 6469 return StaticVisitorBase::GetVisitorId(map); |
| 6459 } | 6470 } |
| 6460 | 6471 |
| 6461 } // namespace internal | 6472 } // namespace internal |
| 6462 } // namespace v8 | 6473 } // namespace v8 |
| OLD | NEW |