| 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 #ifndef V8_OBJECTS_VISITING_INL_H_ | 5 #ifndef V8_OBJECTS_VISITING_INL_H_ |
| 6 #define V8_OBJECTS_VISITING_INL_H_ | 6 #define V8_OBJECTS_VISITING_INL_H_ |
| 7 | 7 |
| 8 #include "src/heap/objects-visiting.h" | 8 #include "src/heap/objects-visiting.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 76 kVisitStructGeneric>(); | 76 kVisitStructGeneric>(); |
| 77 } | 77 } |
| 78 | 78 |
| 79 | 79 |
| 80 template <typename StaticVisitor> | 80 template <typename StaticVisitor> |
| 81 int StaticNewSpaceVisitor<StaticVisitor>::VisitJSArrayBuffer( | 81 int StaticNewSpaceVisitor<StaticVisitor>::VisitJSArrayBuffer( |
| 82 Map* map, HeapObject* object) { | 82 Map* map, HeapObject* object) { |
| 83 Heap* heap = map->GetHeap(); | 83 Heap* heap = map->GetHeap(); |
| 84 | 84 |
| 85 VisitPointers( | 85 VisitPointers( |
| 86 heap, | 86 heap, object, |
| 87 HeapObject::RawField(object, JSArrayBuffer::BodyDescriptor::kStartOffset), | 87 HeapObject::RawField(object, JSArrayBuffer::BodyDescriptor::kStartOffset), |
| 88 HeapObject::RawField(object, JSArrayBuffer::kSizeWithInternalFields)); | 88 HeapObject::RawField(object, JSArrayBuffer::kSizeWithInternalFields)); |
| 89 if (!JSArrayBuffer::cast(object)->is_external()) { | 89 if (!JSArrayBuffer::cast(object)->is_external()) { |
| 90 heap->RegisterLiveArrayBuffer(true, | 90 heap->RegisterLiveArrayBuffer(true, |
| 91 JSArrayBuffer::cast(object)->backing_store()); | 91 JSArrayBuffer::cast(object)->backing_store()); |
| 92 } | 92 } |
| 93 return JSArrayBuffer::kSizeWithInternalFields; | 93 return JSArrayBuffer::kSizeWithInternalFields; |
| 94 } | 94 } |
| 95 | 95 |
| 96 | 96 |
| 97 template <typename StaticVisitor> | 97 template <typename StaticVisitor> |
| 98 int StaticNewSpaceVisitor<StaticVisitor>::VisitJSTypedArray( | 98 int StaticNewSpaceVisitor<StaticVisitor>::VisitJSTypedArray( |
| 99 Map* map, HeapObject* object) { | 99 Map* map, HeapObject* object) { |
| 100 VisitPointers( | 100 VisitPointers( |
| 101 map->GetHeap(), | 101 map->GetHeap(), object, |
| 102 HeapObject::RawField(object, JSTypedArray::BodyDescriptor::kStartOffset), | 102 HeapObject::RawField(object, JSTypedArray::BodyDescriptor::kStartOffset), |
| 103 HeapObject::RawField(object, JSTypedArray::kSizeWithInternalFields)); | 103 HeapObject::RawField(object, JSTypedArray::kSizeWithInternalFields)); |
| 104 return JSTypedArray::kSizeWithInternalFields; | 104 return JSTypedArray::kSizeWithInternalFields; |
| 105 } | 105 } |
| 106 | 106 |
| 107 | 107 |
| 108 template <typename StaticVisitor> | 108 template <typename StaticVisitor> |
| 109 int StaticNewSpaceVisitor<StaticVisitor>::VisitJSDataView(Map* map, | 109 int StaticNewSpaceVisitor<StaticVisitor>::VisitJSDataView(Map* map, |
| 110 HeapObject* object) { | 110 HeapObject* object) { |
| 111 VisitPointers( | 111 VisitPointers( |
| 112 map->GetHeap(), | 112 map->GetHeap(), object, |
| 113 HeapObject::RawField(object, JSDataView::BodyDescriptor::kStartOffset), | 113 HeapObject::RawField(object, JSDataView::BodyDescriptor::kStartOffset), |
| 114 HeapObject::RawField(object, JSDataView::kSizeWithInternalFields)); | 114 HeapObject::RawField(object, JSDataView::kSizeWithInternalFields)); |
| 115 return JSDataView::kSizeWithInternalFields; | 115 return JSDataView::kSizeWithInternalFields; |
| 116 } | 116 } |
| 117 | 117 |
| 118 | 118 |
| 119 template <typename StaticVisitor> | 119 template <typename StaticVisitor> |
| 120 void StaticMarkingVisitor<StaticVisitor>::Initialize() { | 120 void StaticMarkingVisitor<StaticVisitor>::Initialize() { |
| 121 table_.Register(kVisitShortcutCandidate, | 121 table_.Register(kVisitShortcutCandidate, |
| 122 &FixedBodyVisitor<StaticVisitor, ConsString::BodyDescriptor, | 122 &FixedBodyVisitor<StaticVisitor, ConsString::BodyDescriptor, |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 table_.template RegisterSpecializations<JSObjectVisitor, kVisitJSObject, | 192 table_.template RegisterSpecializations<JSObjectVisitor, kVisitJSObject, |
| 193 kVisitJSObjectGeneric>(); | 193 kVisitJSObjectGeneric>(); |
| 194 | 194 |
| 195 table_.template RegisterSpecializations<StructObjectVisitor, kVisitStruct, | 195 table_.template RegisterSpecializations<StructObjectVisitor, kVisitStruct, |
| 196 kVisitStructGeneric>(); | 196 kVisitStructGeneric>(); |
| 197 } | 197 } |
| 198 | 198 |
| 199 | 199 |
| 200 template <typename StaticVisitor> | 200 template <typename StaticVisitor> |
| 201 void StaticMarkingVisitor<StaticVisitor>::VisitCodeEntry( | 201 void StaticMarkingVisitor<StaticVisitor>::VisitCodeEntry( |
| 202 Heap* heap, Address entry_address) { | 202 Heap* heap, HeapObject* object, Address entry_address) { |
| 203 Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address)); | 203 Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address)); |
| 204 heap->mark_compact_collector()->RecordCodeEntrySlot(entry_address, code); | 204 heap->mark_compact_collector()->RecordCodeEntrySlot(object, entry_address, |
| 205 code); |
| 205 StaticVisitor::MarkObject(heap, code); | 206 StaticVisitor::MarkObject(heap, code); |
| 206 } | 207 } |
| 207 | 208 |
| 208 | 209 |
| 209 template <typename StaticVisitor> | 210 template <typename StaticVisitor> |
| 210 void StaticMarkingVisitor<StaticVisitor>::VisitEmbeddedPointer( | 211 void StaticMarkingVisitor<StaticVisitor>::VisitEmbeddedPointer( |
| 211 Heap* heap, RelocInfo* rinfo) { | 212 Heap* heap, RelocInfo* rinfo) { |
| 212 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); | 213 DCHECK(rinfo->rmode() == RelocInfo::EMBEDDED_OBJECT); |
| 213 HeapObject* object = HeapObject::cast(rinfo->target_object()); | 214 HeapObject* object = HeapObject::cast(rinfo->target_object()); |
| 214 heap->mark_compact_collector()->RecordRelocSlot(rinfo, object); | 215 heap->mark_compact_collector()->RecordRelocSlot(rinfo, object); |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 template <typename StaticVisitor> | 279 template <typename StaticVisitor> |
| 279 void StaticMarkingVisitor<StaticVisitor>::VisitNativeContext( | 280 void StaticMarkingVisitor<StaticVisitor>::VisitNativeContext( |
| 280 Map* map, HeapObject* object) { | 281 Map* map, HeapObject* object) { |
| 281 FixedBodyVisitor<StaticVisitor, Context::MarkCompactBodyDescriptor, | 282 FixedBodyVisitor<StaticVisitor, Context::MarkCompactBodyDescriptor, |
| 282 void>::Visit(map, object); | 283 void>::Visit(map, object); |
| 283 | 284 |
| 284 MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector(); | 285 MarkCompactCollector* collector = map->GetHeap()->mark_compact_collector(); |
| 285 for (int idx = Context::FIRST_WEAK_SLOT; idx < Context::NATIVE_CONTEXT_SLOTS; | 286 for (int idx = Context::FIRST_WEAK_SLOT; idx < Context::NATIVE_CONTEXT_SLOTS; |
| 286 ++idx) { | 287 ++idx) { |
| 287 Object** slot = Context::cast(object)->RawFieldOfElementAt(idx); | 288 Object** slot = Context::cast(object)->RawFieldOfElementAt(idx); |
| 288 collector->RecordSlot(slot, slot, *slot); | 289 collector->RecordSlot(object, slot, *slot); |
| 289 } | 290 } |
| 290 } | 291 } |
| 291 | 292 |
| 292 | 293 |
| 293 template <typename StaticVisitor> | 294 template <typename StaticVisitor> |
| 294 void StaticMarkingVisitor<StaticVisitor>::VisitMap(Map* map, | 295 void StaticMarkingVisitor<StaticVisitor>::VisitMap(Map* map, |
| 295 HeapObject* object) { | 296 HeapObject* object) { |
| 296 Heap* heap = map->GetHeap(); | 297 Heap* heap = map->GetHeap(); |
| 297 Map* map_object = Map::cast(object); | 298 Map* map_object = Map::cast(object); |
| 298 | 299 |
| 299 // Clears the cache of ICs related to this map. | 300 // Clears the cache of ICs related to this map. |
| 300 if (FLAG_cleanup_code_caches_at_gc) { | 301 if (FLAG_cleanup_code_caches_at_gc) { |
| 301 map_object->ClearCodeCache(heap); | 302 map_object->ClearCodeCache(heap); |
| 302 } | 303 } |
| 303 | 304 |
| 304 // When map collection is enabled we have to mark through map's transitions | 305 // When map collection is enabled we have to mark through map's transitions |
| 305 // and back pointers in a special way to make these links weak. | 306 // and back pointers in a special way to make these links weak. |
| 306 if (map_object->CanTransition()) { | 307 if (map_object->CanTransition()) { |
| 307 MarkMapContents(heap, map_object); | 308 MarkMapContents(heap, map_object); |
| 308 } else { | 309 } else { |
| 309 StaticVisitor::VisitPointers( | 310 StaticVisitor::VisitPointers( |
| 310 heap, HeapObject::RawField(object, Map::kPointerFieldsBeginOffset), | 311 heap, object, |
| 312 HeapObject::RawField(object, Map::kPointerFieldsBeginOffset), |
| 311 HeapObject::RawField(object, Map::kPointerFieldsEndOffset)); | 313 HeapObject::RawField(object, Map::kPointerFieldsEndOffset)); |
| 312 } | 314 } |
| 313 } | 315 } |
| 314 | 316 |
| 315 | 317 |
| 316 template <typename StaticVisitor> | 318 template <typename StaticVisitor> |
| 317 void StaticMarkingVisitor<StaticVisitor>::VisitPropertyCell( | 319 void StaticMarkingVisitor<StaticVisitor>::VisitPropertyCell( |
| 318 Map* map, HeapObject* object) { | 320 Map* map, HeapObject* object) { |
| 319 Heap* heap = map->GetHeap(); | 321 Heap* heap = map->GetHeap(); |
| 320 | 322 |
| 321 StaticVisitor::VisitPointers( | 323 StaticVisitor::VisitPointers( |
| 322 heap, | 324 heap, object, |
| 323 HeapObject::RawField(object, PropertyCell::kPointerFieldsBeginOffset), | 325 HeapObject::RawField(object, PropertyCell::kPointerFieldsBeginOffset), |
| 324 HeapObject::RawField(object, PropertyCell::kPointerFieldsEndOffset)); | 326 HeapObject::RawField(object, PropertyCell::kPointerFieldsEndOffset)); |
| 325 } | 327 } |
| 326 | 328 |
| 327 | 329 |
| 328 template <typename StaticVisitor> | 330 template <typename StaticVisitor> |
| 329 void StaticMarkingVisitor<StaticVisitor>::VisitWeakCell(Map* map, | 331 void StaticMarkingVisitor<StaticVisitor>::VisitWeakCell(Map* map, |
| 330 HeapObject* object) { | 332 HeapObject* object) { |
| 331 Heap* heap = map->GetHeap(); | 333 Heap* heap = map->GetHeap(); |
| 332 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(object); | 334 WeakCell* weak_cell = reinterpret_cast<WeakCell*>(object); |
| 333 // Enqueue weak cell in linked list of encountered weak collections. | 335 // Enqueue weak cell in linked list of encountered weak collections. |
| 334 // We can ignore weak cells with cleared values because they will always | 336 // We can ignore weak cells with cleared values because they will always |
| 335 // contain smi zero. | 337 // contain smi zero. |
| 336 if (weak_cell->next_cleared() && !weak_cell->cleared()) { | 338 if (weak_cell->next_cleared() && !weak_cell->cleared()) { |
| 337 weak_cell->set_next(heap->encountered_weak_cells(), | 339 weak_cell->set_next(heap->encountered_weak_cells(), |
| 338 UPDATE_WEAK_WRITE_BARRIER); | 340 UPDATE_WEAK_WRITE_BARRIER); |
| 339 heap->set_encountered_weak_cells(weak_cell); | 341 heap->set_encountered_weak_cells(weak_cell); |
| 340 } | 342 } |
| 341 } | 343 } |
| 342 | 344 |
| 343 | 345 |
| 344 template <typename StaticVisitor> | 346 template <typename StaticVisitor> |
| 345 void StaticMarkingVisitor<StaticVisitor>::VisitAllocationSite( | 347 void StaticMarkingVisitor<StaticVisitor>::VisitAllocationSite( |
| 346 Map* map, HeapObject* object) { | 348 Map* map, HeapObject* object) { |
| 347 Heap* heap = map->GetHeap(); | 349 Heap* heap = map->GetHeap(); |
| 348 | 350 |
| 349 StaticVisitor::VisitPointers( | 351 StaticVisitor::VisitPointers( |
| 350 heap, | 352 heap, object, |
| 351 HeapObject::RawField(object, AllocationSite::kPointerFieldsBeginOffset), | 353 HeapObject::RawField(object, AllocationSite::kPointerFieldsBeginOffset), |
| 352 HeapObject::RawField(object, AllocationSite::kPointerFieldsEndOffset)); | 354 HeapObject::RawField(object, AllocationSite::kPointerFieldsEndOffset)); |
| 353 } | 355 } |
| 354 | 356 |
| 355 | 357 |
| 356 template <typename StaticVisitor> | 358 template <typename StaticVisitor> |
| 357 void StaticMarkingVisitor<StaticVisitor>::VisitWeakCollection( | 359 void StaticMarkingVisitor<StaticVisitor>::VisitWeakCollection( |
| 358 Map* map, HeapObject* object) { | 360 Map* map, HeapObject* object) { |
| 359 Heap* heap = map->GetHeap(); | 361 Heap* heap = map->GetHeap(); |
| 360 JSWeakCollection* weak_collection = | 362 JSWeakCollection* weak_collection = |
| 361 reinterpret_cast<JSWeakCollection*>(object); | 363 reinterpret_cast<JSWeakCollection*>(object); |
| 362 | 364 |
| 363 // Enqueue weak collection in linked list of encountered weak collections. | 365 // Enqueue weak collection in linked list of encountered weak collections. |
| 364 if (weak_collection->next() == heap->undefined_value()) { | 366 if (weak_collection->next() == heap->undefined_value()) { |
| 365 weak_collection->set_next(heap->encountered_weak_collections()); | 367 weak_collection->set_next(heap->encountered_weak_collections()); |
| 366 heap->set_encountered_weak_collections(weak_collection); | 368 heap->set_encountered_weak_collections(weak_collection); |
| 367 } | 369 } |
| 368 | 370 |
| 369 // Skip visiting the backing hash table containing the mappings and the | 371 // Skip visiting the backing hash table containing the mappings and the |
| 370 // pointer to the other enqueued weak collections, both are post-processed. | 372 // pointer to the other enqueued weak collections, both are post-processed. |
| 371 StaticVisitor::VisitPointers( | 373 StaticVisitor::VisitPointers( |
| 372 heap, HeapObject::RawField(object, JSWeakCollection::kPropertiesOffset), | 374 heap, object, |
| 375 HeapObject::RawField(object, JSWeakCollection::kPropertiesOffset), |
| 373 HeapObject::RawField(object, JSWeakCollection::kTableOffset)); | 376 HeapObject::RawField(object, JSWeakCollection::kTableOffset)); |
| 374 STATIC_ASSERT(JSWeakCollection::kTableOffset + kPointerSize == | 377 STATIC_ASSERT(JSWeakCollection::kTableOffset + kPointerSize == |
| 375 JSWeakCollection::kNextOffset); | 378 JSWeakCollection::kNextOffset); |
| 376 STATIC_ASSERT(JSWeakCollection::kNextOffset + kPointerSize == | 379 STATIC_ASSERT(JSWeakCollection::kNextOffset + kPointerSize == |
| 377 JSWeakCollection::kSize); | 380 JSWeakCollection::kSize); |
| 378 | 381 |
| 379 // Partially initialized weak collection is enqueued, but table is ignored. | 382 // Partially initialized weak collection is enqueued, but table is ignored. |
| 380 if (!weak_collection->table()->IsHashTable()) return; | 383 if (!weak_collection->table()->IsHashTable()) return; |
| 381 | 384 |
| 382 // Mark the backing hash table without pushing it on the marking stack. | 385 // Mark the backing hash table without pushing it on the marking stack. |
| 383 Object** slot = HeapObject::RawField(object, JSWeakCollection::kTableOffset); | 386 Object** slot = HeapObject::RawField(object, JSWeakCollection::kTableOffset); |
| 384 HeapObject* obj = HeapObject::cast(*slot); | 387 HeapObject* obj = HeapObject::cast(*slot); |
| 385 heap->mark_compact_collector()->RecordSlot(slot, slot, obj); | 388 heap->mark_compact_collector()->RecordSlot(object, slot, obj); |
| 386 StaticVisitor::MarkObjectWithoutPush(heap, obj); | 389 StaticVisitor::MarkObjectWithoutPush(heap, obj); |
| 387 } | 390 } |
| 388 | 391 |
| 389 | 392 |
| 390 template <typename StaticVisitor> | 393 template <typename StaticVisitor> |
| 391 void StaticMarkingVisitor<StaticVisitor>::VisitCode(Map* map, | 394 void StaticMarkingVisitor<StaticVisitor>::VisitCode(Map* map, |
| 392 HeapObject* object) { | 395 HeapObject* object) { |
| 393 Heap* heap = map->GetHeap(); | 396 Heap* heap = map->GetHeap(); |
| 394 Code* code = Code::cast(object); | 397 Code* code = Code::cast(object); |
| 395 if (FLAG_age_code && !heap->isolate()->serializer_enabled()) { | 398 if (FLAG_age_code && !heap->isolate()->serializer_enabled()) { |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 VisitJSFunctionStrongCode(heap, object); | 490 VisitJSFunctionStrongCode(heap, object); |
| 488 } | 491 } |
| 489 | 492 |
| 490 | 493 |
| 491 template <typename StaticVisitor> | 494 template <typename StaticVisitor> |
| 492 void StaticMarkingVisitor<StaticVisitor>::VisitJSRegExp(Map* map, | 495 void StaticMarkingVisitor<StaticVisitor>::VisitJSRegExp(Map* map, |
| 493 HeapObject* object) { | 496 HeapObject* object) { |
| 494 int last_property_offset = | 497 int last_property_offset = |
| 495 JSRegExp::kSize + kPointerSize * map->inobject_properties(); | 498 JSRegExp::kSize + kPointerSize * map->inobject_properties(); |
| 496 StaticVisitor::VisitPointers( | 499 StaticVisitor::VisitPointers( |
| 497 map->GetHeap(), HeapObject::RawField(object, JSRegExp::kPropertiesOffset), | 500 map->GetHeap(), object, |
| 501 HeapObject::RawField(object, JSRegExp::kPropertiesOffset), |
| 498 HeapObject::RawField(object, last_property_offset)); | 502 HeapObject::RawField(object, last_property_offset)); |
| 499 } | 503 } |
| 500 | 504 |
| 501 | 505 |
| 502 template <typename StaticVisitor> | 506 template <typename StaticVisitor> |
| 503 void StaticMarkingVisitor<StaticVisitor>::VisitJSArrayBuffer( | 507 void StaticMarkingVisitor<StaticVisitor>::VisitJSArrayBuffer( |
| 504 Map* map, HeapObject* object) { | 508 Map* map, HeapObject* object) { |
| 505 Heap* heap = map->GetHeap(); | 509 Heap* heap = map->GetHeap(); |
| 506 | 510 |
| 507 StaticVisitor::VisitPointers( | 511 StaticVisitor::VisitPointers( |
| 508 heap, | 512 heap, object, |
| 509 HeapObject::RawField(object, JSArrayBuffer::BodyDescriptor::kStartOffset), | 513 HeapObject::RawField(object, JSArrayBuffer::BodyDescriptor::kStartOffset), |
| 510 HeapObject::RawField(object, JSArrayBuffer::kSizeWithInternalFields)); | 514 HeapObject::RawField(object, JSArrayBuffer::kSizeWithInternalFields)); |
| 511 if (!JSArrayBuffer::cast(object)->is_external()) { | 515 if (!JSArrayBuffer::cast(object)->is_external()) { |
| 512 heap->RegisterLiveArrayBuffer(false, | 516 heap->RegisterLiveArrayBuffer(false, |
| 513 JSArrayBuffer::cast(object)->backing_store()); | 517 JSArrayBuffer::cast(object)->backing_store()); |
| 514 } | 518 } |
| 515 } | 519 } |
| 516 | 520 |
| 517 | 521 |
| 518 template <typename StaticVisitor> | 522 template <typename StaticVisitor> |
| 519 void StaticMarkingVisitor<StaticVisitor>::VisitJSTypedArray( | 523 void StaticMarkingVisitor<StaticVisitor>::VisitJSTypedArray( |
| 520 Map* map, HeapObject* object) { | 524 Map* map, HeapObject* object) { |
| 521 StaticVisitor::VisitPointers( | 525 StaticVisitor::VisitPointers( |
| 522 map->GetHeap(), | 526 map->GetHeap(), object, |
| 523 HeapObject::RawField(object, JSTypedArray::BodyDescriptor::kStartOffset), | 527 HeapObject::RawField(object, JSTypedArray::BodyDescriptor::kStartOffset), |
| 524 HeapObject::RawField(object, JSTypedArray::kSizeWithInternalFields)); | 528 HeapObject::RawField(object, JSTypedArray::kSizeWithInternalFields)); |
| 525 } | 529 } |
| 526 | 530 |
| 527 | 531 |
| 528 template <typename StaticVisitor> | 532 template <typename StaticVisitor> |
| 529 void StaticMarkingVisitor<StaticVisitor>::VisitJSDataView(Map* map, | 533 void StaticMarkingVisitor<StaticVisitor>::VisitJSDataView(Map* map, |
| 530 HeapObject* object) { | 534 HeapObject* object) { |
| 531 StaticVisitor::VisitPointers( | 535 StaticVisitor::VisitPointers( |
| 532 map->GetHeap(), | 536 map->GetHeap(), object, |
| 533 HeapObject::RawField(object, JSDataView::BodyDescriptor::kStartOffset), | 537 HeapObject::RawField(object, JSDataView::BodyDescriptor::kStartOffset), |
| 534 HeapObject::RawField(object, JSDataView::kSizeWithInternalFields)); | 538 HeapObject::RawField(object, JSDataView::kSizeWithInternalFields)); |
| 535 } | 539 } |
| 536 | 540 |
| 537 | 541 |
| 538 template <typename StaticVisitor> | 542 template <typename StaticVisitor> |
| 539 void StaticMarkingVisitor<StaticVisitor>::MarkMapContents(Heap* heap, | 543 void StaticMarkingVisitor<StaticVisitor>::MarkMapContents(Heap* heap, |
| 540 Map* map) { | 544 Map* map) { |
| 541 Object* raw_transitions = map->raw_transitions(); | 545 Object* raw_transitions = map->raw_transitions(); |
| 542 if (TransitionArray::IsFullTransitionArray(raw_transitions)) { | 546 if (TransitionArray::IsFullTransitionArray(raw_transitions)) { |
| 543 MarkTransitionArray(heap, TransitionArray::cast(raw_transitions)); | 547 MarkTransitionArray(heap, TransitionArray::cast(raw_transitions)); |
| 544 } | 548 } |
| 545 | 549 |
| 546 // Since descriptor arrays are potentially shared, ensure that only the | 550 // Since descriptor arrays are potentially shared, ensure that only the |
| 547 // descriptors that belong to this map are marked. The first time a non-empty | 551 // descriptors that belong to this map are marked. The first time a non-empty |
| 548 // descriptor array is marked, its header is also visited. The slot holding | 552 // descriptor array is marked, its header is also visited. The slot holding |
| 549 // the descriptor array will be implicitly recorded when the pointer fields of | 553 // the descriptor array will be implicitly recorded when the pointer fields of |
| 550 // this map are visited. Prototype maps don't keep track of transitions, so | 554 // this map are visited. Prototype maps don't keep track of transitions, so |
| 551 // just mark the entire descriptor array. | 555 // just mark the entire descriptor array. |
| 552 if (!map->is_prototype_map()) { | 556 if (!map->is_prototype_map()) { |
| 553 DescriptorArray* descriptors = map->instance_descriptors(); | 557 DescriptorArray* descriptors = map->instance_descriptors(); |
| 554 if (StaticVisitor::MarkObjectWithoutPush(heap, descriptors) && | 558 if (StaticVisitor::MarkObjectWithoutPush(heap, descriptors) && |
| 555 descriptors->length() > 0) { | 559 descriptors->length() > 0) { |
| 556 StaticVisitor::VisitPointers(heap, descriptors->GetFirstElementAddress(), | 560 StaticVisitor::VisitPointers(heap, descriptors, |
| 561 descriptors->GetFirstElementAddress(), |
| 557 descriptors->GetDescriptorEndSlot(0)); | 562 descriptors->GetDescriptorEndSlot(0)); |
| 558 } | 563 } |
| 559 int start = 0; | 564 int start = 0; |
| 560 int end = map->NumberOfOwnDescriptors(); | 565 int end = map->NumberOfOwnDescriptors(); |
| 561 if (start < end) { | 566 if (start < end) { |
| 562 StaticVisitor::VisitPointers(heap, | 567 StaticVisitor::VisitPointers(heap, descriptors, |
| 563 descriptors->GetDescriptorStartSlot(start), | 568 descriptors->GetDescriptorStartSlot(start), |
| 564 descriptors->GetDescriptorEndSlot(end)); | 569 descriptors->GetDescriptorEndSlot(end)); |
| 565 } | 570 } |
| 566 } | 571 } |
| 567 | 572 |
| 568 // Mark the pointer fields of the Map. Since the transitions array has | 573 // Mark the pointer fields of the Map. Since the transitions array has |
| 569 // been marked already, it is fine that one of these fields contains a | 574 // been marked already, it is fine that one of these fields contains a |
| 570 // pointer to it. | 575 // pointer to it. |
| 571 StaticVisitor::VisitPointers( | 576 StaticVisitor::VisitPointers( |
| 572 heap, HeapObject::RawField(map, Map::kPointerFieldsBeginOffset), | 577 heap, map, HeapObject::RawField(map, Map::kPointerFieldsBeginOffset), |
| 573 HeapObject::RawField(map, Map::kPointerFieldsEndOffset)); | 578 HeapObject::RawField(map, Map::kPointerFieldsEndOffset)); |
| 574 } | 579 } |
| 575 | 580 |
| 576 | 581 |
| 577 template <typename StaticVisitor> | 582 template <typename StaticVisitor> |
| 578 void StaticMarkingVisitor<StaticVisitor>::MarkTransitionArray( | 583 void StaticMarkingVisitor<StaticVisitor>::MarkTransitionArray( |
| 579 Heap* heap, TransitionArray* transitions) { | 584 Heap* heap, TransitionArray* transitions) { |
| 580 if (!StaticVisitor::MarkObjectWithoutPush(heap, transitions)) return; | 585 if (!StaticVisitor::MarkObjectWithoutPush(heap, transitions)) return; |
| 581 | 586 |
| 582 if (transitions->HasPrototypeTransitions()) { | 587 if (transitions->HasPrototypeTransitions()) { |
| 583 StaticVisitor::VisitPointer(heap, | 588 StaticVisitor::VisitPointer(heap, transitions, |
| 584 transitions->GetPrototypeTransitionsSlot()); | 589 transitions->GetPrototypeTransitionsSlot()); |
| 585 } | 590 } |
| 586 | 591 |
| 587 int num_transitions = TransitionArray::NumberOfTransitions(transitions); | 592 int num_transitions = TransitionArray::NumberOfTransitions(transitions); |
| 588 for (int i = 0; i < num_transitions; ++i) { | 593 for (int i = 0; i < num_transitions; ++i) { |
| 589 StaticVisitor::VisitPointer(heap, transitions->GetKeySlot(i)); | 594 StaticVisitor::VisitPointer(heap, transitions, transitions->GetKeySlot(i)); |
| 590 } | 595 } |
| 591 } | 596 } |
| 592 | 597 |
| 593 | 598 |
| 594 template <typename StaticVisitor> | 599 template <typename StaticVisitor> |
| 595 void StaticMarkingVisitor<StaticVisitor>::MarkOptimizedCodeMap( | 600 void StaticMarkingVisitor<StaticVisitor>::MarkOptimizedCodeMap( |
| 596 Heap* heap, FixedArray* code_map) { | 601 Heap* heap, FixedArray* code_map) { |
| 597 if (!StaticVisitor::MarkObjectWithoutPush(heap, code_map)) return; | 602 if (!StaticVisitor::MarkObjectWithoutPush(heap, code_map)) return; |
| 598 | 603 |
| 599 // Mark the context-independent entry in the optimized code map. Depending on | 604 // Mark the context-independent entry in the optimized code map. Depending on |
| 600 // the age of the code object, we treat it as a strong or a weak reference. | 605 // the age of the code object, we treat it as a strong or a weak reference. |
| 601 Object* shared_object = code_map->get(SharedFunctionInfo::kSharedCodeIndex); | 606 Object* shared_object = code_map->get(SharedFunctionInfo::kSharedCodeIndex); |
| 602 if (FLAG_turbo_preserve_shared_code && shared_object->IsCode() && | 607 if (FLAG_turbo_preserve_shared_code && shared_object->IsCode() && |
| 603 FLAG_age_code && !Code::cast(shared_object)->IsOld()) { | 608 FLAG_age_code && !Code::cast(shared_object)->IsOld()) { |
| 604 StaticVisitor::VisitPointer( | 609 StaticVisitor::VisitPointer( |
| 605 heap, | 610 heap, code_map, |
| 606 code_map->RawFieldOfElementAt(SharedFunctionInfo::kSharedCodeIndex)); | 611 code_map->RawFieldOfElementAt(SharedFunctionInfo::kSharedCodeIndex)); |
| 607 } | 612 } |
| 608 } | 613 } |
| 609 | 614 |
| 610 | 615 |
| 611 template <typename StaticVisitor> | 616 template <typename StaticVisitor> |
| 612 void StaticMarkingVisitor<StaticVisitor>::MarkInlinedFunctionsCode(Heap* heap, | 617 void StaticMarkingVisitor<StaticVisitor>::MarkInlinedFunctionsCode(Heap* heap, |
| 613 Code* code) { | 618 Code* code) { |
| 614 // For optimized functions we should retain both non-optimized version | 619 // For optimized functions we should retain both non-optimized version |
| 615 // of its code and non-optimized version of all inlined functions. | 620 // of its code and non-optimized version of all inlined functions. |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 727 } | 732 } |
| 728 | 733 |
| 729 | 734 |
| 730 template <typename StaticVisitor> | 735 template <typename StaticVisitor> |
| 731 void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfoStrongCode( | 736 void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfoStrongCode( |
| 732 Heap* heap, HeapObject* object) { | 737 Heap* heap, HeapObject* object) { |
| 733 Object** start_slot = HeapObject::RawField( | 738 Object** start_slot = HeapObject::RawField( |
| 734 object, SharedFunctionInfo::BodyDescriptor::kStartOffset); | 739 object, SharedFunctionInfo::BodyDescriptor::kStartOffset); |
| 735 Object** end_slot = HeapObject::RawField( | 740 Object** end_slot = HeapObject::RawField( |
| 736 object, SharedFunctionInfo::BodyDescriptor::kEndOffset); | 741 object, SharedFunctionInfo::BodyDescriptor::kEndOffset); |
| 737 StaticVisitor::VisitPointers(heap, start_slot, end_slot); | 742 StaticVisitor::VisitPointers(heap, object, start_slot, end_slot); |
| 738 } | 743 } |
| 739 | 744 |
| 740 | 745 |
| 741 template <typename StaticVisitor> | 746 template <typename StaticVisitor> |
| 742 void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfoWeakCode( | 747 void StaticMarkingVisitor<StaticVisitor>::VisitSharedFunctionInfoWeakCode( |
| 743 Heap* heap, HeapObject* object) { | 748 Heap* heap, HeapObject* object) { |
| 744 Object** name_slot = | 749 Object** name_slot = |
| 745 HeapObject::RawField(object, SharedFunctionInfo::kNameOffset); | 750 HeapObject::RawField(object, SharedFunctionInfo::kNameOffset); |
| 746 StaticVisitor::VisitPointer(heap, name_slot); | 751 StaticVisitor::VisitPointer(heap, object, name_slot); |
| 747 | 752 |
| 748 // Skip visiting kCodeOffset as it is treated weakly here. | 753 // Skip visiting kCodeOffset as it is treated weakly here. |
| 749 STATIC_ASSERT(SharedFunctionInfo::kNameOffset + kPointerSize == | 754 STATIC_ASSERT(SharedFunctionInfo::kNameOffset + kPointerSize == |
| 750 SharedFunctionInfo::kCodeOffset); | 755 SharedFunctionInfo::kCodeOffset); |
| 751 STATIC_ASSERT(SharedFunctionInfo::kCodeOffset + kPointerSize == | 756 STATIC_ASSERT(SharedFunctionInfo::kCodeOffset + kPointerSize == |
| 752 SharedFunctionInfo::kOptimizedCodeMapOffset); | 757 SharedFunctionInfo::kOptimizedCodeMapOffset); |
| 753 | 758 |
| 754 Object** start_slot = | 759 Object** start_slot = |
| 755 HeapObject::RawField(object, SharedFunctionInfo::kOptimizedCodeMapOffset); | 760 HeapObject::RawField(object, SharedFunctionInfo::kOptimizedCodeMapOffset); |
| 756 Object** end_slot = HeapObject::RawField( | 761 Object** end_slot = HeapObject::RawField( |
| 757 object, SharedFunctionInfo::BodyDescriptor::kEndOffset); | 762 object, SharedFunctionInfo::BodyDescriptor::kEndOffset); |
| 758 StaticVisitor::VisitPointers(heap, start_slot, end_slot); | 763 StaticVisitor::VisitPointers(heap, object, start_slot, end_slot); |
| 759 } | 764 } |
| 760 | 765 |
| 761 | 766 |
| 762 template <typename StaticVisitor> | 767 template <typename StaticVisitor> |
| 763 void StaticMarkingVisitor<StaticVisitor>::VisitJSFunctionStrongCode( | 768 void StaticMarkingVisitor<StaticVisitor>::VisitJSFunctionStrongCode( |
| 764 Heap* heap, HeapObject* object) { | 769 Heap* heap, HeapObject* object) { |
| 765 Object** start_slot = | 770 Object** start_slot = |
| 766 HeapObject::RawField(object, JSFunction::kPropertiesOffset); | 771 HeapObject::RawField(object, JSFunction::kPropertiesOffset); |
| 767 Object** end_slot = | 772 Object** end_slot = |
| 768 HeapObject::RawField(object, JSFunction::kCodeEntryOffset); | 773 HeapObject::RawField(object, JSFunction::kCodeEntryOffset); |
| 769 StaticVisitor::VisitPointers(heap, start_slot, end_slot); | 774 StaticVisitor::VisitPointers(heap, object, start_slot, end_slot); |
| 770 | 775 |
| 771 VisitCodeEntry(heap, object->address() + JSFunction::kCodeEntryOffset); | 776 VisitCodeEntry(heap, object, |
| 777 object->address() + JSFunction::kCodeEntryOffset); |
| 772 STATIC_ASSERT(JSFunction::kCodeEntryOffset + kPointerSize == | 778 STATIC_ASSERT(JSFunction::kCodeEntryOffset + kPointerSize == |
| 773 JSFunction::kPrototypeOrInitialMapOffset); | 779 JSFunction::kPrototypeOrInitialMapOffset); |
| 774 | 780 |
| 775 start_slot = | 781 start_slot = |
| 776 HeapObject::RawField(object, JSFunction::kPrototypeOrInitialMapOffset); | 782 HeapObject::RawField(object, JSFunction::kPrototypeOrInitialMapOffset); |
| 777 end_slot = HeapObject::RawField(object, JSFunction::kNonWeakFieldsEndOffset); | 783 end_slot = HeapObject::RawField(object, JSFunction::kNonWeakFieldsEndOffset); |
| 778 StaticVisitor::VisitPointers(heap, start_slot, end_slot); | 784 StaticVisitor::VisitPointers(heap, object, start_slot, end_slot); |
| 779 } | 785 } |
| 780 | 786 |
| 781 | 787 |
| 782 template <typename StaticVisitor> | 788 template <typename StaticVisitor> |
| 783 void StaticMarkingVisitor<StaticVisitor>::VisitJSFunctionWeakCode( | 789 void StaticMarkingVisitor<StaticVisitor>::VisitJSFunctionWeakCode( |
| 784 Heap* heap, HeapObject* object) { | 790 Heap* heap, HeapObject* object) { |
| 785 Object** start_slot = | 791 Object** start_slot = |
| 786 HeapObject::RawField(object, JSFunction::kPropertiesOffset); | 792 HeapObject::RawField(object, JSFunction::kPropertiesOffset); |
| 787 Object** end_slot = | 793 Object** end_slot = |
| 788 HeapObject::RawField(object, JSFunction::kCodeEntryOffset); | 794 HeapObject::RawField(object, JSFunction::kCodeEntryOffset); |
| 789 StaticVisitor::VisitPointers(heap, start_slot, end_slot); | 795 StaticVisitor::VisitPointers(heap, object, start_slot, end_slot); |
| 790 | 796 |
| 791 // Skip visiting kCodeEntryOffset as it is treated weakly here. | 797 // Skip visiting kCodeEntryOffset as it is treated weakly here. |
| 792 STATIC_ASSERT(JSFunction::kCodeEntryOffset + kPointerSize == | 798 STATIC_ASSERT(JSFunction::kCodeEntryOffset + kPointerSize == |
| 793 JSFunction::kPrototypeOrInitialMapOffset); | 799 JSFunction::kPrototypeOrInitialMapOffset); |
| 794 | 800 |
| 795 start_slot = | 801 start_slot = |
| 796 HeapObject::RawField(object, JSFunction::kPrototypeOrInitialMapOffset); | 802 HeapObject::RawField(object, JSFunction::kPrototypeOrInitialMapOffset); |
| 797 end_slot = HeapObject::RawField(object, JSFunction::kNonWeakFieldsEndOffset); | 803 end_slot = HeapObject::RawField(object, JSFunction::kNonWeakFieldsEndOffset); |
| 798 StaticVisitor::VisitPointers(heap, start_slot, end_slot); | 804 StaticVisitor::VisitPointers(heap, object, start_slot, end_slot); |
| 799 } | 805 } |
| 800 | 806 |
| 801 | 807 |
| 802 void Code::CodeIterateBody(ObjectVisitor* v) { | 808 void Code::CodeIterateBody(ObjectVisitor* v) { |
| 803 int mode_mask = RelocInfo::kCodeTargetMask | | 809 int mode_mask = RelocInfo::kCodeTargetMask | |
| 804 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | | 810 RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT) | |
| 805 RelocInfo::ModeMask(RelocInfo::CELL) | | 811 RelocInfo::ModeMask(RelocInfo::CELL) | |
| 806 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | | 812 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | |
| 807 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) | | 813 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) | |
| 808 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) | | 814 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) | |
| (...skipping 23 matching lines...) Expand all Loading... |
| 832 RelocInfo::ModeMask(RelocInfo::CELL) | | 838 RelocInfo::ModeMask(RelocInfo::CELL) | |
| 833 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | | 839 RelocInfo::ModeMask(RelocInfo::EXTERNAL_REFERENCE) | |
| 834 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) | | 840 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE) | |
| 835 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) | | 841 RelocInfo::ModeMask(RelocInfo::INTERNAL_REFERENCE_ENCODED) | |
| 836 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) | | 842 RelocInfo::ModeMask(RelocInfo::RUNTIME_ENTRY) | |
| 837 RelocInfo::kDebugBreakSlotMask; | 843 RelocInfo::kDebugBreakSlotMask; |
| 838 | 844 |
| 839 // There are two places where we iterate code bodies: here and the non- | 845 // There are two places where we iterate code bodies: here and the non- |
| 840 // templated CodeIterateBody (above). They should be kept in sync. | 846 // templated CodeIterateBody (above). They should be kept in sync. |
| 841 StaticVisitor::VisitPointer( | 847 StaticVisitor::VisitPointer( |
| 842 heap, | 848 heap, this, |
| 843 reinterpret_cast<Object**>(this->address() + kRelocationInfoOffset)); | 849 reinterpret_cast<Object**>(this->address() + kRelocationInfoOffset)); |
| 844 StaticVisitor::VisitPointer( | 850 StaticVisitor::VisitPointer( |
| 845 heap, reinterpret_cast<Object**>(this->address() + kHandlerTableOffset)); | 851 heap, this, |
| 852 reinterpret_cast<Object**>(this->address() + kHandlerTableOffset)); |
| 846 StaticVisitor::VisitPointer( | 853 StaticVisitor::VisitPointer( |
| 847 heap, | 854 heap, this, |
| 848 reinterpret_cast<Object**>(this->address() + kDeoptimizationDataOffset)); | 855 reinterpret_cast<Object**>(this->address() + kDeoptimizationDataOffset)); |
| 849 StaticVisitor::VisitPointer( | 856 StaticVisitor::VisitPointer( |
| 850 heap, | 857 heap, this, |
| 851 reinterpret_cast<Object**>(this->address() + kTypeFeedbackInfoOffset)); | 858 reinterpret_cast<Object**>(this->address() + kTypeFeedbackInfoOffset)); |
| 852 StaticVisitor::VisitNextCodeLink( | 859 StaticVisitor::VisitNextCodeLink( |
| 853 heap, reinterpret_cast<Object**>(this->address() + kNextCodeLinkOffset)); | 860 heap, reinterpret_cast<Object**>(this->address() + kNextCodeLinkOffset)); |
| 854 | 861 |
| 855 | 862 |
| 856 RelocIterator it(this, mode_mask); | 863 RelocIterator it(this, mode_mask); |
| 857 for (; !it.done(); it.next()) { | 864 for (; !it.done(); it.next()) { |
| 858 it.rinfo()->template Visit<StaticVisitor>(heap); | 865 it.rinfo()->template Visit<StaticVisitor>(heap); |
| 859 } | 866 } |
| 860 } | 867 } |
| 861 } | 868 } |
| 862 } // namespace v8::internal | 869 } // namespace v8::internal |
| 863 | 870 |
| 864 #endif // V8_OBJECTS_VISITING_INL_H_ | 871 #endif // V8_OBJECTS_VISITING_INL_H_ |
| OLD | NEW |