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