1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2016 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_IMTABLE_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_IMTABLE_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include "base/bit_utils.h" 21*795d594fSAndroid Build Coastguard Worker #include "base/casts.h" 22*795d594fSAndroid Build Coastguard Worker #include "base/locks.h" 23*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 24*795d594fSAndroid Build Coastguard Worker #include "base/pointer_size.h" 25*795d594fSAndroid Build Coastguard Worker 26*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 27*795d594fSAndroid Build Coastguard Worker 28*795d594fSAndroid Build Coastguard Worker class ArtMethod; 29*795d594fSAndroid Build Coastguard Worker class DexFile; 30*795d594fSAndroid Build Coastguard Worker 31*795d594fSAndroid Build Coastguard Worker class ImTable { 32*795d594fSAndroid Build Coastguard Worker public: 33*795d594fSAndroid Build Coastguard Worker // Interface method table size. Increasing this value reduces the chance of two interface methods 34*795d594fSAndroid Build Coastguard Worker // colliding in the interface method table but increases the size of classes that implement 35*795d594fSAndroid Build Coastguard Worker // (non-marker) interfaces. 36*795d594fSAndroid Build Coastguard Worker // When this value changes, old images become incompatible, so image file version must change too. 37*795d594fSAndroid Build Coastguard Worker static constexpr size_t kSize = 43; 38*795d594fSAndroid Build Coastguard Worker // Default methods cannot store the imt_index, so instead we make its IMT index depend on the 39*795d594fSAndroid Build Coastguard Worker // method_index and mask it with the closest power of 2 of kSize - 1. This 40*795d594fSAndroid Build Coastguard Worker // is to simplify fetching it in the interpreter. 41*795d594fSAndroid Build Coastguard Worker static constexpr size_t kSizeTruncToPowerOfTwo = TruncToPowerOfTwo(kSize); 42*795d594fSAndroid Build Coastguard Worker AddressOfElement(size_t index,PointerSize pointer_size)43*795d594fSAndroid Build Coastguard Worker uint8_t* AddressOfElement(size_t index, PointerSize pointer_size) { 44*795d594fSAndroid Build Coastguard Worker return reinterpret_cast<uint8_t*>(this) + OffsetOfElement(index, pointer_size); 45*795d594fSAndroid Build Coastguard Worker } 46*795d594fSAndroid Build Coastguard Worker Get(size_t index,PointerSize pointer_size)47*795d594fSAndroid Build Coastguard Worker ArtMethod* Get(size_t index, PointerSize pointer_size) { 48*795d594fSAndroid Build Coastguard Worker DCHECK_LT(index, kSize); 49*795d594fSAndroid Build Coastguard Worker uint8_t* ptr = AddressOfElement(index, pointer_size); 50*795d594fSAndroid Build Coastguard Worker if (pointer_size == PointerSize::k32) { 51*795d594fSAndroid Build Coastguard Worker uint32_t value = *reinterpret_cast<uint32_t*>(ptr); 52*795d594fSAndroid Build Coastguard Worker return reinterpret_cast32<ArtMethod*>(value); 53*795d594fSAndroid Build Coastguard Worker } else { 54*795d594fSAndroid Build Coastguard Worker uint64_t value = *reinterpret_cast<uint64_t*>(ptr); 55*795d594fSAndroid Build Coastguard Worker return reinterpret_cast64<ArtMethod*>(value); 56*795d594fSAndroid Build Coastguard Worker } 57*795d594fSAndroid Build Coastguard Worker } 58*795d594fSAndroid Build Coastguard Worker Set(size_t index,ArtMethod * method,PointerSize pointer_size)59*795d594fSAndroid Build Coastguard Worker void Set(size_t index, ArtMethod* method, PointerSize pointer_size) { 60*795d594fSAndroid Build Coastguard Worker DCHECK_LT(index, kSize); 61*795d594fSAndroid Build Coastguard Worker uint8_t* ptr = AddressOfElement(index, pointer_size); 62*795d594fSAndroid Build Coastguard Worker if (pointer_size == PointerSize::k32) { 63*795d594fSAndroid Build Coastguard Worker *reinterpret_cast<uint32_t*>(ptr) = reinterpret_cast32<uint32_t>(method); 64*795d594fSAndroid Build Coastguard Worker } else { 65*795d594fSAndroid Build Coastguard Worker *reinterpret_cast<uint64_t*>(ptr) = reinterpret_cast64<uint64_t>(method); 66*795d594fSAndroid Build Coastguard Worker } 67*795d594fSAndroid Build Coastguard Worker } 68*795d594fSAndroid Build Coastguard Worker OffsetOfElement(size_t index,PointerSize pointer_size)69*795d594fSAndroid Build Coastguard Worker static size_t OffsetOfElement(size_t index, PointerSize pointer_size) { 70*795d594fSAndroid Build Coastguard Worker return index * static_cast<size_t>(pointer_size); 71*795d594fSAndroid Build Coastguard Worker } 72*795d594fSAndroid Build Coastguard Worker Populate(ArtMethod ** data,PointerSize pointer_size)73*795d594fSAndroid Build Coastguard Worker void Populate(ArtMethod** data, PointerSize pointer_size) { 74*795d594fSAndroid Build Coastguard Worker for (size_t i = 0; i < kSize; ++i) { 75*795d594fSAndroid Build Coastguard Worker Set(i, data[i], pointer_size); 76*795d594fSAndroid Build Coastguard Worker } 77*795d594fSAndroid Build Coastguard Worker } 78*795d594fSAndroid Build Coastguard Worker SizeInBytes(PointerSize pointer_size)79*795d594fSAndroid Build Coastguard Worker constexpr static size_t SizeInBytes(PointerSize pointer_size) { 80*795d594fSAndroid Build Coastguard Worker return kSize * static_cast<size_t>(pointer_size); 81*795d594fSAndroid Build Coastguard Worker } 82*795d594fSAndroid Build Coastguard Worker 83*795d594fSAndroid Build Coastguard Worker // Converts a method to the base hash components used in GetImtIndex. 84*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE static inline void GetImtHashComponents(ArtMethod* method, 85*795d594fSAndroid Build Coastguard Worker uint32_t* class_hash, 86*795d594fSAndroid Build Coastguard Worker uint32_t* name_hash, 87*795d594fSAndroid Build Coastguard Worker uint32_t* signature_hash) 88*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 89*795d594fSAndroid Build Coastguard Worker 90*795d594fSAndroid Build Coastguard Worker // The (complete) hashing scheme to map an ArtMethod to a slot in the Interface Method Table 91*795d594fSAndroid Build Coastguard Worker // (IMT). 92*795d594fSAndroid Build Coastguard Worker ALWAYS_INLINE static inline uint32_t GetImtIndex(ArtMethod* method) 93*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 94*795d594fSAndroid Build Coastguard Worker }; 95*795d594fSAndroid Build Coastguard Worker 96*795d594fSAndroid Build Coastguard Worker } // namespace art 97*795d594fSAndroid Build Coastguard Worker 98*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_IMTABLE_H_ 99*795d594fSAndroid Build Coastguard Worker 100