1 /* 2 * Copyright 2024 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_JIT_JIT_CODE_CACHE_INL_H_ 18 #define ART_RUNTIME_JIT_JIT_CODE_CACHE_INL_H_ 19 20 #include "jit/jit_code_cache.h" 21 22 #include "base/macros.h" 23 #include "read_barrier.h" 24 #include "thread.h" 25 #include "well_known_classes-inl.h" 26 27 namespace art HIDDEN { 28 29 class ArtMethod; 30 31 namespace jit { 32 33 template<typename RootVisitorType> VisitRootTables(ArtMethod * method,RootVisitorType & visitor)34EXPORT void JitCodeCache::VisitRootTables(ArtMethod* method, RootVisitorType& visitor) { 35 if (method->IsNative()) { 36 return; 37 } 38 39 Thread* self = Thread::Current(); 40 ScopedDebugDisallowReadBarriers sddrb(self); 41 MutexLock mu(self, *Locks::jit_lock_); 42 43 auto code_ptrs_it = method_code_map_reversed_.find(method); 44 if (code_ptrs_it == method_code_map_reversed_.end()) { 45 return; 46 } 47 48 const std::vector<const void*>& code_ptrs = code_ptrs_it->second; 49 50 for (const void* code_ptr : code_ptrs) { 51 uint32_t number_of_roots = 0; 52 const uint8_t* root_table = GetRootTable(code_ptr, &number_of_roots); 53 uint8_t* roots_data = private_region_.IsInDataSpace(root_table) 54 ? private_region_.GetWritableDataAddress(root_table) 55 : shared_region_.GetWritableDataAddress(root_table); 56 GcRoot<mirror::Object>* roots = reinterpret_cast<GcRoot<mirror::Object>*>(roots_data); 57 for (uint32_t i = 0; i < number_of_roots; ++i) { 58 // This does not need a read barrier because this is called by GC. 59 mirror::Object* object = roots[i].Read<kWithoutReadBarrier>(); 60 if (object == nullptr || 61 object == Runtime::GetWeakClassSentinel() || 62 object->IsString<kDefaultVerifyFlags>() || 63 object->IsClass<kDefaultVerifyFlags>()) { 64 continue; 65 } 66 // We don't need to visit j.l.Class and j.l.String and the only remaining possible 67 // objects are MethodType-s. 68 ObjPtr<mirror::Class> method_type_class = 69 WellKnownClasses::java_lang_invoke_MethodType.Get<kWithoutReadBarrier>(); 70 ObjPtr<mirror::Class> klass = 71 object->GetClass<kDefaultVerifyFlags, kWithoutReadBarrier>(); 72 DCHECK(klass == method_type_class || 73 klass == ReadBarrier::IsMarked(method_type_class.Ptr()) || 74 ReadBarrier::IsMarked(klass.Ptr()) == method_type_class); 75 76 visitor.VisitRoot(roots[i].AddressWithoutBarrier()); 77 } 78 } 79 } 80 81 } // namespace jit 82 } // namespace art 83 84 #endif // ART_RUNTIME_JIT_JIT_CODE_CACHE_INL_H_ 85 86 87