dex_file_method_inliner.h revision b48b9eb6d181a1f52e2e605cf26a21505f1d46ed
15c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko/*
25c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * Copyright (C) 2013 The Android Open Source Project
35c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko *
45c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * Licensed under the Apache License, Version 2.0 (the "License");
55c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * you may not use this file except in compliance with the License.
65c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * You may obtain a copy of the License at
75c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko *
85c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko *      http://www.apache.org/licenses/LICENSE-2.0
95c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko *
105c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * Unless required by applicable law or agreed to in writing, software
115c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * distributed under the License is distributed on an "AS IS" BASIS,
125c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * See the License for the specific language governing permissions and
145c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * limitations under the License.
155c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko */
165c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
175c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko#ifndef ART_COMPILER_DEX_QUICK_DEX_FILE_METHOD_INLINER_H_
185c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko#define ART_COMPILER_DEX_QUICK_DEX_FILE_METHOD_INLINER_H_
195c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
205c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko#include <stdint.h>
21e13717e796d338b08ea66f6a7e3470ca44de707fVladimir Marko#include "base/mutex.h"
22e13717e796d338b08ea66f6a7e3470ca44de707fVladimir Marko#include "base/macros.h"
23dce164adfbf679d7ec9c9dc778fa3fb596011740Ian Rogers#include "safe_map.h"
245816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex/compiler_enums.h"
255816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko#include "dex_file.h"
26e13717e796d338b08ea66f6a7e3470ca44de707fVladimir Marko#include "locks.h"
275c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
285c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Markonamespace art {
295c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
302bc47809febcf36369dd40877b8226318642b428Vladimir Markonamespace verifier {
312bc47809febcf36369dd40877b8226318642b428Vladimir Markoclass MethodVerifier;
322bc47809febcf36369dd40877b8226318642b428Vladimir Marko}  // namespace verifier
332bc47809febcf36369dd40877b8226318642b428Vladimir Marko
34b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogersstruct CallInfo;
355c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Markoclass Mir2Lir;
365c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
375816ed48bc339c983b40dc493e96b97821ce7966Vladimir Markoenum InlineMethodOpcode : uint16_t {
385c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicDoubleCvt,
395c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFloatCvt,
405c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicReverseBytes,
415c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicAbsInt,
425c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicAbsLong,
43dbb17e378b538133750e56375bbdbb217db7b248Yixin Shou  kIntrinsicAbsFloat,
44dbb17e378b538133750e56375bbdbb217db7b248Yixin Shou  kIntrinsicAbsDouble,
455c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicMinMaxInt,
465c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicSqrt,
475c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicCharAt,
485c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicCompareTo,
495c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicIsEmptyOrLength,
505c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicIndexOf,
515c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicCurrentThread,
525c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicPeek,
535c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicPoke,
541c282e2b9a9b432e132b2c332f861cad9feb4a73Vladimir Marko  kIntrinsicCas,
555c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicUnsafeGet,
565c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicUnsafePut,
575816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko
585816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko  kInlineOpNop,
595816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko  kInlineOpReturnArg,
603bc01748ef1c3e43361bdf520947a9d656658bf8Razvan A Lupusoru  kInlineOpNonWideConst,
615816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko  kInlineOpIGet,
625816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko  kInlineOpIPut,
635816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko};
64b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogersstd::ostream& operator<<(std::ostream& os, const InlineMethodOpcode& rhs);
655816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko
66dce164adfbf679d7ec9c9dc778fa3fb596011740Ian Rogersenum InlineMethodFlags : uint16_t {
67dce164adfbf679d7ec9c9dc778fa3fb596011740Ian Rogers  kNoInlineMethodFlags = 0x0000,
68dce164adfbf679d7ec9c9dc778fa3fb596011740Ian Rogers  kInlineIntrinsic     = 0x0001,
69dce164adfbf679d7ec9c9dc778fa3fb596011740Ian Rogers  kInlineSpecial       = 0x0002,
705816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko};
715816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko
722bc47809febcf36369dd40877b8226318642b428Vladimir Marko// IntrinsicFlags are stored in InlineMethod::d::raw_data
735c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Markoenum IntrinsicFlags {
745c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagNone = 0,
755c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
765c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  // kIntrinsicMinMaxInt
775c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagMax = kIntrinsicFlagNone,
785c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagMin = 1,
795c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
805c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  // kIntrinsicIsEmptyOrLength
815c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagLength  = kIntrinsicFlagNone,
82b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers  kIntrinsicFlagIsEmpty = kIntrinsicFlagMin,
835c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
845c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  // kIntrinsicIndexOf
85b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers  kIntrinsicFlagBase0 = kIntrinsicFlagMin,
865c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
871c282e2b9a9b432e132b2c332f861cad9feb4a73Vladimir Marko  // kIntrinsicUnsafeGet, kIntrinsicUnsafePut, kIntrinsicUnsafeCas
88b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers  kIntrinsicFlagIsLong     = kIntrinsicFlagMin,
891c282e2b9a9b432e132b2c332f861cad9feb4a73Vladimir Marko  // kIntrinsicUnsafeGet, kIntrinsicUnsafePut
905c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagIsVolatile = 2,
911c282e2b9a9b432e132b2c332f861cad9feb4a73Vladimir Marko  // kIntrinsicUnsafePut, kIntrinsicUnsafeCas
925c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagIsObject   = 4,
931c282e2b9a9b432e132b2c332f861cad9feb4a73Vladimir Marko  // kIntrinsicUnsafePut
945c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagIsOrdered  = 8,
955c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko};
965c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
975816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko// Check that OpSize fits into 3 bits (at least the values the inliner uses).
985816ed48bc339c983b40dc493e96b97821ce7966Vladimir MarkoCOMPILE_ASSERT(kWord < 8 && kLong < 8 && kSingle < 8 && kDouble < 8 && kUnsignedHalf < 8 &&
995816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko               kSignedHalf < 8 && kUnsignedByte < 8 && kSignedByte < 8, op_size_field_too_narrow);
1005816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko
1012bc47809febcf36369dd40877b8226318642b428Vladimir Markostruct InlineIGetIPutData {
1022bc47809febcf36369dd40877b8226318642b428Vladimir Marko  uint16_t op_size : 3;  // OpSize
1032bc47809febcf36369dd40877b8226318642b428Vladimir Marko  uint16_t is_object : 1;
1042bc47809febcf36369dd40877b8226318642b428Vladimir Marko  uint16_t object_arg : 4;
1052bc47809febcf36369dd40877b8226318642b428Vladimir Marko  uint16_t src_arg : 4;  // iput only
1062bc47809febcf36369dd40877b8226318642b428Vladimir Marko  uint16_t method_is_static : 1;
1072bc47809febcf36369dd40877b8226318642b428Vladimir Marko  uint16_t reserved : 3;
1082bc47809febcf36369dd40877b8226318642b428Vladimir Marko  uint16_t field_idx;
1092bc47809febcf36369dd40877b8226318642b428Vladimir Marko  uint32_t is_volatile : 1;
1102bc47809febcf36369dd40877b8226318642b428Vladimir Marko  uint32_t field_offset : 31;
1115dc5727261e87ba8a418e2d0e970c75f67e4ab79Vladimir Marko};
1122bc47809febcf36369dd40877b8226318642b428Vladimir MarkoCOMPILE_ASSERT(sizeof(InlineIGetIPutData) == sizeof(uint64_t), InvalidSizeOfInlineIGetIPutData);
1132bc47809febcf36369dd40877b8226318642b428Vladimir Marko
1142bc47809febcf36369dd40877b8226318642b428Vladimir Markostruct InlineReturnArgData {
1152bc47809febcf36369dd40877b8226318642b428Vladimir Marko  uint16_t arg;
1162bc47809febcf36369dd40877b8226318642b428Vladimir Marko  uint16_t op_size : 3;  // OpSize
1172bc47809febcf36369dd40877b8226318642b428Vladimir Marko  uint16_t is_object : 1;
1182bc47809febcf36369dd40877b8226318642b428Vladimir Marko  uint16_t reserved : 12;
1192bc47809febcf36369dd40877b8226318642b428Vladimir Marko  uint32_t reserved2;
1202bc47809febcf36369dd40877b8226318642b428Vladimir Marko};
1212bc47809febcf36369dd40877b8226318642b428Vladimir MarkoCOMPILE_ASSERT(sizeof(InlineReturnArgData) == sizeof(uint64_t), InvalidSizeOfInlineReturnArgData);
1222bc47809febcf36369dd40877b8226318642b428Vladimir Marko
1232bc47809febcf36369dd40877b8226318642b428Vladimir Markostruct InlineMethod {
1242bc47809febcf36369dd40877b8226318642b428Vladimir Marko  InlineMethodOpcode opcode;
1252bc47809febcf36369dd40877b8226318642b428Vladimir Marko  InlineMethodFlags flags;
1262bc47809febcf36369dd40877b8226318642b428Vladimir Marko  union {
1272bc47809febcf36369dd40877b8226318642b428Vladimir Marko    uint64_t data;
1282bc47809febcf36369dd40877b8226318642b428Vladimir Marko    InlineIGetIPutData ifield_data;
1292bc47809febcf36369dd40877b8226318642b428Vladimir Marko    InlineReturnArgData return_data;
1305816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko  } d;
1315816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko};
1325c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
1335c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko/**
1345c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * Handles inlining of methods from a particular DexFile.
1355c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko *
1365c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * Intrinsics are a special case of inline methods. The DexFile indices for
1375c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * all the supported intrinsic methods are looked up once by the FindIntrinsics
1385c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * function and cached by this class for quick lookup by the method index.
1395c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko *
1405c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * TODO: Detect short methods (at least getters, setters and empty functions)
1415c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * from the verifier and mark them for inlining. Inline these methods early
1425c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * during compilation to allow further optimizations. Similarly, provide
1435c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * additional information about intrinsics to the early phases of compilation.
1445c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko */
1455c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Markoclass DexFileMethodInliner {
1465c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  public:
147867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko    DexFileMethodInliner();
148867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko    ~DexFileMethodInliner();
1495c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
1505c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
1515816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko     * Analyse method code to determine if the method is a candidate for inlining.
1525816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko     * If it is, record its data for later.
1535816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko     *
15484c072c348006d87a370ad6e746e2d976cbe62f2Vladimir Marko     * @param verifier the method verifier holding data about the method to analyse.
15584c072c348006d87a370ad6e746e2d976cbe62f2Vladimir Marko     * @return true if the method is a candidate for inlining, false otherwise.
1565816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko     */
1572bc47809febcf36369dd40877b8226318642b428Vladimir Marko    bool AnalyseMethodCode(verifier::MethodVerifier* verifier)
1582bc47809febcf36369dd40877b8226318642b428Vladimir Marko        SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) LOCKS_EXCLUDED(lock_);
1595816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko
1605816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko    /**
16184c072c348006d87a370ad6e746e2d976cbe62f2Vladimir Marko     * Analyse method code to determine if the method is a candidate for inlining.
16284c072c348006d87a370ad6e746e2d976cbe62f2Vladimir Marko     * If it is, record the inlining data.
16384c072c348006d87a370ad6e746e2d976cbe62f2Vladimir Marko     *
16484c072c348006d87a370ad6e746e2d976cbe62f2Vladimir Marko     * @param verifier the method verifier holding data about the method to analyse.
16584c072c348006d87a370ad6e746e2d976cbe62f2Vladimir Marko     * @param method placeholder for the inline method data.
16684c072c348006d87a370ad6e746e2d976cbe62f2Vladimir Marko     * @return true if the method is a candidate for inlining, false otherwise.
16784c072c348006d87a370ad6e746e2d976cbe62f2Vladimir Marko     */
16884c072c348006d87a370ad6e746e2d976cbe62f2Vladimir Marko    bool AnalyseMethodCode(verifier::MethodVerifier* verifier, InlineMethod* method)
16984c072c348006d87a370ad6e746e2d976cbe62f2Vladimir Marko        SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) LOCKS_EXCLUDED(lock_);
17084c072c348006d87a370ad6e746e2d976cbe62f2Vladimir Marko
17184c072c348006d87a370ad6e746e2d976cbe62f2Vladimir Marko    /**
1725c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * Check whether a particular method index corresponds to an intrinsic function.
1735c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
174e13717e796d338b08ea66f6a7e3470ca44de707fVladimir Marko    bool IsIntrinsic(uint32_t method_index) LOCKS_EXCLUDED(lock_);
1755c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
1765c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
1775c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * Generate code for an intrinsic function invocation.
1785c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
179e13717e796d338b08ea66f6a7e3470ca44de707fVladimir Marko    bool GenIntrinsic(Mir2Lir* backend, CallInfo* info) LOCKS_EXCLUDED(lock_);
1805c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
1815816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko    /**
1825816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko     * Check whether a particular method index corresponds to a special function.
1835816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko     */
1845816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko    bool IsSpecial(uint32_t method_index) LOCKS_EXCLUDED(lock_);
1855816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko
1865816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko    /**
1875816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko     * Generate code for a special function.
1885816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko     */
1895816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko    bool GenSpecial(Mir2Lir* backend, uint32_t method_idx);
1905816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko
1915c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
1925c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * To avoid multiple lookups of a class by its descriptor, we cache its
1935c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * type index in the IndexCache. These are the indexes into the IndexCache
1945c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * class_indexes array.
1955c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
1965c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    enum ClassCacheIndex : uint8_t {  // unit8_t to save space, make larger if needed
1975c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheFirst = 0,
1985c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheBoolean = kClassCacheFirst,
1995c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheByte,
2005c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheChar,
2015c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheShort,
2025c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheInt,
2035c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheLong,
2045c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheFloat,
2055c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheDouble,
2065c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheVoid,
2075c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangObject,
2085c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangString,
2095c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangDouble,
2105c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangFloat,
2115c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangInteger,
2125c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangLong,
2135c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangShort,
2145c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangMath,
2155c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangStrictMath,
2165c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangThread,
2175c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheLibcoreIoMemory,
2185c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheSunMiscUnsafe,
2195c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheLast
2205c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    };
2215c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
2225c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
2235c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * To avoid multiple lookups of a method name string, we cache its string
2245c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * index in the IndexCache. These are the indexes into the IndexCache
2255c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * name_indexes array.
2265c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
2275c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    enum NameCacheIndex : uint8_t {  // unit8_t to save space, make larger if needed
2285c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheFirst = 0,
2295c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheReverseBytes = kNameCacheFirst,
2305c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheDoubleToRawLongBits,
2315c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheLongBitsToDouble,
2325c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheFloatToRawIntBits,
2335c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheIntBitsToFloat,
2345c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheAbs,
2355c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheMax,
2365c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheMin,
2375c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheSqrt,
2385c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheCharAt,
2395c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheCompareTo,
2405c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheIsEmpty,
2415c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheIndexOf,
2425c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheLength,
2435c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheCurrentThread,
2445c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePeekByte,
2455c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePeekIntNative,
2465c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePeekLongNative,
2475c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePeekShortNative,
2485c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePokeByte,
2495c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePokeIntNative,
2505c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePokeLongNative,
2515c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePokeShortNative,
2525c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheCompareAndSwapInt,
2531c282e2b9a9b432e132b2c332f861cad9feb4a73Vladimir Marko      kNameCacheCompareAndSwapLong,
2545c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheCompareAndSwapObject,
2555c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheGetInt,
2565c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheGetIntVolatile,
2575c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutInt,
2585c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutIntVolatile,
2595c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutOrderedInt,
2605c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheGetLong,
2615c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheGetLongVolatile,
2625c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutLong,
2635c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutLongVolatile,
2645c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutOrderedLong,
2655c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheGetObject,
2665c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheGetObjectVolatile,
2675c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutObject,
2685c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutObjectVolatile,
2695c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutOrderedObject,
2705c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheLast
2715c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    };
2725c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
2735c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
2745c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * To avoid multiple lookups of a method signature, we cache its proto
2755c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * index in the IndexCache. These are the indexes into the IndexCache
2765c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * proto_indexes array.
2775c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
2785c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    enum ProtoCacheIndex : uint8_t {  // unit8_t to save space, make larger if needed
2795c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheFirst = 0,
2805c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheI_I = kProtoCacheFirst,
2815c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJ_J,
2825c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheS_S,
2835c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheD_D,
284dbb17e378b538133750e56375bbdbb217db7b248Yixin Shou      kProtoCacheF_F,
2855c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheD_J,
2865c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJ_D,
2875c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheF_I,
2885c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheI_F,
2895c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheII_I,
2905c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheI_C,
2915c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheString_I,
2925c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCache_Z,
2935c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCache_I,
2945c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCache_Thread,
2955c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJ_B,
2965c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJ_I,
2975c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJ_S,
2985c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJB_V,
2995c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJI_V,
3005c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJJ_V,
3015c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJS_V,
3025c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJII_Z,
3031c282e2b9a9b432e132b2c332f861cad9feb4a73Vladimir Marko      kProtoCacheObjectJJJ_Z,
3045c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJObjectObject_Z,
3055c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJ_I,
3065c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJI_V,
3075c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJ_J,
3085c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJJ_V,
3095c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJ_Object,
3105c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJObject_V,
3115c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheLast
3125c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    };
3135c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
314b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers  private:
3155c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
3165c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * The maximum number of method parameters we support in the ProtoDef.
3175c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
3185c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static constexpr uint32_t kProtoMaxParams = 6;
3195c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
3205c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
3215c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * The method signature (proto) definition using cached class indexes.
3225c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * The return_type and params are used with the IndexCache to look up
3235c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * appropriate class indexes to be passed to DexFile::FindProtoId().
3245c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
3255c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    struct ProtoDef {
3265c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      ClassCacheIndex return_type;
3275c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      uint8_t param_count;
3285c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      ClassCacheIndex params[kProtoMaxParams];
3295c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    };
3305c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
3315c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
3325c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * The method definition using cached class, name and proto indexes.
3335c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * The class index, method name index and proto index are used with
3345c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * IndexCache to look up appropriate parameters for DexFile::FindMethodId().
3355c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
3365c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    struct MethodDef {
3375c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      ClassCacheIndex declaring_class;
3385c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      NameCacheIndex name;
3395c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      ProtoCacheIndex proto;
3405c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    };
3415c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
3425c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
3435c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * The definition of an intrinsic function binds the method definition
3445c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * to an Intrinsic.
3455c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
3465c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    struct IntrinsicDef {
3475c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      MethodDef method_def;
3485816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko      InlineMethod intrinsic;
3495c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    };
3505c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
3515c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
3525c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * Cache for class, method name and method signature indexes used during
3535c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * intrinsic function lookup to avoid multiple lookups of the same items.
3545c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     *
3555c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * Many classes have multiple intrinsics and/or they are used in multiple
3565c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * method signatures and we want to avoid repeated lookups since they are
3575c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * not exactly cheap. The method names and method signatures are sometimes
3585c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * reused and therefore cached as well.
3595c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
3605c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    struct IndexCache {
3615c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      IndexCache();
3625c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
3635c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      uint32_t class_indexes[kClassCacheLast - kClassCacheFirst];
3645c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      uint32_t name_indexes[kNameCacheLast - kNameCacheFirst];
3655c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      uint32_t proto_indexes[kProtoCacheLast - kProtoCacheFirst];
3665c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    };
3675c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
3685816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko    static const char* const kClassCacheNames[];
3695816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko    static const char* const kNameCacheNames[];
3705c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static const ProtoDef kProtoCacheDefs[];
371867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko    static const IntrinsicDef kIntrinsicMethods[];
3725c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
3735c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static const uint32_t kIndexNotFound = static_cast<uint32_t>(-1);
3745c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static const uint32_t kIndexUnresolved = static_cast<uint32_t>(-2);
3755c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
3765c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static uint32_t FindClassIndex(const DexFile* dex_file, IndexCache* cache,
3775c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko                                   ClassCacheIndex index);
3785c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static uint32_t FindNameIndex(const DexFile* dex_file, IndexCache* cache,
3795c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko                                  NameCacheIndex index);
3805c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static uint32_t FindProtoIndex(const DexFile* dex_file, IndexCache* cache,
3815c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko                                   ProtoCacheIndex index);
3825c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static uint32_t FindMethodIndex(const DexFile* dex_file, IndexCache* cache,
3835c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko                                    const MethodDef& method_def);
3845c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
385867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko    /**
386867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko     * Find all known intrinsic methods in the dex_file and cache their indices.
387867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko     *
388867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko     * Only DexFileToMethodInlinerMap may call this function to initialize the inliner.
389867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko     */
390e13717e796d338b08ea66f6a7e3470ca44de707fVladimir Marko    void FindIntrinsics(const DexFile* dex_file) EXCLUSIVE_LOCKS_REQUIRED(lock_);
391867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko
392867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko    friend class DexFileToMethodInlinerMap;
3935c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
3942bc47809febcf36369dd40877b8226318642b428Vladimir Marko    bool AddInlineMethod(int32_t method_idx, const InlineMethod& method) LOCKS_EXCLUDED(lock_);
3952bc47809febcf36369dd40877b8226318642b428Vladimir Marko
3962bc47809febcf36369dd40877b8226318642b428Vladimir Marko    static bool AnalyseReturnMethod(const DexFile::CodeItem* code_item, InlineMethod* result);
3972bc47809febcf36369dd40877b8226318642b428Vladimir Marko    static bool AnalyseConstMethod(const DexFile::CodeItem* code_item, InlineMethod* result);
3982bc47809febcf36369dd40877b8226318642b428Vladimir Marko    static bool AnalyseIGetMethod(verifier::MethodVerifier* verifier, InlineMethod* result)
3992bc47809febcf36369dd40877b8226318642b428Vladimir Marko        SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
4002bc47809febcf36369dd40877b8226318642b428Vladimir Marko    static bool AnalyseIPutMethod(verifier::MethodVerifier* verifier, InlineMethod* result)
4012bc47809febcf36369dd40877b8226318642b428Vladimir Marko        SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
4025816ed48bc339c983b40dc493e96b97821ce7966Vladimir Marko
403e13717e796d338b08ea66f6a7e3470ca44de707fVladimir Marko    ReaderWriterMutex lock_;
4045c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /*
4055c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * Maps method indexes (for the particular DexFile) to Intrinsic defintions.
4065c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
407dce164adfbf679d7ec9c9dc778fa3fb596011740Ian Rogers    SafeMap<uint32_t, InlineMethod> inline_methods_ GUARDED_BY(lock_);
4085c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    const DexFile* dex_file_;
409867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko
410867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko    DISALLOW_COPY_AND_ASSIGN(DexFileMethodInliner);
4115c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko};
4125c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
4135c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko}  // namespace art
4145c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
4155c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko#endif  // ART_COMPILER_DEX_QUICK_DEX_FILE_METHOD_INLINER_H_
416