| 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 |