blob: b2922ec6d2165bd80caa64c876ab2f70b819cbb5 [file] [log] [blame]
Vladimir Marko0eb882b2017-05-15 13:39:18 +01001/*
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
25namespace art {
26namespace linker {
27
28// Helper class for encoding compressed MethodBssMapping.
29class MethodBssMappingEncoder {
30 public:
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.
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
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
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_