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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/base/atomicops.h" | 7 #include "src/base/atomicops.h" |
8 #include "src/base/bits.h" | 8 #include "src/base/bits.h" |
9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
10 #include "src/compilation-cache.h" | 10 #include "src/compilation-cache.h" |
(...skipping 2990 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3001 | 3001 |
3002 data[index++] = 0xeeeeeeeeeeUL; | 3002 data[index++] = 0xeeeeeeeeeeUL; |
3003 DCHECK(index < kDataBufferSize); | 3003 DCHECK(index < kDataBufferSize); |
3004 base::OS::PrintError("Data: %p\n", static_cast<void*>(data)); | 3004 base::OS::PrintError("Data: %p\n", static_cast<void*>(data)); |
3005 base::OS::Abort(); | 3005 base::OS::Abort(); |
3006 } | 3006 } |
3007 #endif | 3007 #endif |
3008 | 3008 |
3009 | 3009 |
3010 static void UpdatePointer(HeapObject** address, HeapObject* object) { | 3010 static void UpdatePointer(HeapObject** address, HeapObject* object) { |
3011 Address new_addr = Memory::Address_at(object->address()); | 3011 MapWord map_word = object->map_word(); |
3012 | 3012 // The store buffer can still contain stale pointers in dead large objects. |
3013 // The new space sweep will overwrite the map word of dead objects | 3013 // Ignore these pointers here. |
3014 // with NULL. In this case we do not need to transfer this entry to | 3014 DCHECK(map_word.IsForwardingAddress() || |
3015 // the store buffer which we are rebuilding. | 3015 object->GetHeap()->lo_space()->FindPage( |
3016 // We perform the pointer update with a no barrier compare-and-swap. The | 3016 reinterpret_cast<Address>(address)) != NULL); |
3017 // compare and swap may fail in the case where the pointer update tries to | 3017 if (map_word.IsForwardingAddress()) { |
3018 // update garbage memory which was concurrently accessed by the sweeper. | 3018 // Update the corresponding slot. |
3019 if (new_addr != NULL) { | 3019 *address = map_word.ToForwardingAddress(); |
3020 base::NoBarrier_CompareAndSwap( | |
3021 reinterpret_cast<base::AtomicWord*>(address), | |
3022 reinterpret_cast<base::AtomicWord>(object), | |
3023 reinterpret_cast<base::AtomicWord>(HeapObject::FromAddress(new_addr))); | |
3024 } | 3020 } |
3025 } | 3021 } |
3026 | 3022 |
3027 | 3023 |
3028 static String* UpdateReferenceInExternalStringTableEntry(Heap* heap, | 3024 static String* UpdateReferenceInExternalStringTableEntry(Heap* heap, |
3029 Object** p) { | 3025 Object** p) { |
3030 MapWord map_word = HeapObject::cast(*p)->map_word(); | 3026 MapWord map_word = HeapObject::cast(*p)->map_word(); |
3031 | 3027 |
3032 if (map_word.IsForwardingAddress()) { | 3028 if (map_word.IsForwardingAddress()) { |
3033 return String::cast(map_word.ToForwardingAddress()); | 3029 return String::cast(map_word.ToForwardingAddress()); |
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3643 GCTracer::Scope::MC_UPDATE_ROOT_TO_NEW_POINTERS); | 3639 GCTracer::Scope::MC_UPDATE_ROOT_TO_NEW_POINTERS); |
3644 // Update roots. | 3640 // Update roots. |
3645 heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); | 3641 heap_->IterateRoots(&updating_visitor, VISIT_ALL_IN_SWEEP_NEWSPACE); |
3646 } | 3642 } |
3647 | 3643 |
3648 { | 3644 { |
3649 GCTracer::Scope gc_scope(heap()->tracer(), | 3645 GCTracer::Scope gc_scope(heap()->tracer(), |
3650 GCTracer::Scope::MC_UPDATE_OLD_TO_NEW_POINTERS); | 3646 GCTracer::Scope::MC_UPDATE_OLD_TO_NEW_POINTERS); |
3651 StoreBufferRebuildScope scope(heap_, heap_->store_buffer(), | 3647 StoreBufferRebuildScope scope(heap_, heap_->store_buffer(), |
3652 &Heap::ScavengeStoreBufferCallback); | 3648 &Heap::ScavengeStoreBufferCallback); |
3653 heap_->store_buffer()->IteratePointersToNewSpaceAndClearMaps( | 3649 heap_->store_buffer()->IteratePointersToNewSpace(&UpdatePointer); |
3654 &UpdatePointer); | |
3655 } | 3650 } |
3656 | 3651 |
3657 { | 3652 { |
3658 GCTracer::Scope gc_scope(heap()->tracer(), | 3653 GCTracer::Scope gc_scope(heap()->tracer(), |
3659 GCTracer::Scope::MC_UPDATE_POINTERS_TO_EVACUATED); | 3654 GCTracer::Scope::MC_UPDATE_POINTERS_TO_EVACUATED); |
3660 SlotsBuffer::UpdateSlotsRecordedIn(heap_, migration_slots_buffer_, | 3655 SlotsBuffer::UpdateSlotsRecordedIn(heap_, migration_slots_buffer_, |
3661 code_slots_filtering_required); | 3656 code_slots_filtering_required); |
3662 if (FLAG_trace_fragmentation) { | 3657 if (FLAG_trace_fragmentation) { |
3663 PrintF(" migration slots buffer: %d\n", | 3658 PrintF(" migration slots buffer: %d\n", |
3664 SlotsBuffer::SizeOfChain(migration_slots_buffer_)); | 3659 SlotsBuffer::SizeOfChain(migration_slots_buffer_)); |
(...skipping 971 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4636 SlotsBuffer* buffer = *buffer_address; | 4631 SlotsBuffer* buffer = *buffer_address; |
4637 while (buffer != NULL) { | 4632 while (buffer != NULL) { |
4638 SlotsBuffer* next_buffer = buffer->next(); | 4633 SlotsBuffer* next_buffer = buffer->next(); |
4639 DeallocateBuffer(buffer); | 4634 DeallocateBuffer(buffer); |
4640 buffer = next_buffer; | 4635 buffer = next_buffer; |
4641 } | 4636 } |
4642 *buffer_address = NULL; | 4637 *buffer_address = NULL; |
4643 } | 4638 } |
4644 } | 4639 } |
4645 } // namespace v8::internal | 4640 } // namespace v8::internal |
OLD | NEW |