| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 if (count > 0 && FLAG_trace_fragmentation) { | 419 if (count > 0 && FLAG_trace_fragmentation) { |
| 420 PrintF("Collected %d evacuation candidates for space %s\n", | 420 PrintF("Collected %d evacuation candidates for space %s\n", |
| 421 count, | 421 count, |
| 422 AllocationSpaceName(space->identity())); | 422 AllocationSpaceName(space->identity())); |
| 423 } | 423 } |
| 424 } | 424 } |
| 425 | 425 |
| 426 | 426 |
| 427 void MarkCompactCollector::Prepare(GCTracer* tracer) { | 427 void MarkCompactCollector::Prepare(GCTracer* tracer) { |
| 428 FLAG_flush_code = false; | 428 FLAG_flush_code = false; |
| 429 FLAG_always_compact = false; | |
| 430 | 429 |
| 431 // Disable collection of maps if incremental marking is enabled. | 430 // Disable collection of maps if incremental marking is enabled. |
| 432 // Map collection algorithm relies on a special map transition tree traversal | 431 // Map collection algorithm relies on a special map transition tree traversal |
| 433 // order which is not implemented for incremental marking. | 432 // order which is not implemented for incremental marking. |
| 434 collect_maps_ = FLAG_collect_maps && | 433 collect_maps_ = FLAG_collect_maps && |
| 435 !heap()->incremental_marking()->IsMarking(); | 434 !heap()->incremental_marking()->IsMarking(); |
| 436 | 435 |
| 437 // Rather than passing the tracer around we stash it in a static member | 436 // Rather than passing the tracer around we stash it in a static member |
| 438 // variable. | 437 // variable. |
| 439 tracer_ = tracer; | 438 tracer_ = tracer; |
| (...skipping 2968 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3408 bool SlotsBuffer::IsTypedSlot(ObjectSlot slot) { | 3407 bool SlotsBuffer::IsTypedSlot(ObjectSlot slot) { |
| 3409 return reinterpret_cast<uintptr_t>(slot) < NUMBER_OF_SLOT_TYPES; | 3408 return reinterpret_cast<uintptr_t>(slot) < NUMBER_OF_SLOT_TYPES; |
| 3410 } | 3409 } |
| 3411 | 3410 |
| 3412 | 3411 |
| 3413 bool SlotsBuffer::AddTo(SlotsBufferAllocator* allocator, | 3412 bool SlotsBuffer::AddTo(SlotsBufferAllocator* allocator, |
| 3414 SlotsBuffer** buffer_address, | 3413 SlotsBuffer** buffer_address, |
| 3415 SlotType type, | 3414 SlotType type, |
| 3416 Address addr, | 3415 Address addr, |
| 3417 AdditionMode mode) { | 3416 AdditionMode mode) { |
| 3418 if(!AddTo(allocator, | 3417 SlotsBuffer* buffer = *buffer_address; |
| 3419 buffer_address, | 3418 if (buffer == NULL || !buffer->HasSpaceForTypedSlot()) { |
| 3420 reinterpret_cast<ObjectSlot>(type), | 3419 if (mode == FAIL_ON_OVERFLOW && ChainLengthThresholdReached(buffer)) { |
| 3421 mode)) { | 3420 allocator->DeallocateChain(buffer_address); |
| 3422 return false; | 3421 return false; |
| 3422 } |
| 3423 buffer = allocator->AllocateBuffer(buffer); |
| 3424 *buffer_address = buffer; |
| 3423 } | 3425 } |
| 3424 return AddTo(allocator, | 3426 ASSERT(buffer->HasSpaceForTypedSlot()); |
| 3425 buffer_address, | 3427 buffer->Add(reinterpret_cast<ObjectSlot>(type)); |
| 3426 reinterpret_cast<ObjectSlot>(addr), | 3428 buffer->Add(reinterpret_cast<ObjectSlot>(addr)); |
| 3427 mode); | 3429 return true; |
| 3428 } | 3430 } |
| 3429 | 3431 |
| 3430 | 3432 |
| 3431 static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { | 3433 static inline SlotsBuffer::SlotType SlotTypeForRMode(RelocInfo::Mode rmode) { |
| 3432 if (RelocInfo::IsCodeTarget(rmode)) { | 3434 if (RelocInfo::IsCodeTarget(rmode)) { |
| 3433 return SlotsBuffer::CODE_TARGET_SLOT; | 3435 return SlotsBuffer::CODE_TARGET_SLOT; |
| 3434 } else if (RelocInfo::IsDebugBreakSlot(rmode)) { | 3436 } else if (RelocInfo::IsDebugBreakSlot(rmode)) { |
| 3435 return SlotsBuffer::DEBUG_TARGET_SLOT; | 3437 return SlotsBuffer::DEBUG_TARGET_SLOT; |
| 3436 } else if (RelocInfo::IsJSReturn(rmode)) { | 3438 } else if (RelocInfo::IsJSReturn(rmode)) { |
| 3437 return SlotsBuffer::JS_RETURN_SLOT; | 3439 return SlotsBuffer::JS_RETURN_SLOT; |
| 3438 } | 3440 } |
| 3439 UNREACHABLE(); | 3441 UNREACHABLE(); |
| 3440 return SlotsBuffer::NONE; | 3442 return SlotsBuffer::NUMBER_OF_SLOT_TYPES; |
| 3441 } | 3443 } |
| 3442 | 3444 |
| 3443 | 3445 |
| 3444 void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Code* target) { | 3446 void MarkCompactCollector::RecordRelocSlot(RelocInfo* rinfo, Code* target) { |
| 3445 Page* target_page = Page::FromAddress( | 3447 Page* target_page = Page::FromAddress( |
| 3446 reinterpret_cast<Address>(target)); | 3448 reinterpret_cast<Address>(target)); |
| 3447 if (target_page->IsEvacuationCandidate() && | 3449 if (target_page->IsEvacuationCandidate() && |
| 3448 !ShouldSkipEvacuationSlotRecording(rinfo->host())) { | 3450 (rinfo->host() == NULL || |
| 3451 !ShouldSkipEvacuationSlotRecording(rinfo->host()))) { |
| 3449 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, | 3452 if (!SlotsBuffer::AddTo(&slots_buffer_allocator_, |
| 3450 target_page->slots_buffer_address(), | 3453 target_page->slots_buffer_address(), |
| 3451 SlotTypeForRMode(rinfo->rmode()), | 3454 SlotTypeForRMode(rinfo->rmode()), |
| 3452 rinfo->pc(), | 3455 rinfo->pc(), |
| 3453 SlotsBuffer::FAIL_ON_OVERFLOW)) { | 3456 SlotsBuffer::FAIL_ON_OVERFLOW)) { |
| 3454 EvictEvacuationCandidate(target_page); | 3457 EvictEvacuationCandidate(target_page); |
| 3455 } | 3458 } |
| 3456 } | 3459 } |
| 3457 } | 3460 } |
| 3458 | 3461 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 3472 } | 3475 } |
| 3473 } | 3476 } |
| 3474 | 3477 |
| 3475 | 3478 |
| 3476 static inline SlotsBuffer::SlotType DecodeSlotType( | 3479 static inline SlotsBuffer::SlotType DecodeSlotType( |
| 3477 SlotsBuffer::ObjectSlot slot) { | 3480 SlotsBuffer::ObjectSlot slot) { |
| 3478 return static_cast<SlotsBuffer::SlotType>(reinterpret_cast<intptr_t>(slot)); | 3481 return static_cast<SlotsBuffer::SlotType>(reinterpret_cast<intptr_t>(slot)); |
| 3479 } | 3482 } |
| 3480 | 3483 |
| 3481 | 3484 |
| 3482 SlotsBuffer::SlotType SlotsBuffer::UpdateSlots( | 3485 void SlotsBuffer::UpdateSlots(Heap* heap) { |
| 3483 Heap* heap, | |
| 3484 SlotsBuffer::SlotType pending) { | |
| 3485 PointersUpdatingVisitor v(heap); | 3486 PointersUpdatingVisitor v(heap); |
| 3486 | 3487 |
| 3487 if (pending != NONE) { | |
| 3488 UpdateSlot(&v, pending, reinterpret_cast<Address>(slots_[0])); | |
| 3489 } | |
| 3490 | |
| 3491 for (int slot_idx = 0; slot_idx < idx_; ++slot_idx) { | 3488 for (int slot_idx = 0; slot_idx < idx_; ++slot_idx) { |
| 3492 ObjectSlot slot = slots_[slot_idx]; | 3489 ObjectSlot slot = slots_[slot_idx]; |
| 3493 if (!IsTypedSlot(slot)) { | 3490 if (!IsTypedSlot(slot)) { |
| 3494 UpdateSlot(slot); | 3491 UpdateSlot(slot); |
| 3495 } else { | 3492 } else { |
| 3496 ++slot_idx; | 3493 ++slot_idx; |
| 3497 if (slot_idx < idx_) { | 3494 ASSERT(slot_idx < idx_); |
| 3498 UpdateSlot(&v, | 3495 UpdateSlot(&v, |
| 3499 DecodeSlotType(slot), | 3496 DecodeSlotType(slot), |
| 3500 reinterpret_cast<Address>(slots_[slot_idx])); | 3497 reinterpret_cast<Address>(slots_[slot_idx])); |
| 3501 } else { | |
| 3502 return DecodeSlotType(slot); | |
| 3503 } | |
| 3504 } | 3498 } |
| 3505 } | 3499 } |
| 3506 | |
| 3507 return SlotsBuffer::NONE; | |
| 3508 } | 3500 } |
| 3509 | 3501 |
| 3510 | 3502 |
| 3511 SlotsBuffer* SlotsBufferAllocator::AllocateBuffer(SlotsBuffer* next_buffer) { | 3503 SlotsBuffer* SlotsBufferAllocator::AllocateBuffer(SlotsBuffer* next_buffer) { |
| 3512 return new SlotsBuffer(next_buffer); | 3504 return new SlotsBuffer(next_buffer); |
| 3513 } | 3505 } |
| 3514 | 3506 |
| 3515 | 3507 |
| 3516 void SlotsBufferAllocator::DeallocateBuffer(SlotsBuffer* buffer) { | 3508 void SlotsBufferAllocator::DeallocateBuffer(SlotsBuffer* buffer) { |
| 3517 delete buffer; | 3509 delete buffer; |
| 3518 } | 3510 } |
| 3519 | 3511 |
| 3520 | 3512 |
| 3521 void SlotsBufferAllocator::DeallocateChain(SlotsBuffer** buffer_address) { | 3513 void SlotsBufferAllocator::DeallocateChain(SlotsBuffer** buffer_address) { |
| 3522 SlotsBuffer* buffer = *buffer_address; | 3514 SlotsBuffer* buffer = *buffer_address; |
| 3523 while (buffer != NULL) { | 3515 while (buffer != NULL) { |
| 3524 SlotsBuffer* next_buffer = buffer->next(); | 3516 SlotsBuffer* next_buffer = buffer->next(); |
| 3525 DeallocateBuffer(buffer); | 3517 DeallocateBuffer(buffer); |
| 3526 buffer = next_buffer; | 3518 buffer = next_buffer; |
| 3527 } | 3519 } |
| 3528 *buffer_address = NULL; | 3520 *buffer_address = NULL; |
| 3529 } | 3521 } |
| 3530 | 3522 |
| 3531 | 3523 |
| 3532 } } // namespace v8::internal | 3524 } } // namespace v8::internal |
| OLD | NEW |