semi_space-inl.h revision 624468cd401cc1ac0dd70c746301e0788a597759
1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ART_RUNTIME_GC_COLLECTOR_SEMI_SPACE_INL_H_
18#define ART_RUNTIME_GC_COLLECTOR_SEMI_SPACE_INL_H_
19
20#include "semi_space.h"
21
22#include "gc/accounting/heap_bitmap.h"
23#include "mirror/object-inl.h"
24
25namespace art {
26namespace gc {
27namespace collector {
28
29inline mirror::Object* SemiSpace::GetForwardingAddressInFromSpace(mirror::Object* obj) const {
30  DCHECK(from_space_->HasAddress(obj));
31  LockWord lock_word = obj->GetLockWord();
32  if (lock_word.GetState() != LockWord::kForwardingAddress) {
33    return nullptr;
34  }
35  return reinterpret_cast<mirror::Object*>(lock_word.ForwardingAddress());
36}
37
38// Used to mark and copy objects. Any newly-marked objects who are in the from space get moved to
39// the to-space and have their forward address updated. Objects which have been newly marked are
40// pushed on the mark stack.
41template<bool kPoisonReferences>
42inline void SemiSpace::MarkObject(
43    mirror::ObjectReference<kPoisonReferences, mirror::Object>* obj_ptr) {
44  mirror::Object* obj = obj_ptr->AsMirrorPtr();
45  if (obj == nullptr) {
46    return;
47  }
48  if (kUseBakerOrBrooksReadBarrier) {
49    // Verify all the objects have the correct forward pointer installed.
50    obj->AssertReadBarrierPointer();
51  }
52  if (!immune_region_.ContainsObject(obj)) {
53    if (from_space_->HasAddress(obj)) {
54      mirror::Object* forward_address = GetForwardingAddressInFromSpace(obj);
55      // If the object has already been moved, return the new forward address.
56      if (forward_address == nullptr) {
57        forward_address = MarkNonForwardedObject(obj);
58        DCHECK(forward_address != nullptr);
59        // Make sure to only update the forwarding address AFTER you copy the object so that the
60        // monitor word doesn't get stomped over.
61        obj->SetLockWord(LockWord::FromForwardingAddress(
62            reinterpret_cast<size_t>(forward_address)));
63        // Push the object onto the mark stack for later processing.
64        MarkStackPush(forward_address);
65      }
66      obj_ptr->Assign(forward_address);
67    } else {
68      accounting::SpaceBitmap* object_bitmap =
69          heap_->GetMarkBitmap()->GetContinuousSpaceBitmap(obj);
70      if (LIKELY(object_bitmap != nullptr)) {
71        if (generational_) {
72          // If a bump pointer space only collection, we should not
73          // reach here as we don't/won't mark the objects in the
74          // non-moving space (except for the promoted objects.)  Note
75          // the non-moving space is added to the immune space.
76          DCHECK(whole_heap_collection_);
77        }
78        if (!object_bitmap->Set(obj)) {
79          // This object was not previously marked.
80          MarkStackPush(obj);
81        }
82      } else {
83        CHECK(!to_space_->HasAddress(obj)) << "Marking " << obj << " in to_space_";
84        if (MarkLargeObject(obj)) {
85          MarkStackPush(obj);
86        }
87      }
88    }
89  }
90}
91
92}  // namespace collector
93}  // namespace gc
94}  // namespace art
95
96#endif  // ART_RUNTIME_GC_COLLECTOR_SEMI_SPACE_INL_H_
97