| 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 1536 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1547 return heap->InNewSpace(*p) && | 1547 return heap->InNewSpace(*p) && |
| 1548 !HeapObject::cast(*p)->map_word().IsForwardingAddress(); | 1548 !HeapObject::cast(*p)->map_word().IsForwardingAddress(); |
| 1549 } | 1549 } |
| 1550 | 1550 |
| 1551 | 1551 |
| 1552 static bool IsUnmodifiedHeapObject(Object** p) { | 1552 static bool IsUnmodifiedHeapObject(Object** p) { |
| 1553 Object* object = *p; | 1553 Object* object = *p; |
| 1554 if (object->IsSmi()) return false; | 1554 if (object->IsSmi()) return false; |
| 1555 HeapObject* heap_object = HeapObject::cast(object); | 1555 HeapObject* heap_object = HeapObject::cast(object); |
| 1556 if (!object->IsJSObject()) return false; | 1556 if (!object->IsJSObject()) return false; |
| 1557 Object* obj_constructor = (JSObject::cast(object))->map()->GetConstructor(); | 1557 JSObject* js_object = JSObject::cast(object); |
| 1558 if (!obj_constructor->IsJSFunction()) return false; | 1558 if (!js_object->WasConstructedFromApiFunction()) return false; |
| 1559 JSFunction* constructor = JSFunction::cast(obj_constructor); | 1559 JSFunction* constructor = |
| 1560 if (!constructor->shared()->IsApiFunction()) return false; | 1560 JSFunction::cast(js_object->map()->GetConstructor()); |
| 1561 if (constructor != nullptr && | 1561 |
| 1562 constructor->initial_map() == heap_object->map()) { | 1562 return constructor->initial_map() == heap_object->map(); |
| 1563 return true; | |
| 1564 } | |
| 1565 return false; | |
| 1566 } | 1563 } |
| 1567 | 1564 |
| 1568 | 1565 |
| 1569 void PromotionQueue::Initialize() { | 1566 void PromotionQueue::Initialize() { |
| 1570 // The last to-space page may be used for promotion queue. On promotion | 1567 // The last to-space page may be used for promotion queue. On promotion |
| 1571 // conflict, we use the emergency stack. | 1568 // conflict, we use the emergency stack. |
| 1572 DCHECK((Page::kPageSize - MemoryChunk::kBodyOffset) % (2 * kPointerSize) == | 1569 DCHECK((Page::kPageSize - MemoryChunk::kBodyOffset) % (2 * kPointerSize) == |
| 1573 0); | 1570 0); |
| 1574 front_ = rear_ = | 1571 front_ = rear_ = |
| 1575 reinterpret_cast<struct Entry*>(heap_->new_space()->ToSpaceEnd()); | 1572 reinterpret_cast<struct Entry*>(heap_->new_space()->ToSpaceEnd()); |
| (...skipping 2006 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3582 | 3579 |
| 3583 AllocationResult Heap::CopyJSObject(JSObject* source, AllocationSite* site) { | 3580 AllocationResult Heap::CopyJSObject(JSObject* source, AllocationSite* site) { |
| 3584 // Make the clone. | 3581 // Make the clone. |
| 3585 Map* map = source->map(); | 3582 Map* map = source->map(); |
| 3586 | 3583 |
| 3587 // We can only clone regexps, normal objects, api objects or arrays. Copying | 3584 // We can only clone regexps, normal objects, api objects or arrays. Copying |
| 3588 // anything else will break invariants. | 3585 // anything else will break invariants. |
| 3589 CHECK(map->instance_type() == JS_REGEXP_TYPE || | 3586 CHECK(map->instance_type() == JS_REGEXP_TYPE || |
| 3590 map->instance_type() == JS_OBJECT_TYPE || | 3587 map->instance_type() == JS_OBJECT_TYPE || |
| 3591 map->instance_type() == JS_ARRAY_TYPE || | 3588 map->instance_type() == JS_ARRAY_TYPE || |
| 3589 map->instance_type() == JS_API_OBJECT_TYPE || |
| 3592 map->instance_type() == JS_SPECIAL_API_OBJECT_TYPE); | 3590 map->instance_type() == JS_SPECIAL_API_OBJECT_TYPE); |
| 3593 | 3591 |
| 3594 int object_size = map->instance_size(); | 3592 int object_size = map->instance_size(); |
| 3595 HeapObject* clone = nullptr; | 3593 HeapObject* clone = nullptr; |
| 3596 | 3594 |
| 3597 DCHECK(site == NULL || AllocationSite::CanTrack(map->instance_type())); | 3595 DCHECK(site == NULL || AllocationSite::CanTrack(map->instance_type())); |
| 3598 | 3596 |
| 3599 int adjusted_object_size = | 3597 int adjusted_object_size = |
| 3600 site != NULL ? object_size + AllocationMemento::kSize : object_size; | 3598 site != NULL ? object_size + AllocationMemento::kSize : object_size; |
| 3601 AllocationResult allocation = AllocateRaw(adjusted_object_size, NEW_SPACE); | 3599 AllocationResult allocation = AllocateRaw(adjusted_object_size, NEW_SPACE); |
| (...skipping 1776 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5378 #ifdef DEBUG | 5376 #ifdef DEBUG |
| 5379 // All pages right after bootstrapping must be marked as never-evacuate. | 5377 // All pages right after bootstrapping must be marked as never-evacuate. |
| 5380 PagedSpaces spaces(this); | 5378 PagedSpaces spaces(this); |
| 5381 for (PagedSpace* s = spaces.next(); s != NULL; s = spaces.next()) { | 5379 for (PagedSpace* s = spaces.next(); s != NULL; s = spaces.next()) { |
| 5382 PageIterator it(s); | 5380 PageIterator it(s); |
| 5383 while (it.has_next()) CHECK(it.next()->NeverEvacuate()); | 5381 while (it.has_next()) CHECK(it.next()->NeverEvacuate()); |
| 5384 } | 5382 } |
| 5385 #endif // DEBUG | 5383 #endif // DEBUG |
| 5386 } | 5384 } |
| 5387 | 5385 |
| 5386 void Heap::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) { |
| 5387 DCHECK_NOT_NULL(tracer); |
| 5388 CHECK_NULL(embedder_heap_tracer_); |
| 5389 embedder_heap_tracer_ = tracer; |
| 5390 } |
| 5391 |
| 5392 void Heap::TracePossibleWrapper(JSObject* js_object) { |
| 5393 DCHECK(js_object->WasConstructedFromApiFunction()); |
| 5394 if (js_object->GetInternalFieldCount() >= 2 && |
| 5395 js_object->GetInternalField(0) != undefined_value() && |
| 5396 js_object->GetInternalField(1) != undefined_value()) { |
| 5397 mark_compact_collector()->wrappers_to_trace().push_back( |
| 5398 std::pair<Value*, Value*>( |
| 5399 reinterpret_cast<Value*>(js_object->GetInternalField(0)), |
| 5400 reinterpret_cast<Value*>(js_object->GetInternalField(1)))); |
| 5401 } |
| 5402 } |
| 5403 |
| 5388 void Heap::RegisterExternallyReferencedObject(Object** object) { | 5404 void Heap::RegisterExternallyReferencedObject(Object** object) { |
| 5389 DCHECK(mark_compact_collector()->in_use()); | 5405 DCHECK(mark_compact_collector()->in_use()); |
| 5390 HeapObject* heap_object = HeapObject::cast(*object); | 5406 HeapObject* heap_object = HeapObject::cast(*object); |
| 5391 DCHECK(Contains(heap_object)); | 5407 DCHECK(Contains(heap_object)); |
| 5392 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); | 5408 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); |
| 5393 mark_compact_collector()->MarkObject(heap_object, mark_bit); | 5409 mark_compact_collector()->MarkObject(heap_object, mark_bit); |
| 5394 } | 5410 } |
| 5395 | 5411 |
| 5396 void Heap::TearDown() { | 5412 void Heap::TearDown() { |
| 5397 #ifdef VERIFY_HEAP | 5413 #ifdef VERIFY_HEAP |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5553 DCHECK(callback != NULL); | 5569 DCHECK(callback != NULL); |
| 5554 for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { | 5570 for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { |
| 5555 if (gc_epilogue_callbacks_[i].callback == callback) { | 5571 if (gc_epilogue_callbacks_[i].callback == callback) { |
| 5556 gc_epilogue_callbacks_.Remove(i); | 5572 gc_epilogue_callbacks_.Remove(i); |
| 5557 return; | 5573 return; |
| 5558 } | 5574 } |
| 5559 } | 5575 } |
| 5560 UNREACHABLE(); | 5576 UNREACHABLE(); |
| 5561 } | 5577 } |
| 5562 | 5578 |
| 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. | 5579 // TODO(ishell): Find a better place for this. |
| 5570 void Heap::AddWeakObjectToCodeDependency(Handle<HeapObject> obj, | 5580 void Heap::AddWeakObjectToCodeDependency(Handle<HeapObject> obj, |
| 5571 Handle<DependentCode> dep) { | 5581 Handle<DependentCode> dep) { |
| 5572 DCHECK(!InNewSpace(*obj)); | 5582 DCHECK(!InNewSpace(*obj)); |
| 5573 DCHECK(!InNewSpace(*dep)); | 5583 DCHECK(!InNewSpace(*dep)); |
| 5574 Handle<WeakHashTable> table(weak_object_to_code_table(), isolate()); | 5584 Handle<WeakHashTable> table(weak_object_to_code_table(), isolate()); |
| 5575 table = WeakHashTable::Put(table, obj, dep); | 5585 table = WeakHashTable::Put(table, obj, dep); |
| 5576 if (*table != weak_object_to_code_table()) | 5586 if (*table != weak_object_to_code_table()) |
| 5577 set_weak_object_to_code_table(*table); | 5587 set_weak_object_to_code_table(*table); |
| 5578 DCHECK_EQ(*dep, LookupWeakObjectToCodeDependency(obj)); | 5588 DCHECK_EQ(*dep, LookupWeakObjectToCodeDependency(obj)); |
| (...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6453 } | 6463 } |
| 6454 | 6464 |
| 6455 | 6465 |
| 6456 // static | 6466 // static |
| 6457 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6467 int Heap::GetStaticVisitorIdForMap(Map* map) { |
| 6458 return StaticVisitorBase::GetVisitorId(map); | 6468 return StaticVisitorBase::GetVisitorId(map); |
| 6459 } | 6469 } |
| 6460 | 6470 |
| 6461 } // namespace internal | 6471 } // namespace internal |
| 6462 } // namespace v8 | 6472 } // namespace v8 |
| OLD | NEW |