1590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier/*
2590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier * Copyright (C) 2013 The Android Open Source Project
3590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier *
4590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier * Licensed under the Apache License, Version 2.0 (the "License");
5590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier * you may not use this file except in compliance with the License.
6590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier * You may obtain a copy of the License at
7590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier *
8590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier *      http://www.apache.org/licenses/LICENSE-2.0
9590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier *
10590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier * Unless required by applicable law or agreed to in writing, software
11590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier * distributed under the License is distributed on an "AS IS" BASIS,
12590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier * See the License for the specific language governing permissions and
14590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier * limitations under the License.
15590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier */
16590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
17590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier#ifndef ART_RUNTIME_GC_COLLECTOR_SEMI_SPACE_INL_H_
18590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier#define ART_RUNTIME_GC_COLLECTOR_SEMI_SPACE_INL_H_
19590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
203b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier#include "semi_space.h"
213b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier
223b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier#include "gc/accounting/heap_bitmap.h"
233b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier#include "mirror/object-inl.h"
243b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier
25590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartiernamespace art {
26590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartiernamespace gc {
27590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartiernamespace collector {
28590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
29bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartierclass BitmapSetSlowPathVisitor {
30bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier public:
31bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier  explicit BitmapSetSlowPathVisitor(SemiSpace* semi_space) : semi_space_(semi_space) {
32bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier  }
33bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier
34bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier  void operator()(const mirror::Object* obj) const {
35bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier    CHECK(!semi_space_->to_space_->HasAddress(obj)) << "Marking " << obj << " in to_space_";
36bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier    // Marking a large object, make sure its aligned as a sanity check.
37bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier    CHECK(IsAligned<kPageSize>(obj));
38bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier  }
39bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier
40bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier private:
41bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier  SemiSpace* const semi_space_;
42bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier};
43bbd695c71e0bf518f582e84524e1cdeb3de3896cMathieu Chartier
44590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartierinline mirror::Object* SemiSpace::GetForwardingAddressInFromSpace(mirror::Object* obj) const {
45590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  DCHECK(from_space_->HasAddress(obj));
464d7f61d44a732cfbc8573e5d93364983fd746888Mathieu Chartier  LockWord lock_word = obj->GetLockWord(false);
47590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  if (lock_word.GetState() != LockWord::kForwardingAddress) {
48590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier    return nullptr;
49590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  }
50590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier  return reinterpret_cast<mirror::Object*>(lock_word.ForwardingAddress());
51590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier}
52590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
53eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier// Used to mark and copy objects. Any newly-marked objects who are in the from space Get moved to
543b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier// the to-space and have their forward address updated. Objects which have been newly marked are
553b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier// pushed on the mark stack.
563b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartiertemplate<bool kPoisonReferences>
573b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartierinline void SemiSpace::MarkObject(
583b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier    mirror::ObjectReference<kPoisonReferences, mirror::Object>* obj_ptr) {
593b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier  mirror::Object* obj = obj_ptr->AsMirrorPtr();
603b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier  if (obj == nullptr) {
613b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier    return;
623b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier  }
63624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi  if (kUseBakerOrBrooksReadBarrier) {
643b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier    // Verify all the objects have the correct forward pointer installed.
65624468cd401cc1ac0dd70c746301e0788a597759Hiroshi Yamauchi    obj->AssertReadBarrierPointer();
663b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier  }
67b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier  if (from_space_->HasAddress(obj)) {
68b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier    mirror::Object* forward_address = GetForwardingAddressInFromSpace(obj);
69b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier    // If the object has already been moved, return the new forward address.
70b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier    if (UNLIKELY(forward_address == nullptr)) {
71b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier      forward_address = MarkNonForwardedObject(obj);
72b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier      DCHECK(forward_address != nullptr);
73b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier      // Make sure to only update the forwarding address AFTER you copy the object so that the
74b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier      // monitor word doesn't Get stomped over.
75b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier      obj->SetLockWord(
76b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier          LockWord::FromForwardingAddress(reinterpret_cast<size_t>(forward_address)), false);
77b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier      // Push the object onto the mark stack for later processing.
78b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier      MarkStackPush(forward_address);
79b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier    }
80b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier    obj_ptr->Assign(forward_address);
81b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier  } else if (!collect_from_space_only_ && !immune_region_.ContainsObject(obj)) {
82b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier    BitmapSetSlowPathVisitor visitor(this);
83b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier    if (!mark_bitmap_->Set(obj, visitor)) {
84b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier      // This object was not previously marked.
85b76cac637691c29daa9c44e493b5bc26346ed116Mathieu Chartier      MarkStackPush(obj);
863b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier    }
873b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier  }
883b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier}
893b05e9ba874449dbff65b01b8781001f7d93eea6Mathieu Chartier
90590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier}  // namespace collector
91590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier}  // namespace gc
92590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier}  // namespace art
93590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier
94590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier#endif  // ART_RUNTIME_GC_COLLECTOR_SEMI_SPACE_INL_H_
95