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 1760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5362 #ifdef DEBUG | 5360 #ifdef DEBUG |
5363 // All pages right after bootstrapping must be marked as never-evacuate. | 5361 // All pages right after bootstrapping must be marked as never-evacuate. |
5364 PagedSpaces spaces(this); | 5362 PagedSpaces spaces(this); |
5365 for (PagedSpace* s = spaces.next(); s != NULL; s = spaces.next()) { | 5363 for (PagedSpace* s = spaces.next(); s != NULL; s = spaces.next()) { |
5366 PageIterator it(s); | 5364 PageIterator it(s); |
5367 while (it.has_next()) CHECK(it.next()->NeverEvacuate()); | 5365 while (it.has_next()) CHECK(it.next()->NeverEvacuate()); |
5368 } | 5366 } |
5369 #endif // DEBUG | 5367 #endif // DEBUG |
5370 } | 5368 } |
5371 | 5369 |
| 5370 void Heap::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) { |
| 5371 DCHECK_NOT_NULL(tracer); |
| 5372 CHECK_NULL(embedder_heap_tracer_); |
| 5373 embedder_heap_tracer_ = tracer; |
| 5374 } |
| 5375 |
| 5376 void Heap::TracePossibleWrapper(JSObject* js_object) { |
| 5377 DCHECK(js_object->WasConstructedFromApiFunction()); |
| 5378 if (js_object->GetInternalFieldCount() >= 2 && |
| 5379 js_object->GetInternalField(0) != undefined_value() && |
| 5380 js_object->GetInternalField(1) != undefined_value()) { |
| 5381 mark_compact_collector()->wrappers_to_trace().push_back( |
| 5382 std::pair<Data*, Data*>( |
| 5383 reinterpret_cast<Data*>(js_object->GetInternalField(0)), |
| 5384 reinterpret_cast<Data*>(js_object->GetInternalField(1)))); |
| 5385 } |
| 5386 } |
| 5387 |
5372 void Heap::RegisterExternallyReferencedObject(Object** object) { | 5388 void Heap::RegisterExternallyReferencedObject(Object** object) { |
5373 DCHECK(mark_compact_collector()->in_use()); | 5389 DCHECK(mark_compact_collector()->in_use()); |
5374 HeapObject* heap_object = HeapObject::cast(*object); | 5390 HeapObject* heap_object = HeapObject::cast(*object); |
5375 DCHECK(Contains(heap_object)); | 5391 DCHECK(Contains(heap_object)); |
5376 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); | 5392 MarkBit mark_bit = Marking::MarkBitFrom(heap_object); |
5377 mark_compact_collector()->MarkObject(heap_object, mark_bit); | 5393 mark_compact_collector()->MarkObject(heap_object, mark_bit); |
5378 } | 5394 } |
5379 | 5395 |
5380 void Heap::TearDown() { | 5396 void Heap::TearDown() { |
5381 #ifdef VERIFY_HEAP | 5397 #ifdef VERIFY_HEAP |
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5537 DCHECK(callback != NULL); | 5553 DCHECK(callback != NULL); |
5538 for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { | 5554 for (int i = 0; i < gc_epilogue_callbacks_.length(); ++i) { |
5539 if (gc_epilogue_callbacks_[i].callback == callback) { | 5555 if (gc_epilogue_callbacks_[i].callback == callback) { |
5540 gc_epilogue_callbacks_.Remove(i); | 5556 gc_epilogue_callbacks_.Remove(i); |
5541 return; | 5557 return; |
5542 } | 5558 } |
5543 } | 5559 } |
5544 UNREACHABLE(); | 5560 UNREACHABLE(); |
5545 } | 5561 } |
5546 | 5562 |
5547 void Heap::SetEmbedderHeapTracer(EmbedderHeapTracer* tracer) { | |
5548 DCHECK_NOT_NULL(tracer); | |
5549 CHECK_NULL(embedder_heap_tracer_); | |
5550 embedder_heap_tracer_ = tracer; | |
5551 } | |
5552 | |
5553 // TODO(ishell): Find a better place for this. | 5563 // TODO(ishell): Find a better place for this. |
5554 void Heap::AddWeakObjectToCodeDependency(Handle<HeapObject> obj, | 5564 void Heap::AddWeakObjectToCodeDependency(Handle<HeapObject> obj, |
5555 Handle<DependentCode> dep) { | 5565 Handle<DependentCode> dep) { |
5556 DCHECK(!InNewSpace(*obj)); | 5566 DCHECK(!InNewSpace(*obj)); |
5557 DCHECK(!InNewSpace(*dep)); | 5567 DCHECK(!InNewSpace(*dep)); |
5558 Handle<WeakHashTable> table(weak_object_to_code_table(), isolate()); | 5568 Handle<WeakHashTable> table(weak_object_to_code_table(), isolate()); |
5559 table = WeakHashTable::Put(table, obj, dep); | 5569 table = WeakHashTable::Put(table, obj, dep); |
5560 if (*table != weak_object_to_code_table()) | 5570 if (*table != weak_object_to_code_table()) |
5561 set_weak_object_to_code_table(*table); | 5571 set_weak_object_to_code_table(*table); |
5562 DCHECK_EQ(*dep, LookupWeakObjectToCodeDependency(obj)); | 5572 DCHECK_EQ(*dep, LookupWeakObjectToCodeDependency(obj)); |
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6437 } | 6447 } |
6438 | 6448 |
6439 | 6449 |
6440 // static | 6450 // static |
6441 int Heap::GetStaticVisitorIdForMap(Map* map) { | 6451 int Heap::GetStaticVisitorIdForMap(Map* map) { |
6442 return StaticVisitorBase::GetVisitorId(map); | 6452 return StaticVisitorBase::GetVisitorId(map); |
6443 } | 6453 } |
6444 | 6454 |
6445 } // namespace internal | 6455 } // namespace internal |
6446 } // namespace v8 | 6456 } // namespace v8 |
OLD | NEW |