1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2017 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_OAT_INDEX_BSS_MAPPING_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_RUNTIME_OAT_INDEX_BSS_MAPPING_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <android-base/logging.h> 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker #include "base/bit_utils.h" 23*795d594fSAndroid Build Coastguard Worker #include "base/macros.h" 24*795d594fSAndroid Build Coastguard Worker 25*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 26*795d594fSAndroid Build Coastguard Worker 27*795d594fSAndroid Build Coastguard Worker template<typename T> class LengthPrefixedArray; 28*795d594fSAndroid Build Coastguard Worker 29*795d594fSAndroid Build Coastguard Worker // IndexBssMappingEntry describes a mapping of one or more indexes to their offsets in the .bss. 30*795d594fSAndroid Build Coastguard Worker // A sorted array of IndexBssMappingEntry is used to describe the mapping of method indexes, 31*795d594fSAndroid Build Coastguard Worker // type indexes or string indexes to offsets of their assigned slots in the .bss. 32*795d594fSAndroid Build Coastguard Worker // 33*795d594fSAndroid Build Coastguard Worker // The highest index and a mask are stored in a single `uint32_t index_and_mask` and the split 34*795d594fSAndroid Build Coastguard Worker // between the index and the mask is provided externally. The "mask" bits specify whether some 35*795d594fSAndroid Build Coastguard Worker // of the previous indexes are mapped to immediately preceding slots. This is permissible only 36*795d594fSAndroid Build Coastguard Worker // if the slots are consecutive and in the same order as indexes. 37*795d594fSAndroid Build Coastguard Worker // 38*795d594fSAndroid Build Coastguard Worker // The .bss offset of the slot associated with the highest index is stored in plain form as 39*795d594fSAndroid Build Coastguard Worker // `bss_offset`. If the mask specifies any smaller indexes being mapped to immediately 40*795d594fSAndroid Build Coastguard Worker // preceding slots, their offsets are calculated using an externally supplied size of the slot. 41*795d594fSAndroid Build Coastguard Worker struct IndexBssMappingEntry { IndexBitsIndexBssMappingEntry42*795d594fSAndroid Build Coastguard Worker static size_t IndexBits(uint32_t number_of_indexes) { 43*795d594fSAndroid Build Coastguard Worker DCHECK_NE(number_of_indexes, 0u); 44*795d594fSAndroid Build Coastguard Worker return MinimumBitsToStore(number_of_indexes - 1u); 45*795d594fSAndroid Build Coastguard Worker } 46*795d594fSAndroid Build Coastguard Worker IndexMaskIndexBssMappingEntry47*795d594fSAndroid Build Coastguard Worker static uint32_t IndexMask(size_t index_bits) { 48*795d594fSAndroid Build Coastguard Worker DCHECK_LE(index_bits, 32u); 49*795d594fSAndroid Build Coastguard Worker constexpr uint32_t kAllOnes = static_cast<uint32_t>(-1); 50*795d594fSAndroid Build Coastguard Worker // Handle `index_bits == 32u` explicitly; shifting uint32_t left by 32 is undefined behavior. 51*795d594fSAndroid Build Coastguard Worker return (index_bits == 32u) ? kAllOnes : ~(kAllOnes << index_bits); 52*795d594fSAndroid Build Coastguard Worker } 53*795d594fSAndroid Build Coastguard Worker GetIndexIndexBssMappingEntry54*795d594fSAndroid Build Coastguard Worker uint32_t GetIndex(size_t index_bits) const { 55*795d594fSAndroid Build Coastguard Worker return index_and_mask & IndexMask(index_bits); 56*795d594fSAndroid Build Coastguard Worker } 57*795d594fSAndroid Build Coastguard Worker GetMaskIndexBssMappingEntry58*795d594fSAndroid Build Coastguard Worker uint32_t GetMask(size_t index_bits) const { 59*795d594fSAndroid Build Coastguard Worker DCHECK_LT(index_bits, 32u); // GetMask() is valid only if there is at least 1 mask bit. 60*795d594fSAndroid Build Coastguard Worker return index_and_mask >> index_bits; 61*795d594fSAndroid Build Coastguard Worker } 62*795d594fSAndroid Build Coastguard Worker 63*795d594fSAndroid Build Coastguard Worker size_t GetBssOffset(size_t index_bits, uint32_t index, size_t slot_size) const; 64*795d594fSAndroid Build Coastguard Worker 65*795d594fSAndroid Build Coastguard Worker uint32_t index_and_mask; 66*795d594fSAndroid Build Coastguard Worker uint32_t bss_offset; 67*795d594fSAndroid Build Coastguard Worker }; 68*795d594fSAndroid Build Coastguard Worker 69*795d594fSAndroid Build Coastguard Worker using IndexBssMapping = LengthPrefixedArray<IndexBssMappingEntry>; 70*795d594fSAndroid Build Coastguard Worker 71*795d594fSAndroid Build Coastguard Worker class IndexBssMappingLookup { 72*795d594fSAndroid Build Coastguard Worker public: 73*795d594fSAndroid Build Coastguard Worker static constexpr size_t npos = static_cast<size_t>(-1); 74*795d594fSAndroid Build Coastguard Worker 75*795d594fSAndroid Build Coastguard Worker static size_t GetBssOffset(const IndexBssMapping* mapping, 76*795d594fSAndroid Build Coastguard Worker uint32_t index, 77*795d594fSAndroid Build Coastguard Worker uint32_t number_of_indexes, 78*795d594fSAndroid Build Coastguard Worker size_t slot_size); 79*795d594fSAndroid Build Coastguard Worker }; 80*795d594fSAndroid Build Coastguard Worker 81*795d594fSAndroid Build Coastguard Worker } // namespace art 82*795d594fSAndroid Build Coastguard Worker 83*795d594fSAndroid Build Coastguard Worker #endif // ART_RUNTIME_OAT_INDEX_BSS_MAPPING_H_ 84