1723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi/* 2723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi * Copyright (C) 2015 The Android Open Source Project 3723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi * 4723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi * Licensed under the Apache License, Version 2.0 (the "License"); 5723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi * you may not use this file except in compliance with the License. 6723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi * You may obtain a copy of the License at 7723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi * 8723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi * http://www.apache.org/licenses/LICENSE-2.0 9723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi * 10723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi * Unless required by applicable law or agreed to in writing, software 11723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi * distributed under the License is distributed on an "AS IS" BASIS, 12723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi * See the License for the specific language governing permissions and 14723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi * limitations under the License. 15723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi */ 16723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi 17723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi#ifndef ART_RUNTIME_GC_COLLECTOR_CONCURRENT_COPYING_INL_H_ 18723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi#define ART_RUNTIME_GC_COLLECTOR_CONCURRENT_COPYING_INL_H_ 19723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi 20723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi#include "concurrent_copying.h" 21723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi 22723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi#include "gc/accounting/space_bitmap-inl.h" 23723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi#include "gc/heap.h" 24723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi#include "gc/space/region_space.h" 25723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi#include "lock_word.h" 26723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi 27723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchinamespace art { 28723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchinamespace gc { 29723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchinamespace collector { 30723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi 31723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchiinline mirror::Object* ConcurrentCopying::Mark(mirror::Object* from_ref) { 32723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi if (from_ref == nullptr) { 33723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi return nullptr; 34723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi } 35723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi DCHECK(heap_->collector_type_ == kCollectorTypeCC); 36723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi if (UNLIKELY(kUseBakerReadBarrier && !is_active_)) { 37723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // In the lock word forward address state, the read barrier bits 38723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // in the lock word are part of the stored forwarding address and 39723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // invalid. This is usually OK as the from-space copy of objects 40723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // aren't accessed by mutators due to the to-space 41723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // invariant. However, during the dex2oat image writing relocation 42723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // and the zygote compaction, objects can be in the forward 43723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // address state (to store the forward/relocation addresses) and 44723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // they can still be accessed and the invalid read barrier bits 45723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // are consulted. If they look like gray but aren't really, the 46723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // read barriers slow path can trigger when it shouldn't. To guard 47723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // against this, return here if the CC collector isn't running. 48723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi return from_ref; 49723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi } 50723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi DCHECK(region_space_ != nullptr) << "Read barrier slow path taken when CC isn't running?"; 51723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi space::RegionSpace::RegionType rtype = region_space_->GetRegionType(from_ref); 52723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi switch (rtype) { 53723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi case space::RegionSpace::RegionType::kRegionTypeToSpace: 54723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // It's already marked. 55723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi return from_ref; 56723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi case space::RegionSpace::RegionType::kRegionTypeFromSpace: { 57723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi mirror::Object* to_ref = GetFwdPtr(from_ref); 58723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi if (kUseBakerReadBarrier) { 59723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi DCHECK_NE(to_ref, ReadBarrier::GrayPtr()) 60723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi << "from_ref=" << from_ref << " to_ref=" << to_ref; 61723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi } 62723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi if (to_ref == nullptr) { 63723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // It isn't marked yet. Mark it by copying it to the to-space. 64723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi to_ref = Copy(from_ref); 65723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi } 66723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi DCHECK(region_space_->IsInToSpace(to_ref) || heap_->non_moving_space_->HasAddress(to_ref)) 67723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi << "from_ref=" << from_ref << " to_ref=" << to_ref; 68723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi return to_ref; 69723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi } 70723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi case space::RegionSpace::RegionType::kRegionTypeUnevacFromSpace: { 71723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // This may or may not succeed, which is ok. 72723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi if (kUseBakerReadBarrier) { 73723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi from_ref->AtomicSetReadBarrierPointer(ReadBarrier::WhitePtr(), ReadBarrier::GrayPtr()); 74723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi } 75723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi mirror::Object* to_ref = from_ref; 76723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi if (region_space_bitmap_->AtomicTestAndSet(from_ref)) { 77723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // Already marked. 78723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi } else { 79723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi // Newly marked. 80723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi if (kUseBakerReadBarrier) { 81723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi DCHECK_EQ(to_ref->GetReadBarrierPointer(), ReadBarrier::GrayPtr()); 82723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi } 83723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi PushOntoMarkStack(to_ref); 84723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi } 85723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi return to_ref; 86723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi } 87723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi case space::RegionSpace::RegionType::kRegionTypeNone: 88723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi return MarkNonMoving(from_ref); 89723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi default: 90723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi UNREACHABLE(); 91723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi } 92723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi} 93723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi 94723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchiinline mirror::Object* ConcurrentCopying::GetFwdPtr(mirror::Object* from_ref) { 95723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi DCHECK(region_space_->IsInFromSpace(from_ref)); 96723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi LockWord lw = from_ref->GetLockWord(false); 97723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi if (lw.GetState() == LockWord::kForwardingAddress) { 98723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi mirror::Object* fwd_ptr = reinterpret_cast<mirror::Object*>(lw.ForwardingAddress()); 99723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi DCHECK(fwd_ptr != nullptr); 100723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi return fwd_ptr; 101723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi } else { 102723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi return nullptr; 103723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi } 104723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi} 105723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi 106723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi} // namespace collector 107723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi} // namespace gc 108723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi} // namespace art 109723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi 110723e6cee35671d2dd9aeb884dd11f6994307c01fHiroshi Yamauchi#endif // ART_RUNTIME_GC_COLLECTOR_CONCURRENT_COPYING_INL_H_ 111