dex_file_method_inliner.h revision 867a2b35e67ddcbec089964e8f3cd9a827186e48
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>
215c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko#include <map>
225c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
235c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Markonamespace art {
245c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
255c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Markoclass CallInfo;
265c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Markoclass DexFile;
275c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Markoclass Mir2Lir;
285c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
295c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Markoenum IntrinsicOpcode {
305c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicDoubleCvt,
315c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFloatCvt,
325c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicReverseBytes,
335c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicAbsInt,
345c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicAbsLong,
355c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicMinMaxInt,
365c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicSqrt,
375c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicCharAt,
385c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicCompareTo,
395c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicIsEmptyOrLength,
405c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicIndexOf,
415c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicCurrentThread,
425c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicPeek,
435c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicPoke,
441c282e2b9a9b432e132b2c332f861cad9feb4a73Vladimir Marko  kIntrinsicCas,
455c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicUnsafeGet,
465c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicUnsafePut,
475c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko};
485c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
495c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Markoenum IntrinsicFlags {
505c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagNone = 0,
515c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
525c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  // kIntrinsicMinMaxInt
535c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagMax = kIntrinsicFlagNone,
545c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagMin = 1,
555c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
565c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  // kIntrinsicIsEmptyOrLength
575c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagLength  = kIntrinsicFlagNone,
585c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagIsEmpty = 1,
595c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
605c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  // kIntrinsicIndexOf
615c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagBase0 = 1,
625c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
631c282e2b9a9b432e132b2c332f861cad9feb4a73Vladimir Marko  // kIntrinsicUnsafeGet, kIntrinsicUnsafePut, kIntrinsicUnsafeCas
645c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagIsLong     = 1,
651c282e2b9a9b432e132b2c332f861cad9feb4a73Vladimir Marko  // kIntrinsicUnsafeGet, kIntrinsicUnsafePut
665c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagIsVolatile = 2,
671c282e2b9a9b432e132b2c332f861cad9feb4a73Vladimir Marko  // kIntrinsicUnsafePut, kIntrinsicUnsafeCas
685c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagIsObject   = 4,
691c282e2b9a9b432e132b2c332f861cad9feb4a73Vladimir Marko  // kIntrinsicUnsafePut
705c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  kIntrinsicFlagIsOrdered  = 8,
715c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko};
725c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
735c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Markostruct Intrinsic {
745c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  IntrinsicOpcode opcode;
755c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  uint32_t data;
765c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko};
775c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
785c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko/**
795c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * Handles inlining of methods from a particular DexFile.
805c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko *
815c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * Intrinsics are a special case of inline methods. The DexFile indices for
825c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * all the supported intrinsic methods are looked up once by the FindIntrinsics
835c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * function and cached by this class for quick lookup by the method index.
845c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko *
855c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * TODO: Detect short methods (at least getters, setters and empty functions)
865c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * from the verifier and mark them for inlining. Inline these methods early
875c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * during compilation to allow further optimizations. Similarly, provide
885c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko * additional information about intrinsics to the early phases of compilation.
895c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko */
905c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Markoclass DexFileMethodInliner {
915c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko  public:
92867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko    DexFileMethodInliner();
93867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko    ~DexFileMethodInliner();
945c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
955c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
965c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * Check whether a particular method index corresponds to an intrinsic function.
975c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
985c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    bool IsIntrinsic(uint32_t method_index) const;
995c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
1005c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
1015c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * Generate code for an intrinsic function invocation.
1025c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
1035c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    bool GenIntrinsic(Mir2Lir* backend, CallInfo* info) const;
1045c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
105867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko  private:
1065c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
1075c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * To avoid multiple lookups of a class by its descriptor, we cache its
1085c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * type index in the IndexCache. These are the indexes into the IndexCache
1095c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * class_indexes array.
1105c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
1115c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    enum ClassCacheIndex : uint8_t {  // unit8_t to save space, make larger if needed
1125c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheFirst = 0,
1135c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheBoolean = kClassCacheFirst,
1145c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheByte,
1155c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheChar,
1165c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheShort,
1175c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheInt,
1185c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheLong,
1195c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheFloat,
1205c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheDouble,
1215c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheVoid,
1225c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangObject,
1235c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangString,
1245c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangDouble,
1255c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangFloat,
1265c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangInteger,
1275c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangLong,
1285c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangShort,
1295c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangMath,
1305c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangStrictMath,
1315c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheJavaLangThread,
1325c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheLibcoreIoMemory,
1335c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheSunMiscUnsafe,
1345c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kClassCacheLast
1355c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    };
1365c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
1375c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
1385c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * To avoid multiple lookups of a method name string, we cache its string
1395c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * index in the IndexCache. These are the indexes into the IndexCache
1405c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * name_indexes array.
1415c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
1425c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    enum NameCacheIndex : uint8_t {  // unit8_t to save space, make larger if needed
1435c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheFirst = 0,
1445c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheReverseBytes = kNameCacheFirst,
1455c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheDoubleToRawLongBits,
1465c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheLongBitsToDouble,
1475c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheFloatToRawIntBits,
1485c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheIntBitsToFloat,
1495c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheAbs,
1505c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheMax,
1515c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheMin,
1525c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheSqrt,
1535c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheCharAt,
1545c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheCompareTo,
1555c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheIsEmpty,
1565c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheIndexOf,
1575c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheLength,
1585c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheCurrentThread,
1595c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePeekByte,
1605c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePeekIntNative,
1615c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePeekLongNative,
1625c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePeekShortNative,
1635c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePokeByte,
1645c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePokeIntNative,
1655c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePokeLongNative,
1665c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePokeShortNative,
1675c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheCompareAndSwapInt,
1681c282e2b9a9b432e132b2c332f861cad9feb4a73Vladimir Marko      kNameCacheCompareAndSwapLong,
1695c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheCompareAndSwapObject,
1705c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheGetInt,
1715c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheGetIntVolatile,
1725c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutInt,
1735c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutIntVolatile,
1745c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutOrderedInt,
1755c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheGetLong,
1765c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheGetLongVolatile,
1775c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutLong,
1785c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutLongVolatile,
1795c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutOrderedLong,
1805c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheGetObject,
1815c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheGetObjectVolatile,
1825c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutObject,
1835c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutObjectVolatile,
1845c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCachePutOrderedObject,
1855c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kNameCacheLast
1865c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    };
1875c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
1885c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
1895c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * To avoid multiple lookups of a method signature, we cache its proto
1905c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * index in the IndexCache. These are the indexes into the IndexCache
1915c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * proto_indexes array.
1925c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
1935c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    enum ProtoCacheIndex : uint8_t {  // unit8_t to save space, make larger if needed
1945c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheFirst = 0,
1955c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheI_I = kProtoCacheFirst,
1965c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJ_J,
1975c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheS_S,
1985c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheD_D,
1995c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheD_J,
2005c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJ_D,
2015c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheF_I,
2025c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheI_F,
2035c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheII_I,
2045c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheI_C,
2055c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheString_I,
2065c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCache_Z,
2075c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCache_I,
2085c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCache_Thread,
2095c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJ_B,
2105c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJ_I,
2115c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJ_S,
2125c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJB_V,
2135c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJI_V,
2145c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJJ_V,
2155c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheJS_V,
2165c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJII_Z,
2171c282e2b9a9b432e132b2c332f861cad9feb4a73Vladimir Marko      kProtoCacheObjectJJJ_Z,
2185c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJObjectObject_Z,
2195c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJ_I,
2205c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJI_V,
2215c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJ_J,
2225c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJJ_V,
2235c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJ_Object,
2245c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheObjectJObject_V,
2255c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      kProtoCacheLast
2265c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    };
2275c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
2285c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
2295c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * The maximum number of method parameters we support in the ProtoDef.
2305c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
2315c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static constexpr uint32_t kProtoMaxParams = 6;
2325c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
2335c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
2345c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * The method signature (proto) definition using cached class indexes.
2355c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * The return_type and params are used with the IndexCache to look up
2365c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * appropriate class indexes to be passed to DexFile::FindProtoId().
2375c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
2385c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    struct ProtoDef {
2395c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      ClassCacheIndex return_type;
2405c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      uint8_t param_count;
2415c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      ClassCacheIndex params[kProtoMaxParams];
2425c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    };
2435c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
2445c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
2455c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * The method definition using cached class, name and proto indexes.
2465c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * The class index, method name index and proto index are used with
2475c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * IndexCache to look up appropriate parameters for DexFile::FindMethodId().
2485c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
2495c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    struct MethodDef {
2505c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      ClassCacheIndex declaring_class;
2515c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      NameCacheIndex name;
2525c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      ProtoCacheIndex proto;
2535c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    };
2545c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
2555c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
2565c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * The definition of an intrinsic function binds the method definition
2575c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * to an Intrinsic.
2585c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
2595c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    struct IntrinsicDef {
2605c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      MethodDef method_def;
2615c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      Intrinsic intrinsic;
2625c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    };
2635c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
2645c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /**
2655c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * Cache for class, method name and method signature indexes used during
2665c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * intrinsic function lookup to avoid multiple lookups of the same items.
2675c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     *
2685c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * Many classes have multiple intrinsics and/or they are used in multiple
2695c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * method signatures and we want to avoid repeated lookups since they are
2705c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * not exactly cheap. The method names and method signatures are sometimes
2715c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * reused and therefore cached as well.
2725c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
2735c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    struct IndexCache {
2745c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      IndexCache();
2755c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
2765c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      uint32_t class_indexes[kClassCacheLast - kClassCacheFirst];
2775c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      uint32_t name_indexes[kNameCacheLast - kNameCacheFirst];
2785c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko      uint32_t proto_indexes[kProtoCacheLast - kProtoCacheFirst];
2795c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    };
2805c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
2815c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static const char* kClassCacheNames[];
2825c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static const char* kNameCacheNames[];
2835c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static const ProtoDef kProtoCacheDefs[];
284867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko    static const IntrinsicDef kIntrinsicMethods[];
2855c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
2865c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static const uint32_t kIndexNotFound = static_cast<uint32_t>(-1);
2875c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static const uint32_t kIndexUnresolved = static_cast<uint32_t>(-2);
2885c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
2895c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static uint32_t FindClassIndex(const DexFile* dex_file, IndexCache* cache,
2905c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko                                   ClassCacheIndex index);
2915c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static uint32_t FindNameIndex(const DexFile* dex_file, IndexCache* cache,
2925c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko                                  NameCacheIndex index);
2935c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static uint32_t FindProtoIndex(const DexFile* dex_file, IndexCache* cache,
2945c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko                                   ProtoCacheIndex index);
2955c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    static uint32_t FindMethodIndex(const DexFile* dex_file, IndexCache* cache,
2965c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko                                    const MethodDef& method_def);
2975c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
298867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko    /**
299867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko     * Find all known intrinsic methods in the dex_file and cache their indices.
300867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko     *
301867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko     * Only DexFileToMethodInlinerMap may call this function to initialize the inliner.
302867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko     */
303867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko    void FindIntrinsics(const DexFile* dex_file);
304867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko
305867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko    friend class DexFileToMethodInlinerMap;
3065c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
3075c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    /*
3085c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     * Maps method indexes (for the particular DexFile) to Intrinsic defintions.
3095c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko     */
3105c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    std::map<uint32_t, Intrinsic> intrinsics_;
3115c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko    const DexFile* dex_file_;
312867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko
313867a2b35e67ddcbec089964e8f3cd9a827186e48Vladimir Marko    DISALLOW_COPY_AND_ASSIGN(DexFileMethodInliner);
3145c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko};
3155c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
3165c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko}  // namespace art
3175c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko
3185c96e6b4dc354a7439b211b93462fbe8edea5e57Vladimir Marko#endif  // ART_COMPILER_DEX_QUICK_DEX_FILE_METHOD_INLINER_H_
319