1e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier/* 2e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier * Copyright (C) 2015 The Android Open Source Project 3e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier * 4e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier * Licensed under the Apache License, Version 2.0 (the "License"); 5e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier * you may not use this file except in compliance with the License. 6e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier * You may obtain a copy of the License at 7e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier * 8e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier * http://www.apache.org/licenses/LICENSE-2.0 9e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier * 10e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier * Unless required by applicable law or agreed to in writing, software 11e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier * distributed under the License is distributed on an "AS IS" BASIS, 12e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier * See the License for the specific language governing permissions and 14e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier * limitations under the License. 15e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier */ 16e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 17e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier#ifndef ART_RUNTIME_CLASS_TABLE_INL_H_ 18e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier#define ART_RUNTIME_CLASS_TABLE_INL_H_ 19e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 20e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier#include "class_table.h" 21508fdf3eb53824f109c89f98484927085bdc43baAndreas Gampe 22508fdf3eb53824f109c89f98484927085bdc43baAndreas Gampe#include "gc_root-inl.h" 23aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko#include "oat_file.h" 24e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 25e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartiernamespace art { 26e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 27e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartiertemplate<class Visitor> 28e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartiervoid ClassTable::VisitRoots(Visitor& visitor) { 291609e3a42051769f4a8be3b6731e7bb2f828b3bbMathieu Chartier ReaderMutexLock mu(Thread::Current(), lock_); 30e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier for (ClassSet& class_set : classes_) { 3158c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier for (TableSlot& table_slot : class_set) { 3258c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier table_slot.VisitRoot(visitor); 33e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier } 34e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier } 35c9dbb1df3b5c06ba122cacaf35b17cb53c6be3c6Mathieu Chartier for (GcRoot<mirror::Object>& root : strong_roots_) { 361aa8ec2ccdd7bedb6d30d91c89f1e94ab23c4439Mathieu Chartier visitor.VisitRoot(root.AddressWithoutBarrier()); 371aa8ec2ccdd7bedb6d30d91c89f1e94ab23c4439Mathieu Chartier } 38aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko for (const OatFile* oat_file : oat_files_) { 39aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko for (GcRoot<mirror::Object>& root : oat_file->GetBssGcRoots()) { 40aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko visitor.VisitRootIfNonNull(root.AddressWithoutBarrier()); 41aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko } 42aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko } 43e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier} 44e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 45e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartiertemplate<class Visitor> 46e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartiervoid ClassTable::VisitRoots(const Visitor& visitor) { 471609e3a42051769f4a8be3b6731e7bb2f828b3bbMathieu Chartier ReaderMutexLock mu(Thread::Current(), lock_); 48e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier for (ClassSet& class_set : classes_) { 4958c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier for (TableSlot& table_slot : class_set) { 5058c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier table_slot.VisitRoot(visitor); 51e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier } 52e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier } 53c9dbb1df3b5c06ba122cacaf35b17cb53c6be3c6Mathieu Chartier for (GcRoot<mirror::Object>& root : strong_roots_) { 5400310e0bb4ee541b99f0b687dbf5f706db2aabcaMathieu Chartier visitor.VisitRoot(root.AddressWithoutBarrier()); 5500310e0bb4ee541b99f0b687dbf5f706db2aabcaMathieu Chartier } 56aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko for (const OatFile* oat_file : oat_files_) { 57aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko for (GcRoot<mirror::Object>& root : oat_file->GetBssGcRoots()) { 58aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko visitor.VisitRootIfNonNull(root.AddressWithoutBarrier()); 59aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko } 60aad75c6d5bfab2dc8e30fc99fafe8cd2dc8b74d8Vladimir Marko } 61e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier} 62e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 63ab2ce84d4995f05c38c5ebfefc6683b244a36260Alexey Grebenkintemplate <typename Visitor, ReadBarrierOption kReadBarrierOption> 641aa8ec2ccdd7bedb6d30d91c89f1e94ab23c4439Mathieu Chartierbool ClassTable::Visit(Visitor& visitor) { 651609e3a42051769f4a8be3b6731e7bb2f828b3bbMathieu Chartier ReaderMutexLock mu(Thread::Current(), lock_); 661aa8ec2ccdd7bedb6d30d91c89f1e94ab23c4439Mathieu Chartier for (ClassSet& class_set : classes_) { 6758c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier for (TableSlot& table_slot : class_set) { 68ab2ce84d4995f05c38c5ebfefc6683b244a36260Alexey Grebenkin if (!visitor(table_slot.Read<kReadBarrierOption>())) { 69db70ce5e788404f36cb5dbb137c6a8f79f34a2a0Mathieu Chartier return false; 70db70ce5e788404f36cb5dbb137c6a8f79f34a2a0Mathieu Chartier } 71db70ce5e788404f36cb5dbb137c6a8f79f34a2a0Mathieu Chartier } 72db70ce5e788404f36cb5dbb137c6a8f79f34a2a0Mathieu Chartier } 73db70ce5e788404f36cb5dbb137c6a8f79f34a2a0Mathieu Chartier return true; 74db70ce5e788404f36cb5dbb137c6a8f79f34a2a0Mathieu Chartier} 75db70ce5e788404f36cb5dbb137c6a8f79f34a2a0Mathieu Chartier 76ab2ce84d4995f05c38c5ebfefc6683b244a36260Alexey Grebenkintemplate <typename Visitor, ReadBarrierOption kReadBarrierOption> 77db70ce5e788404f36cb5dbb137c6a8f79f34a2a0Mathieu Chartierbool ClassTable::Visit(const Visitor& visitor) { 78db70ce5e788404f36cb5dbb137c6a8f79f34a2a0Mathieu Chartier ReaderMutexLock mu(Thread::Current(), lock_); 79db70ce5e788404f36cb5dbb137c6a8f79f34a2a0Mathieu Chartier for (ClassSet& class_set : classes_) { 80db70ce5e788404f36cb5dbb137c6a8f79f34a2a0Mathieu Chartier for (TableSlot& table_slot : class_set) { 81ab2ce84d4995f05c38c5ebfefc6683b244a36260Alexey Grebenkin if (!visitor(table_slot.Read<kReadBarrierOption>())) { 821aa8ec2ccdd7bedb6d30d91c89f1e94ab23c4439Mathieu Chartier return false; 831aa8ec2ccdd7bedb6d30d91c89f1e94ab23c4439Mathieu Chartier } 841aa8ec2ccdd7bedb6d30d91c89f1e94ab23c4439Mathieu Chartier } 851aa8ec2ccdd7bedb6d30d91c89f1e94ab23c4439Mathieu Chartier } 861aa8ec2ccdd7bedb6d30d91c89f1e94ab23c4439Mathieu Chartier return true; 871aa8ec2ccdd7bedb6d30d91c89f1e94ab23c4439Mathieu Chartier} 881aa8ec2ccdd7bedb6d30d91c89f1e94ab23c4439Mathieu Chartier 8958c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartiertemplate<ReadBarrierOption kReadBarrierOption> 9058c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartierinline mirror::Class* ClassTable::TableSlot::Read() const { 9158c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier const uint32_t before = data_.LoadRelaxed(); 9258c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier ObjPtr<mirror::Class> const before_ptr(ExtractPtr(before)); 9358c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier ObjPtr<mirror::Class> const after_ptr( 9458c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier GcRoot<mirror::Class>(before_ptr).Read<kReadBarrierOption>()); 9558c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier if (kReadBarrierOption != kWithoutReadBarrier && before_ptr != after_ptr) { 9658c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier // If another thread raced and updated the reference, do not store the read barrier updated 9758c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier // one. 984557b3858a66aa20e42bce937e1f0620aad880a2Orion Hodson data_.CompareAndSetStrongRelease(before, Encode(after_ptr, MaskHash(before))); 9958c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier } 10058c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier return after_ptr.Ptr(); 10158c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier} 10258c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier 10358c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartiertemplate<typename Visitor> 10458c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartierinline void ClassTable::TableSlot::VisitRoot(const Visitor& visitor) const { 10558c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier const uint32_t before = data_.LoadRelaxed(); 10658c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier ObjPtr<mirror::Class> before_ptr(ExtractPtr(before)); 10758c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier GcRoot<mirror::Class> root(before_ptr); 10858c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier visitor.VisitRoot(root.AddressWithoutBarrier()); 10958c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier ObjPtr<mirror::Class> after_ptr(root.Read<kWithoutReadBarrier>()); 11058c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier if (before_ptr != after_ptr) { 11158c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier // If another thread raced and updated the reference, do not store the read barrier updated 11258c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier // one. 1134557b3858a66aa20e42bce937e1f0620aad880a2Orion Hodson data_.CompareAndSetStrongRelease(before, Encode(after_ptr, MaskHash(before))); 11458c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier } 11558c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier} 11658c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier 11758c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartierinline ObjPtr<mirror::Class> ClassTable::TableSlot::ExtractPtr(uint32_t data) { 11858c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier return reinterpret_cast<mirror::Class*>(data & ~kHashMask); 11958c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier} 12058c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier 12158c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartierinline uint32_t ClassTable::TableSlot::Encode(ObjPtr<mirror::Class> klass, uint32_t hash_bits) { 12258c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier DCHECK_LE(hash_bits, kHashMask); 12358c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier return reinterpret_cast<uintptr_t>(klass.Ptr()) | hash_bits; 12458c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier} 12558c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier 12658c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartierinline ClassTable::TableSlot::TableSlot(ObjPtr<mirror::Class> klass, uint32_t descriptor_hash) 12758c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier : data_(Encode(klass, MaskHash(descriptor_hash))) { 12858c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier if (kIsDebugBuild) { 12958c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier std::string temp; 13058c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier const uint32_t hash = ComputeModifiedUtf8Hash(klass->GetDescriptor(&temp)); 13158c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier CHECK_EQ(descriptor_hash, hash); 13258c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier } 13358c3f6a0d15a4340c0a11ab7fbc8c4b990c64b77Mathieu Chartier} 1341aa8ec2ccdd7bedb6d30d91c89f1e94ab23c4439Mathieu Chartier 13572041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartiertemplate <typename Filter> 13672041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartierinline void ClassTable::RemoveStrongRoots(const Filter& filter) { 13772041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier WriterMutexLock mu(Thread::Current(), lock_); 13872041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier strong_roots_.erase(std::remove_if(strong_roots_.begin(), strong_roots_.end(), filter), 13972041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier strong_roots_.end()); 14072041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier} 14172041a0dcb5b7c133b79a1d6783a23039f2136bdMathieu Chartier 142e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier} // namespace art 143e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier 144e4275c07e9852a6944f47efa9d0591fceb8e8e36Mathieu Chartier#endif // ART_RUNTIME_CLASS_TABLE_INL_H_ 145