blob: b5a69575488570c60b6d7d24611c89aab88916fd [file] [log] [blame]
Mathieu Chartier69147f12017-11-06 20:02:24 -08001/*
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// TODO: Dex helpers have ART specific APIs, we may want to refactor these for use in dexdump.
18
David Sehr9e734c72018-01-04 17:56:19 -080019#ifndef ART_RUNTIME_DEX_CODE_ITEM_ACCESSORS_H_
20#define ART_RUNTIME_DEX_CODE_ITEM_ACCESSORS_H_
Mathieu Chartier69147f12017-11-06 20:02:24 -080021
22#include "base/mutex.h"
David Sehr9e734c72018-01-04 17:56:19 -080023#include "compact_dex_file.h"
Mathieu Chartier69147f12017-11-06 20:02:24 -080024#include "dex_file.h"
25#include "dex_instruction_iterator.h"
26#include "standard_dex_file.h"
27
28namespace art {
29
30class ArtMethod;
31
32// Abstracts accesses to the instruction fields of code items for CompactDexFile and
33// StandardDexFile.
34class CodeItemInstructionAccessor {
35 public:
Mathieu Chartier698ebbc2018-01-05 11:00:42 -080036 ALWAYS_INLINE CodeItemInstructionAccessor(const DexFile& dex_file,
Mathieu Chartier69147f12017-11-06 20:02:24 -080037 const DexFile::CodeItem* code_item);
38
39 ALWAYS_INLINE explicit CodeItemInstructionAccessor(ArtMethod* method);
40
41 ALWAYS_INLINE DexInstructionIterator begin() const;
42
43 ALWAYS_INLINE DexInstructionIterator end() const;
44
Mathieu Chartier808c7a52017-12-15 11:19:33 -080045 IterationRange<DexInstructionIterator> InstructionsFrom(uint32_t start_dex_pc) const;
46
Mathieu Chartier69147f12017-11-06 20:02:24 -080047 uint32_t InsnsSizeInCodeUnits() const {
48 return insns_size_in_code_units_;
49 }
50
51 const uint16_t* Insns() const {
52 return insns_;
53 }
54
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -080055 // Return the instruction for a dex pc.
56 const Instruction& InstructionAt(uint32_t dex_pc) const {
Mathieu Chartier808c7a52017-12-15 11:19:33 -080057 DCHECK_LT(dex_pc, InsnsSizeInCodeUnits());
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -080058 return *Instruction::At(insns_ + dex_pc);
59 }
60
Mathieu Chartier69147f12017-11-06 20:02:24 -080061 // Return true if the accessor has a code item.
62 bool HasCodeItem() const {
63 return Insns() != nullptr;
64 }
65
Mathieu Chartier69147f12017-11-06 20:02:24 -080066 protected:
67 CodeItemInstructionAccessor() = default;
68
69 ALWAYS_INLINE void Init(const CompactDexFile::CodeItem& code_item);
70 ALWAYS_INLINE void Init(const StandardDexFile::CodeItem& code_item);
Mathieu Chartier698ebbc2018-01-05 11:00:42 -080071 ALWAYS_INLINE void Init(const DexFile& dex_file, const DexFile::CodeItem* code_item);
Mathieu Chartier69147f12017-11-06 20:02:24 -080072
73 private:
74 // size of the insns array, in 2 byte code units. 0 if there is no code item.
75 uint32_t insns_size_in_code_units_ = 0;
76
77 // Pointer to the instructions, null if there is no code item.
78 const uint16_t* insns_ = 0;
79};
80
81// Abstracts accesses to code item fields other than debug info for CompactDexFile and
82// StandardDexFile.
83class CodeItemDataAccessor : public CodeItemInstructionAccessor {
84 public:
Mathieu Chartier698ebbc2018-01-05 11:00:42 -080085 ALWAYS_INLINE CodeItemDataAccessor(const DexFile& dex_file, const DexFile::CodeItem* code_item);
Mathieu Chartier69147f12017-11-06 20:02:24 -080086
87 ALWAYS_INLINE explicit CodeItemDataAccessor(ArtMethod* method);
88
89 uint16_t RegistersSize() const {
90 return registers_size_;
91 }
92
93 uint16_t InsSize() const {
94 return ins_size_;
95 }
96
97 uint16_t OutsSize() const {
98 return outs_size_;
99 }
100
101 uint16_t TriesSize() const {
102 return tries_size_;
103 }
104
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -0800105 IterationRange<const DexFile::TryItem*> TryItems() const;
106
107 const uint8_t* GetCatchHandlerData(size_t offset = 0) const;
108
109 const DexFile::TryItem* FindTryItem(uint32_t try_dex_pc) const;
110
Mathieu Chartier698ebbc2018-01-05 11:00:42 -0800111 inline const void* CodeItemDataEnd() const;
112
Mathieu Chartier69147f12017-11-06 20:02:24 -0800113 protected:
114 CodeItemDataAccessor() = default;
115
116 ALWAYS_INLINE void Init(const CompactDexFile::CodeItem& code_item);
117 ALWAYS_INLINE void Init(const StandardDexFile::CodeItem& code_item);
Mathieu Chartier698ebbc2018-01-05 11:00:42 -0800118 ALWAYS_INLINE void Init(const DexFile& dex_file, const DexFile::CodeItem* code_item);
Mathieu Chartier69147f12017-11-06 20:02:24 -0800119
120 private:
121 // Fields mirrored from the dex/cdex code item.
122 uint16_t registers_size_;
123 uint16_t ins_size_;
124 uint16_t outs_size_;
125 uint16_t tries_size_;
126};
127
Mathieu Chartier31f4c9f2017-12-08 15:46:11 -0800128// Abstract accesses to code item data including debug info offset. More heavy weight than the other
129// helpers.
130class CodeItemDebugInfoAccessor : public CodeItemDataAccessor {
131 public:
132 CodeItemDebugInfoAccessor() = default;
133
134 // Handles null code items, but not null dex files.
Mathieu Chartier698ebbc2018-01-05 11:00:42 -0800135 ALWAYS_INLINE CodeItemDebugInfoAccessor(const DexFile& dex_file,
Mathieu Chartier31f4c9f2017-12-08 15:46:11 -0800136 const DexFile::CodeItem* code_item);
137
Mathieu Chartier641a3af2017-12-15 11:42:58 -0800138 // Initialize with an existing offset.
Mathieu Chartier698ebbc2018-01-05 11:00:42 -0800139 ALWAYS_INLINE CodeItemDebugInfoAccessor(const DexFile& dex_file,
Mathieu Chartier641a3af2017-12-15 11:42:58 -0800140 const DexFile::CodeItem* code_item,
141 uint32_t debug_info_offset) {
142 Init(dex_file, code_item, debug_info_offset);
143 }
144
Mathieu Chartier698ebbc2018-01-05 11:00:42 -0800145 ALWAYS_INLINE void Init(const DexFile& dex_file,
Mathieu Chartier641a3af2017-12-15 11:42:58 -0800146 const DexFile::CodeItem* code_item,
147 uint32_t debug_info_offset);
148
Mathieu Chartier31f4c9f2017-12-08 15:46:11 -0800149 ALWAYS_INLINE explicit CodeItemDebugInfoAccessor(ArtMethod* method);
150
151 uint32_t DebugInfoOffset() const {
152 return debug_info_offset_;
153 }
154
Mathieu Chartier641a3af2017-12-15 11:42:58 -0800155 template<typename NewLocalCallback>
156 bool DecodeDebugLocalInfo(bool is_static,
157 uint32_t method_idx,
158 NewLocalCallback new_local,
159 void* context) const;
160
Mathieu Chartier31f4c9f2017-12-08 15:46:11 -0800161 protected:
162 ALWAYS_INLINE void Init(const CompactDexFile::CodeItem& code_item);
163 ALWAYS_INLINE void Init(const StandardDexFile::CodeItem& code_item);
164
165 private:
Mathieu Chartier641a3af2017-12-15 11:42:58 -0800166 const DexFile* dex_file_ = nullptr;
Mathieu Chartier31f4c9f2017-12-08 15:46:11 -0800167 uint32_t debug_info_offset_ = 0u;
168};
169
Mathieu Chartier69147f12017-11-06 20:02:24 -0800170} // namespace art
171
David Sehr9e734c72018-01-04 17:56:19 -0800172#endif // ART_RUNTIME_DEX_CODE_ITEM_ACCESSORS_H_