1 /* 2 * Copyright (C) 2017 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_COMPILER_LINKER_METHOD_BSS_MAPPING_ENCODER_H_ 18 #define ART_COMPILER_LINKER_METHOD_BSS_MAPPING_ENCODER_H_ 19 20 #include "base/enums.h" 21 #include "base/logging.h" 22 #include "dex_file.h" 23 #include "method_bss_mapping.h" 24 25 namespace art { 26 namespace linker { 27 28 // Helper class for encoding compressed MethodBssMapping. 29 class MethodBssMappingEncoder { 30 public: MethodBssMappingEncoder(PointerSize pointer_size)31 explicit MethodBssMappingEncoder(PointerSize pointer_size) 32 : pointer_size_(static_cast<size_t>(pointer_size)) { 33 entry_.method_index = DexFile::kDexNoIndex16; 34 entry_.index_mask = 0u; 35 entry_.bss_offset = static_cast<uint32_t>(-1); 36 } 37 38 // Try to merge the next method_index -> bss_offset mapping into the current entry. 39 // Return true on success, false on failure. TryMerge(uint32_t method_index,uint32_t bss_offset)40 bool TryMerge(uint32_t method_index, uint32_t bss_offset) { 41 DCHECK_NE(method_index, entry_.method_index); 42 if (entry_.bss_offset + pointer_size_ != bss_offset) { 43 return false; 44 } 45 uint32_t diff = method_index - entry_.method_index; 46 if (diff > 16u) { 47 return false; 48 } 49 if ((entry_.index_mask & ~(static_cast<uint32_t>(-1) << diff)) != 0u) { 50 return false; 51 } 52 entry_.method_index = method_index; 53 // Insert the bit indicating the method index we've just overwritten 54 // and shift bits indicating method indexes before that. 55 entry_.index_mask = dchecked_integral_cast<uint16_t>( 56 (static_cast<uint32_t>(entry_.index_mask) | 0x10000u) >> diff); 57 entry_.bss_offset = bss_offset; 58 return true; 59 } 60 Reset(uint32_t method_index,uint32_t bss_offset)61 void Reset(uint32_t method_index, uint32_t bss_offset) { 62 entry_.method_index = method_index; 63 entry_.index_mask = 0u; 64 entry_.bss_offset = bss_offset; 65 } 66 GetEntry()67 MethodBssMappingEntry GetEntry() { 68 return entry_; 69 } 70 71 private: 72 size_t pointer_size_; 73 MethodBssMappingEntry entry_; 74 }; 75 76 } // namespace linker 77 } // namespace art 78 79 #endif // ART_COMPILER_LINKER_METHOD_BSS_MAPPING_ENCODER_H_ 80