• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2013 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_RUNTIME_MAPPING_TABLE_H_
18 #define ART_RUNTIME_MAPPING_TABLE_H_
19 
20 #include "base/logging.h"
21 #include "leb128.h"
22 
23 namespace art {
24 
25 // A utility for processing the raw uleb128 encoded mapping table created by the quick compiler.
26 class MappingTable {
27  public:
MappingTable(const uint8_t * encoded_map)28   explicit MappingTable(const uint8_t* encoded_map) : encoded_table_(encoded_map) {
29   }
30 
TotalSize()31   uint32_t TotalSize() const PURE {
32     const uint8_t* table = encoded_table_;
33     if (table == NULL) {
34       return 0;
35     } else {
36       return DecodeUnsignedLeb128(&table);
37     }
38   }
39 
DexToPcSize()40   uint32_t DexToPcSize() const PURE {
41     const uint8_t* table = encoded_table_;
42     if (table == NULL) {
43       return 0;
44     } else {
45       uint32_t total_size = DecodeUnsignedLeb128(&table);
46       uint32_t pc_to_dex_size = DecodeUnsignedLeb128(&table);
47       return total_size - pc_to_dex_size;
48     }
49   }
50 
FirstDexToPcPtr()51   const uint8_t* FirstDexToPcPtr() const {
52     const uint8_t* table = encoded_table_;
53     if (table != NULL) {
54       DecodeUnsignedLeb128(&table);  // Total_size, unused.
55       uint32_t pc_to_dex_size = DecodeUnsignedLeb128(&table);
56       for (uint32_t i = 0; i < pc_to_dex_size; ++i) {
57         DecodeUnsignedLeb128(&table);  // Move ptr past native PC.
58         DecodeUnsignedLeb128(&table);  // Move ptr past dex PC.
59       }
60     }
61     return table;
62   }
63 
64   class DexToPcIterator {
65    public:
DexToPcIterator(const MappingTable * table,uint32_t element)66     DexToPcIterator(const MappingTable* table, uint32_t element) :
67         table_(table), element_(element), end_(table_->DexToPcSize()), encoded_table_ptr_(NULL),
68         native_pc_offset_(0), dex_pc_(0) {
69       if (element == 0) {
70         encoded_table_ptr_ = table_->FirstDexToPcPtr();
71         native_pc_offset_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
72         dex_pc_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
73       } else {
74         DCHECK_EQ(table_->DexToPcSize(), element);
75       }
76     }
NativePcOffset()77     uint32_t NativePcOffset() const {
78       return native_pc_offset_;
79     }
DexPc()80     uint32_t DexPc() const {
81       return dex_pc_;
82     }
83     void operator++() {
84       ++element_;
85       if (element_ != end_) {  // Avoid reading beyond the end of the table.
86         native_pc_offset_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
87         dex_pc_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
88       }
89     }
90     bool operator==(const DexToPcIterator& rhs) const {
91       CHECK(table_ == rhs.table_);
92       return element_ == rhs.element_;
93     }
94     bool operator!=(const DexToPcIterator& rhs) const {
95       CHECK(table_ == rhs.table_);
96       return element_ != rhs.element_;
97     }
98 
99    private:
100     const MappingTable* const table_;  // The original table.
101     uint32_t element_;  // A value in the range 0 to end_.
102     const uint32_t end_;  // Equal to table_->DexToPcSize().
103     const uint8_t* encoded_table_ptr_;  // Either NULL or points to encoded data after this entry.
104     uint32_t native_pc_offset_;  // The current value of native pc offset.
105     uint32_t dex_pc_;  // The current value of dex pc.
106   };
107 
DexToPcBegin()108   DexToPcIterator DexToPcBegin() const {
109     return DexToPcIterator(this, 0);
110   }
111 
DexToPcEnd()112   DexToPcIterator DexToPcEnd() const {
113     uint32_t size = DexToPcSize();
114     return DexToPcIterator(this, size);
115   }
116 
PcToDexSize()117   uint32_t PcToDexSize() const PURE {
118     const uint8_t* table = encoded_table_;
119     if (table == NULL) {
120       return 0;
121     } else {
122       DecodeUnsignedLeb128(&table);  // Total_size, unused.
123       uint32_t pc_to_dex_size = DecodeUnsignedLeb128(&table);
124       return pc_to_dex_size;
125     }
126   }
127 
FirstPcToDexPtr()128   const uint8_t* FirstPcToDexPtr() const {
129     const uint8_t* table = encoded_table_;
130     if (table != NULL) {
131       DecodeUnsignedLeb128(&table);  // Total_size, unused.
132       DecodeUnsignedLeb128(&table);  // PC to Dex size, unused.
133     }
134     return table;
135   }
136 
137   class PcToDexIterator {
138    public:
PcToDexIterator(const MappingTable * table,uint32_t element)139     PcToDexIterator(const MappingTable* table, uint32_t element) :
140         table_(table), element_(element), end_(table_->PcToDexSize()), encoded_table_ptr_(NULL),
141         native_pc_offset_(0), dex_pc_(0) {
142       if (element == 0) {
143         encoded_table_ptr_ = table_->FirstPcToDexPtr();
144         native_pc_offset_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
145         dex_pc_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
146       } else {
147         DCHECK_EQ(table_->PcToDexSize(), element);
148       }
149     }
NativePcOffset()150     uint32_t NativePcOffset() const {
151       return native_pc_offset_;
152     }
DexPc()153     uint32_t DexPc() const {
154       return dex_pc_;
155     }
156     void operator++() {
157       ++element_;
158       if (element_ != end_) {  // Avoid reading beyond the end of the table.
159         native_pc_offset_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
160         dex_pc_ = DecodeUnsignedLeb128(&encoded_table_ptr_);
161       }
162     }
163     bool operator==(const PcToDexIterator& rhs) const {
164       CHECK(table_ == rhs.table_);
165       return element_ == rhs.element_;
166     }
167     bool operator!=(const PcToDexIterator& rhs) const {
168       CHECK(table_ == rhs.table_);
169       return element_ != rhs.element_;
170     }
171 
172    private:
173     const MappingTable* const table_;  // The original table.
174     uint32_t element_;  // A value in the range 0 to PcToDexSize.
175     const uint32_t end_;  // Equal to table_->PcToDexSize().
176     const uint8_t* encoded_table_ptr_;  // Either NULL or points to encoded data after this entry.
177     uint32_t native_pc_offset_;  // The current value of native pc offset.
178     uint32_t dex_pc_;  // The current value of dex pc.
179   };
180 
PcToDexBegin()181   PcToDexIterator PcToDexBegin() const {
182     return PcToDexIterator(this, 0);
183   }
184 
PcToDexEnd()185   PcToDexIterator PcToDexEnd() const {
186     uint32_t size = PcToDexSize();
187     return PcToDexIterator(this, size);
188   }
189 
190  private:
191   const uint8_t* const encoded_table_;
192 };
193 
194 }  // namespace art
195 
196 #endif  // ART_RUNTIME_MAPPING_TABLE_H_
197