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