blob: bd320ce2a2889cc2128bb0f8451c64ef8ade4a03 [file] [log] [blame]
Ian Rogers776ac1f2012-04-13 23:36:36 -07001/*
2 * Copyright (C) 2011 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
Brian Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_
18#define ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_
Ian Rogers776ac1f2012-04-13 23:36:36 -070019
Ian Rogers700a4022014-05-19 16:49:03 -070020#include <memory>
Vladimir Marko637ee0b2015-09-04 12:47:41 +010021#include <sstream>
Ian Rogers776ac1f2012-04-13 23:36:36 -070022#include <vector>
23
Andreas Gampe51de69e2019-04-19 15:14:14 -070024#include <android-base/logging.h>
25
Mathieu Chartierde40d472015-10-15 17:47:48 -070026#include "base/arena_allocator.h"
Elliott Hughes76160052012-12-12 16:31:20 -080027#include "base/macros.h"
Mathieu Chartierde40d472015-10-15 17:47:48 -070028#include "base/scoped_arena_containers.h"
Andreas Gampe9fcfb8a2016-02-04 20:52:54 -080029#include "base/value_object.h"
David Sehr9e734c72018-01-04 17:56:19 -080030#include "dex/code_item_accessors.h"
David Sehr9e734c72018-01-04 17:56:19 -080031#include "dex/dex_file_types.h"
David Sehr312f3b22018-03-19 08:39:26 -070032#include "dex/method_reference.h"
Hiroshi Yamauchidc376172014-08-22 11:13:12 -070033#include "handle.h"
Ian Rogers7b3ddd22013-02-21 15:19:52 -080034#include "instruction_flags.h"
Ian Rogers576ca0c2014-06-06 15:58:22 -070035#include "reg_type_cache.h"
Andreas Gampe8cf9cb32017-07-19 09:28:38 -070036#include "register_line.h"
Andreas Gampe6d7abbd2017-04-24 13:19:09 -070037#include "verifier_enums.h"
Ian Rogers776ac1f2012-04-13 23:36:36 -070038
39namespace art {
40
Andreas Gamped482e732017-04-24 17:59:09 -070041class ClassLinker;
Andreas Gampe53e32d12015-12-09 21:03:23 -080042class CompilerCallbacks;
Andreas Gampe3f1dcd32018-12-28 09:39:56 -080043class DexFile;
Ian Rogers8e1f4f82014-11-05 11:07:30 -080044class Instruction;
Ian Rogers776ac1f2012-04-13 23:36:36 -070045struct ReferenceMap2Visitor;
Mathieu Chartierd0ad2ee2015-03-31 14:59:59 -070046class Thread;
Vladimir Marko8f1e08a2015-06-26 12:06:30 +010047class VariableIndentationOutputStream;
Ian Rogers776ac1f2012-04-13 23:36:36 -070048
Andreas Gampe3f1dcd32018-12-28 09:39:56 -080049namespace dex {
50struct ClassDef;
51struct CodeItem;
52} // namespace dex
53
Andreas Gamped482e732017-04-24 17:59:09 -070054namespace mirror {
55class DexCache;
56} // namespace mirror
57
Ian Rogers776ac1f2012-04-13 23:36:36 -070058namespace verifier {
59
Ian Rogers8e1f4f82014-11-05 11:07:30 -080060class MethodVerifier;
61class RegisterLine;
Mathieu Chartier361e04a2016-02-16 14:06:35 -080062using RegisterLineArenaUniquePtr = std::unique_ptr<RegisterLine, RegisterLineArenaDelete>;
Ian Rogers8e1f4f82014-11-05 11:07:30 -080063class RegType;
Andreas Gampe2ad6cce2019-04-11 16:17:39 -070064struct ScopedNewLine;
Ian Rogers776ac1f2012-04-13 23:36:36 -070065
Ian Rogers776ac1f2012-04-13 23:36:36 -070066// We don't need to store the register data for many instructions, because we either only need
67// it at branch points (for verification) or GC points and branches (for verification +
68// type-precise register analysis).
69enum RegisterTrackingMode {
70 kTrackRegsBranches,
Sameer Abu Asal02c42232013-04-30 12:09:45 -070071 kTrackCompilerInterestPoints,
Ian Rogers776ac1f2012-04-13 23:36:36 -070072 kTrackRegsAll,
73};
74
Ian Rogers2bcb4a42012-11-08 10:39:18 -080075// A mapping from a dex pc to the register line statuses as they are immediately prior to the
76// execution of that instruction.
Ian Rogers776ac1f2012-04-13 23:36:36 -070077class PcToRegisterLineTable {
78 public:
Vladimir Marko69d310e2017-10-09 14:12:23 +010079 explicit PcToRegisterLineTable(ScopedArenaAllocator& allocator);
Ian Rogersd0fbd852013-09-24 18:17:04 -070080 ~PcToRegisterLineTable();
Ian Rogers776ac1f2012-04-13 23:36:36 -070081
82 // Initialize the RegisterTable. Every instruction address can have a different set of information
83 // about what's in which register, but for verification purposes we only need to store it at
84 // branch target addresses (because we merge into that).
Andreas Gamped09c0592019-04-19 15:44:05 -070085 void Init(RegisterTrackingMode mode,
86 InstructionFlags* flags,
87 uint32_t insns_size,
88 uint16_t registers_size,
89 ScopedArenaAllocator& allocator,
90 RegTypeCache* reg_types);
Ian Rogers776ac1f2012-04-13 23:36:36 -070091
Andreas Gampe077d9db2018-01-19 18:54:14 -080092 bool IsInitialized() const {
93 return !register_lines_.empty();
94 }
95
Mathieu Chartierde40d472015-10-15 17:47:48 -070096 RegisterLine* GetLine(size_t idx) const {
97 return register_lines_[idx].get();
Ian Rogers776ac1f2012-04-13 23:36:36 -070098 }
99
100 private:
Mathieu Chartier361e04a2016-02-16 14:06:35 -0800101 ScopedArenaVector<RegisterLineArenaUniquePtr> register_lines_;
Ian Rogers8e1f4f82014-11-05 11:07:30 -0800102
103 DISALLOW_COPY_AND_ASSIGN(PcToRegisterLineTable);
Ian Rogers776ac1f2012-04-13 23:36:36 -0700104};
105
106// The verifier
107class MethodVerifier {
108 public:
Vladimir Marko8f1e08a2015-06-26 12:06:30 +0100109 static MethodVerifier* VerifyMethodAndDump(Thread* self,
110 VariableIndentationOutputStream* vios,
111 uint32_t method_idx,
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700112 const DexFile* dex_file,
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700113 Handle<mirror::DexCache> dex_cache,
114 Handle<mirror::ClassLoader> class_loader,
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800115 const dex::ClassDef& class_def,
116 const dex::CodeItem* code_item, ArtMethod* method,
Andreas Gampe6cc23ac2018-08-24 15:22:43 -0700117 uint32_t method_access_flags,
118 uint32_t api_level)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700119 REQUIRES_SHARED(Locks::mutator_lock_);
Ian Rogers2bcb4a42012-11-08 10:39:18 -0800120
Alex Lighte2ddce32019-05-22 17:08:35 +0000121 // Calculates the verification information for every instruction of the given method. The given
122 // dex-cache and class-loader will be used for lookups. No classes will be loaded. If verification
123 // fails hard nullptr will be returned. This should only be used if one needs to examine what the
124 // verifier believes about the registers of a given method.
125 static MethodVerifier* CalculateVerificationInfo(Thread* self,
126 ArtMethod* method,
127 Handle<mirror::DexCache> dex_cache,
128 Handle<mirror::ClassLoader> class_loader)
129 REQUIRES_SHARED(Locks::mutator_lock_);
130
David Brazdilca3c8c32016-09-06 14:04:48 +0100131 const DexFile& GetDexFile() const {
132 DCHECK(dex_file_ != nullptr);
133 return *dex_file_;
134 }
135
Ian Rogers776ac1f2012-04-13 23:36:36 -0700136 RegTypeCache* GetRegTypeCache() {
137 return &reg_types_;
138 }
139
Ian Rogersad0b3a32012-04-16 14:50:24 -0700140 // Log a verification failure.
Ian Rogers776ac1f2012-04-13 23:36:36 -0700141 std::ostream& Fail(VerifyError error);
142
Ian Rogersad0b3a32012-04-16 14:50:24 -0700143 // Log for verification information.
Andreas Gampe2ad6cce2019-04-11 16:17:39 -0700144 ScopedNewLine LogVerifyInfo();
Ian Rogers776ac1f2012-04-13 23:36:36 -0700145
Andreas Gampeaaf0d382017-11-27 14:10:21 -0800146 // Information structure for a lock held at a certain point in time.
147 struct DexLockInfo {
148 // The registers aliasing the lock.
149 std::set<uint32_t> dex_registers;
150 // The dex PC of the monitor-enter instruction.
151 uint32_t dex_pc;
152
153 explicit DexLockInfo(uint32_t dex_pc_in) {
154 dex_pc = dex_pc_in;
155 }
156 };
Elliott Hughes08fc03a2012-06-26 17:34:00 -0700157 // Fills 'monitor_enter_dex_pcs' with the dex pcs of the monitor-enter instructions corresponding
Sebastien Hertz2d6ba512013-05-17 11:31:37 +0200158 // to the locks held at 'dex_pc' in method 'm'.
Nicolas Geoffrayb041a402017-11-13 15:16:22 +0000159 // Note: this is the only situation where the verifier will visit quickened instructions.
Andreas Gampe6cc23ac2018-08-24 15:22:43 -0700160 static void FindLocksAtDexPc(ArtMethod* m,
161 uint32_t dex_pc,
162 std::vector<DexLockInfo>* monitor_enter_dex_pcs,
163 uint32_t api_level)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700164 REQUIRES_SHARED(Locks::mutator_lock_);
Elliott Hughes08fc03a2012-06-26 17:34:00 -0700165
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700166 static void Init() REQUIRES_SHARED(Locks::mutator_lock_);
Elliott Hughes0a1038b2012-06-14 16:24:17 -0700167 static void Shutdown();
Ian Rogers776ac1f2012-04-13 23:36:36 -0700168
Andreas Gampefc25ae92019-04-19 22:22:57 -0700169 virtual ~MethodVerifier();
Sebastien Hertz33691ab2013-08-02 14:19:57 +0200170
Mathieu Chartierbb87e0f2015-04-03 11:21:55 -0700171 static void VisitStaticRoots(RootVisitor* visitor)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700172 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartierbb87e0f2015-04-03 11:21:55 -0700173 void VisitRoots(RootVisitor* visitor, const RootInfo& roots)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700174 REQUIRES_SHARED(Locks::mutator_lock_);
Mathieu Chartierc528dba2013-11-26 12:00:11 -0800175
Vladimir Marko2b5eaa22013-12-13 13:59:30 +0000176 // Accessors used by the compiler via CompilerCallback
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -0800177 const CodeItemDataAccessor& CodeItem() const {
178 return code_item_accessor_;
179 }
Vladimir Marko2b5eaa22013-12-13 13:59:30 +0000180 RegisterLine* GetRegLine(uint32_t dex_pc);
Mathieu Chartierde40d472015-10-15 17:47:48 -0700181 ALWAYS_INLINE const InstructionFlags& GetInstructionFlags(size_t index) const;
Andreas Gampe51de69e2019-04-19 15:14:14 -0700182
Vladimir Marko2b5eaa22013-12-13 13:59:30 +0000183 MethodReference GetMethodReference() const;
Vladimir Marko2b5eaa22013-12-13 13:59:30 +0000184 bool HasCheckCasts() const;
Vladimir Marko2b5eaa22013-12-13 13:59:30 +0000185 bool HasFailures() const;
Nicolas Geoffray4824c272015-06-24 15:53:03 +0100186 bool HasInstructionThatWillThrow() const {
Andreas Gamped12e7822015-06-25 10:26:40 -0700187 return have_any_pending_runtime_throw_failure_;
Nicolas Geoffray4824c272015-06-24 15:53:03 +0100188 }
189
Andreas Gampefc25ae92019-04-19 22:22:57 -0700190 virtual const RegType& ResolveCheckedClass(dex::TypeIndex class_idx)
191 REQUIRES_SHARED(Locks::mutator_lock_) = 0;
Vladimir Marko2b5eaa22013-12-13 13:59:30 +0000192
Andreas Gampe0760a812015-08-26 17:12:51 -0700193 uint32_t GetEncounteredFailureTypes() {
194 return encountered_failure_types_;
195 }
196
Andreas Gampefc25ae92019-04-19 22:22:57 -0700197 protected:
Andreas Gampe53e32d12015-12-09 21:03:23 -0800198 MethodVerifier(Thread* self,
199 const DexFile* dex_file,
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800200 const dex::CodeItem* code_item,
Andreas Gampefc25ae92019-04-19 22:22:57 -0700201 uint32_t dex_method_idx,
Andreas Gampe53e32d12015-12-09 21:03:23 -0800202 bool can_load_classes,
Andreas Gampe6cc23ac2018-08-24 15:22:43 -0700203 bool allow_thread_suspension,
Andreas Gampefc25ae92019-04-19 22:22:57 -0700204 bool allow_soft_failures)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700205 REQUIRES_SHARED(Locks::mutator_lock_);
Andreas Gampe2ed8def2014-08-28 14:41:02 -0700206
Andreas Gampe9fcfb8a2016-02-04 20:52:54 -0800207 // Verification result for method(s). Includes a (maximum) failure kind, and (the union of)
208 // all failure types.
209 struct FailureData : ValueObject {
Andreas Gampe6d7abbd2017-04-24 13:19:09 -0700210 FailureKind kind = FailureKind::kNoFailure;
Andreas Gampe9fcfb8a2016-02-04 20:52:54 -0800211 uint32_t types = 0U;
212
213 // Merge src into this. Uses the most severe failure kind, and the union of types.
214 void Merge(const FailureData& src);
215 };
216
Ian Rogers776ac1f2012-04-13 23:36:36 -0700217 /*
218 * Perform verification on a single method.
219 *
220 * We do this in three passes:
221 * (1) Walk through all code units, determining instruction locations,
222 * widths, and other characteristics.
223 * (2) Walk through all code units, performing static checks on
224 * operands.
225 * (3) Iterate through the method, checking type safety and looking
226 * for code flow problems.
Ian Rogerse1758fe2012-04-19 11:31:15 -0700227 */
David Brazdilca3c8c32016-09-06 14:04:48 +0100228 static FailureData VerifyMethod(Thread* self,
229 uint32_t method_idx,
Andreas Gampeec6e6c12015-11-05 20:39:56 -0800230 const DexFile* dex_file,
Andreas Gampe5a4b8a22014-09-11 08:30:08 -0700231 Handle<mirror::DexCache> dex_cache,
232 Handle<mirror::ClassLoader> class_loader,
Andreas Gampe3f1dcd32018-12-28 09:39:56 -0800233 const dex::ClassDef& class_def_idx,
234 const dex::CodeItem* code_item,
Andreas Gampeec6e6c12015-11-05 20:39:56 -0800235 ArtMethod* method,
236 uint32_t method_access_flags,
Andreas Gampe53e32d12015-12-09 21:03:23 -0800237 CompilerCallbacks* callbacks,
Andreas Gampeec6e6c12015-11-05 20:39:56 -0800238 bool allow_soft_failures,
Andreas Gampe5fd66d02016-09-12 20:22:19 -0700239 HardFailLogMode log_level,
Andreas Gampeec6e6c12015-11-05 20:39:56 -0800240 bool need_precise_constants,
Andreas Gampe6cc23ac2018-08-24 15:22:43 -0700241 uint32_t api_level,
Andreas Gampeec6e6c12015-11-05 20:39:56 -0800242 std::string* hard_failure_msg)
Andreas Gampebdf7f1c2016-08-30 16:38:47 -0700243 REQUIRES_SHARED(Locks::mutator_lock_);
Ian Rogerse1758fe2012-04-19 11:31:15 -0700244
Andreas Gampe99db7bb2019-04-19 23:05:47 -0700245 template <bool kVerifierDebug>
246 static FailureData VerifyMethod(Thread* self,
247 uint32_t method_idx,
248 const DexFile* dex_file,
249 Handle<mirror::DexCache> dex_cache,
250 Handle<mirror::ClassLoader> class_loader,
251 const dex::ClassDef& class_def_idx,
252 const dex::CodeItem* code_item,
253 ArtMethod* method,
254 uint32_t method_access_flags,
255 CompilerCallbacks* callbacks,
256 bool allow_soft_failures,
257 HardFailLogMode log_level,
258 bool need_precise_constants,
259 uint32_t api_level,
260 std::string* hard_failure_msg)
261 REQUIRES_SHARED(Locks::mutator_lock_);
262
Andreas Gampefc25ae92019-04-19 22:22:57 -0700263 // For VerifierDepsTest. TODO: Refactor.
Andreas Gampe51de69e2019-04-19 15:14:14 -0700264
265 // Run verification on the method. Returns true if verification completes and false if the input
266 // has an irrecoverable corruption.
Andreas Gampefc25ae92019-04-19 22:22:57 -0700267 virtual bool Verify() REQUIRES_SHARED(Locks::mutator_lock_) = 0;
268 static MethodVerifier* CreateVerifier(Thread* self,
269 const DexFile* dex_file,
270 Handle<mirror::DexCache> dex_cache,
271 Handle<mirror::ClassLoader> class_loader,
272 const dex::ClassDef& class_def,
273 const dex::CodeItem* code_item,
274 uint32_t method_idx,
275 ArtMethod* method,
276 uint32_t access_flags,
277 bool can_load_classes,
278 bool allow_soft_failures,
279 bool need_precise_constants,
280 bool verify_to_dump,
281 bool allow_thread_suspension,
282 uint32_t api_level)
283 REQUIRES_SHARED(Locks::mutator_lock_);
Andreas Gampe51de69e2019-04-19 15:14:14 -0700284
Ian Rogers7b078e82014-09-10 14:44:24 -0700285 // The thread we're verifying on.
286 Thread* const self_;
287
Mathieu Chartierde40d472015-10-15 17:47:48 -0700288 // Arena allocator.
289 ArenaStack arena_stack_;
Vladimir Marko69d310e2017-10-09 14:12:23 +0100290 ScopedArenaAllocator allocator_;
Mathieu Chartierde40d472015-10-15 17:47:48 -0700291
Ian Rogers776ac1f2012-04-13 23:36:36 -0700292 RegTypeCache reg_types_;
293
294 PcToRegisterLineTable reg_table_;
295
296 // Storage for the register status we're currently working on.
Mathieu Chartier361e04a2016-02-16 14:06:35 -0800297 RegisterLineArenaUniquePtr work_line_;
Ian Rogers776ac1f2012-04-13 23:36:36 -0700298
299 // The address of the instruction we're currently working on, note that this is in 2 byte
300 // quantities
301 uint32_t work_insn_idx_;
302
303 // Storage for the register status we're saving for later.
Mathieu Chartier361e04a2016-02-16 14:06:35 -0800304 RegisterLineArenaUniquePtr saved_line_;
Ian Rogers776ac1f2012-04-13 23:36:36 -0700305
Ian Rogers637c65b2013-05-31 11:46:00 -0700306 const uint32_t dex_method_idx_; // The method we're working on.
Ian Rogers637c65b2013-05-31 11:46:00 -0700307 const DexFile* const dex_file_; // The dex file containing the method.
Mathieu Chartier3da1d0f2017-11-06 20:02:24 -0800308 const CodeItemDataAccessor code_item_accessor_;
Andreas Gampefc25ae92019-04-19 22:22:57 -0700309
Ian Rogers7b3ddd22013-02-21 15:19:52 -0800310 // Instruction widths and flags, one entry per code unit.
Mathieu Chartierde40d472015-10-15 17:47:48 -0700311 // Owned, but not unique_ptr since insn_flags_ are allocated in arenas.
312 ArenaUniquePtr<InstructionFlags[]> insn_flags_;
Elliott Hughes08fc03a2012-06-26 17:34:00 -0700313
Ian Rogersad0b3a32012-04-16 14:50:24 -0700314 // The types of any error that occurs.
315 std::vector<VerifyError> failures_;
316 // Error messages associated with failures.
317 std::vector<std::ostringstream*> failure_messages_;
318 // Is there a pending hard failure?
319 bool have_pending_hard_failure_;
jeffhaofaf459e2012-08-31 15:32:47 -0700320 // Is there a pending runtime throw failure? A runtime throw failure is when an instruction
321 // would fail at runtime throwing an exception. Such an instruction causes the following code
322 // to be unreachable. This is set by Fail and used to ensure we don't process unreachable
323 // instructions that would hard fail the verification.
Andreas Gamped12e7822015-06-25 10:26:40 -0700324 // Note: this flag is reset after processing each instruction.
jeffhaofaf459e2012-08-31 15:32:47 -0700325 bool have_pending_runtime_throw_failure_;
Igor Murashkin4d7b75f2015-07-21 17:03:36 -0700326 // Is there a pending experimental failure?
327 bool have_pending_experimental_failure_;
Ian Rogers776ac1f2012-04-13 23:36:36 -0700328
Andreas Gamped12e7822015-06-25 10:26:40 -0700329 // A version of the above that is not reset and thus captures if there were *any* throw failures.
330 bool have_any_pending_runtime_throw_failure_;
331
Ian Rogersad0b3a32012-04-16 14:50:24 -0700332 // Info message log use primarily for verifier diagnostics.
Ian Rogers776ac1f2012-04-13 23:36:36 -0700333 std::ostringstream info_messages_;
334
Andreas Gampe0760a812015-08-26 17:12:51 -0700335 // Bitset of the encountered failure types. Bits are according to the values in VerifyError.
336 uint32_t encountered_failure_types_;
337
Elliott Hughes80537bb2013-01-04 16:37:26 -0800338 const bool can_load_classes_;
Jeff Haoee988952013-04-16 14:23:47 -0700339
340 // Converts soft failures to hard failures when false. Only false when the compiler isn't
341 // running and the verifier is called from the class linker.
342 const bool allow_soft_failures_;
Sebastien Hertz4d4adb12013-07-24 16:14:19 +0200343
Ian Rogersa9a82542013-10-04 11:17:26 -0700344 // Indicates the method being verified contains at least one check-cast or aput-object
345 // instruction. Aput-object operations implicitly check for array-store exceptions, similar to
346 // check-cast.
Sebastien Hertz4d4adb12013-07-24 16:14:19 +0200347 bool has_check_casts_;
348
Mathieu Chartierd0ad2ee2015-03-31 14:59:59 -0700349 // Link, for the method verifier root linked list.
350 MethodVerifier* link_;
351
352 friend class art::Thread;
Andreas Gampea43ba3d2019-03-13 15:49:20 -0700353 friend class ClassVerifier;
David Brazdilca3c8c32016-09-06 14:04:48 +0100354 friend class VerifierDepsTest;
Jeff Hao848f70a2014-01-15 13:49:50 -0800355
Ian Rogers8e1f4f82014-11-05 11:07:30 -0800356 DISALLOW_COPY_AND_ASSIGN(MethodVerifier);
Ian Rogers776ac1f2012-04-13 23:36:36 -0700357};
Ian Rogers776ac1f2012-04-13 23:36:36 -0700358
359} // namespace verifier
360} // namespace art
361
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700362#endif // ART_RUNTIME_VERIFIER_METHOD_VERIFIER_H_