• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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