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 |