1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2013 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_RUNTIME_GC_COLLECTOR_SEMI_SPACE_INL_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_GC_COLLECTOR_SEMI_SPACE_INL_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "semi_space.h" 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker #include "gc/accounting/heap_bitmap.h" 23*795d594fSAndroid Build Coastguard Worker #include "mirror/object-inl.h" 24*795d594fSAndroid Build Coastguard Worker 25*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 26*795d594fSAndroid Build Coastguard Worker namespace gc { 27*795d594fSAndroid Build Coastguard Worker namespace collector { 28*795d594fSAndroid Build Coastguard Worker GetForwardingAddressInFromSpace(mirror::Object * obj)29*795d594fSAndroid Build Coastguard Workerinline mirror::Object* SemiSpace::GetForwardingAddressInFromSpace(mirror::Object* obj) const { 30*795d594fSAndroid Build Coastguard Worker DCHECK(from_space_->HasAddress(obj)); 31*795d594fSAndroid Build Coastguard Worker LockWord lock_word = obj->GetLockWord(false); 32*795d594fSAndroid Build Coastguard Worker if (lock_word.GetState() != LockWord::kForwardingAddress) { 33*795d594fSAndroid Build Coastguard Worker return nullptr; 34*795d594fSAndroid Build Coastguard Worker } 35*795d594fSAndroid Build Coastguard Worker return reinterpret_cast<mirror::Object*>(lock_word.ForwardingAddress()); 36*795d594fSAndroid Build Coastguard Worker } 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker // Used to mark and copy objects. Any newly-marked objects who are in the from space Get moved to 39*795d594fSAndroid Build Coastguard Worker // the to-space and have their forward address updated. Objects which have been newly marked are 40*795d594fSAndroid Build Coastguard Worker // pushed on the mark stack. 41*795d594fSAndroid Build Coastguard Worker template<typename CompressedReferenceType> MarkObject(CompressedReferenceType * obj_ptr)42*795d594fSAndroid Build Coastguard Workerinline void SemiSpace::MarkObject(CompressedReferenceType* obj_ptr) { 43*795d594fSAndroid Build Coastguard Worker mirror::Object* obj = obj_ptr->AsMirrorPtr(); 44*795d594fSAndroid Build Coastguard Worker if (obj == nullptr) { 45*795d594fSAndroid Build Coastguard Worker return; 46*795d594fSAndroid Build Coastguard Worker } 47*795d594fSAndroid Build Coastguard Worker if (from_space_->HasAddress(obj)) { 48*795d594fSAndroid Build Coastguard Worker mirror::Object* forward_address = GetForwardingAddressInFromSpace(obj); 49*795d594fSAndroid Build Coastguard Worker // If the object has already been moved, return the new forward address. 50*795d594fSAndroid Build Coastguard Worker if (UNLIKELY(forward_address == nullptr)) { 51*795d594fSAndroid Build Coastguard Worker forward_address = MarkNonForwardedObject(obj); 52*795d594fSAndroid Build Coastguard Worker DCHECK(forward_address != nullptr); 53*795d594fSAndroid Build Coastguard Worker // Make sure to only update the forwarding address AFTER you copy the object so that the 54*795d594fSAndroid Build Coastguard Worker // monitor word doesn't Get stomped over. 55*795d594fSAndroid Build Coastguard Worker obj->SetLockWord( 56*795d594fSAndroid Build Coastguard Worker LockWord::FromForwardingAddress(reinterpret_cast<size_t>(forward_address)), false); 57*795d594fSAndroid Build Coastguard Worker // Push the object onto the mark stack for later processing. 58*795d594fSAndroid Build Coastguard Worker MarkStackPush(forward_address); 59*795d594fSAndroid Build Coastguard Worker } 60*795d594fSAndroid Build Coastguard Worker obj_ptr->Assign(forward_address); 61*795d594fSAndroid Build Coastguard Worker } else if (!immune_spaces_.IsInImmuneRegion(obj)) { 62*795d594fSAndroid Build Coastguard Worker DCHECK(!to_space_->HasAddress(obj)) << "Tried to mark " << obj << " in to-space"; 63*795d594fSAndroid Build Coastguard Worker auto slow_path = [this](const mirror::Object* ref) { 64*795d594fSAndroid Build Coastguard Worker CHECK(!to_space_->HasAddress(ref)) << "Marking " << ref << " in to_space_"; 65*795d594fSAndroid Build Coastguard Worker // Marking a large object, make sure its aligned as a consistency check. 66*795d594fSAndroid Build Coastguard Worker CHECK_ALIGNED_PARAM(ref, space::LargeObjectSpace::ObjectAlignment()); 67*795d594fSAndroid Build Coastguard Worker }; 68*795d594fSAndroid Build Coastguard Worker if (!mark_bitmap_->Set(obj, slow_path)) { 69*795d594fSAndroid Build Coastguard Worker // This object was not previously marked. 70*795d594fSAndroid Build Coastguard Worker MarkStackPush(obj); 71*795d594fSAndroid Build Coastguard Worker } 72*795d594fSAndroid Build Coastguard Worker } 73*795d594fSAndroid Build Coastguard Worker } 74*795d594fSAndroid Build Coastguard Worker 75*795d594fSAndroid Build Coastguard Worker template<typename CompressedReferenceType> MarkObjectIfNotInToSpace(CompressedReferenceType * obj_ptr)76*795d594fSAndroid Build Coastguard Workerinline void SemiSpace::MarkObjectIfNotInToSpace(CompressedReferenceType* obj_ptr) { 77*795d594fSAndroid Build Coastguard Worker if (!to_space_->HasAddress(obj_ptr->AsMirrorPtr())) { 78*795d594fSAndroid Build Coastguard Worker MarkObject(obj_ptr); 79*795d594fSAndroid Build Coastguard Worker } 80*795d594fSAndroid Build Coastguard Worker } 81*795d594fSAndroid Build Coastguard Worker 82*795d594fSAndroid Build Coastguard Worker } // namespace collector 83*795d594fSAndroid Build Coastguard Worker } // namespace gc 84*795d594fSAndroid Build Coastguard Worker } // namespace art 85*795d594fSAndroid Build Coastguard Worker 86*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_GC_COLLECTOR_SEMI_SPACE_INL_H_ 87