Home | History | Annotate | Download | only in quick
      1 /*
      2  * Copyright (C) 2013 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include "dex_file_method_inliner.h"
     18 
     19 #include <algorithm>
     20 
     21 #include "base/logging.h"
     22 #include "base/macros.h"
     23 #include "base/mutex-inl.h"
     24 #include "driver/compiler_driver.h"
     25 #include "thread-inl.h"
     26 #include "dex_instruction-inl.h"
     27 #include "driver/dex_compilation_unit.h"
     28 #include "verifier/method_verifier-inl.h"
     29 
     30 namespace art {
     31 
     32 namespace {  // anonymous namespace
     33 
     34 static constexpr bool kIntrinsicIsStatic[] = {
     35     true,   // kIntrinsicDoubleCvt
     36     true,   // kIntrinsicFloatCvt
     37     true,   // kIntrinsicFloat2Int
     38     true,   // kIntrinsicDouble2Long
     39     true,   // kIntrinsicFloatIsInfinite
     40     true,   // kIntrinsicDoubleIsInfinite
     41     true,   // kIntrinsicFloatIsNaN
     42     true,   // kIntrinsicDoubleIsNaN
     43     true,   // kIntrinsicReverseBits
     44     true,   // kIntrinsicReverseBytes
     45     true,   // kIntrinsicBitCount
     46     true,   // kIntrinsicCompare,
     47     true,   // kIntrinsicHighestOneBit
     48     true,   // kIntrinsicLowestOneBit
     49     true,   // kIntrinsicNumberOfLeadingZeros
     50     true,   // kIntrinsicNumberOfTrailingZeros
     51     true,   // kIntrinsicRotateRight
     52     true,   // kIntrinsicRotateLeft
     53     true,   // kIntrinsicSignum
     54     true,   // kIntrinsicAbsInt
     55     true,   // kIntrinsicAbsLong
     56     true,   // kIntrinsicAbsFloat
     57     true,   // kIntrinsicAbsDouble
     58     true,   // kIntrinsicMinMaxInt
     59     true,   // kIntrinsicMinMaxLong
     60     true,   // kIntrinsicMinMaxFloat
     61     true,   // kIntrinsicMinMaxDouble
     62     true,   // kIntrinsicCos
     63     true,   // kIntrinsicSin
     64     true,   // kIntrinsicAcos
     65     true,   // kIntrinsicAsin
     66     true,   // kIntrinsicAtan
     67     true,   // kIntrinsicAtan2
     68     true,   // kIntrinsicCbrt
     69     true,   // kIntrinsicCosh
     70     true,   // kIntrinsicExp
     71     true,   // kIntrinsicExpm1
     72     true,   // kIntrinsicHypot
     73     true,   // kIntrinsicLog
     74     true,   // kIntrinsicLog10
     75     true,   // kIntrinsicNextAfter
     76     true,   // kIntrinsicSinh
     77     true,   // kIntrinsicTan
     78     true,   // kIntrinsicTanh
     79     true,   // kIntrinsicSqrt
     80     true,   // kIntrinsicCeil
     81     true,   // kIntrinsicFloor
     82     true,   // kIntrinsicRint
     83     true,   // kIntrinsicRoundFloat
     84     true,   // kIntrinsicRoundDouble
     85     false,  // kIntrinsicReferenceGetReferent
     86     false,  // kIntrinsicCharAt
     87     false,  // kIntrinsicCompareTo
     88     false,  // kIntrinsicEquals
     89     false,  // kIntrinsicGetCharsNoCheck
     90     false,  // kIntrinsicIsEmptyOrLength
     91     false,  // kIntrinsicIndexOf
     92     true,   // kIntrinsicNewStringFromBytes
     93     true,   // kIntrinsicNewStringFromChars
     94     true,   // kIntrinsicNewStringFromString
     95     true,   // kIntrinsicCurrentThread
     96     true,   // kIntrinsicPeek
     97     true,   // kIntrinsicPoke
     98     false,  // kIntrinsicCas
     99     false,  // kIntrinsicUnsafeGet
    100     false,  // kIntrinsicUnsafePut
    101     false,  // kIntrinsicUnsafeGetAndAddInt,
    102     false,  // kIntrinsicUnsafeGetAndAddLong,
    103     false,  // kIntrinsicUnsafeGetAndSetInt,
    104     false,  // kIntrinsicUnsafeGetAndSetLong,
    105     false,  // kIntrinsicUnsafeGetAndSetObject,
    106     false,  // kIntrinsicUnsafeLoadFence,
    107     false,  // kIntrinsicUnsafeStoreFence,
    108     false,  // kIntrinsicUnsafeFullFence,
    109     true,   // kIntrinsicSystemArrayCopyCharArray
    110     true,   // kIntrinsicSystemArrayCopy
    111 };
    112 static_assert(arraysize(kIntrinsicIsStatic) == kInlineOpNop,
    113               "arraysize of kIntrinsicIsStatic unexpected");
    114 static_assert(kIntrinsicIsStatic[kIntrinsicDoubleCvt], "DoubleCvt must be static");
    115 static_assert(kIntrinsicIsStatic[kIntrinsicFloatCvt], "FloatCvt must be static");
    116 static_assert(kIntrinsicIsStatic[kIntrinsicFloat2Int], "Float2Int must be static");
    117 static_assert(kIntrinsicIsStatic[kIntrinsicDouble2Long], "Double2Long must be static");
    118 static_assert(kIntrinsicIsStatic[kIntrinsicFloatIsInfinite], "FloatIsInfinite must be static");
    119 static_assert(kIntrinsicIsStatic[kIntrinsicDoubleIsInfinite], "DoubleIsInfinite must be static");
    120 static_assert(kIntrinsicIsStatic[kIntrinsicFloatIsNaN], "FloatIsNaN must be static");
    121 static_assert(kIntrinsicIsStatic[kIntrinsicDoubleIsNaN], "DoubleIsNaN must be static");
    122 static_assert(kIntrinsicIsStatic[kIntrinsicReverseBits], "ReverseBits must be static");
    123 static_assert(kIntrinsicIsStatic[kIntrinsicReverseBytes], "ReverseBytes must be static");
    124 static_assert(kIntrinsicIsStatic[kIntrinsicBitCount], "BitCount must be static");
    125 static_assert(kIntrinsicIsStatic[kIntrinsicCompare], "Compare must be static");
    126 static_assert(kIntrinsicIsStatic[kIntrinsicHighestOneBit], "HighestOneBit must be static");
    127 static_assert(kIntrinsicIsStatic[kIntrinsicLowestOneBit], "LowestOneBit  must be static");
    128 static_assert(kIntrinsicIsStatic[kIntrinsicNumberOfLeadingZeros],
    129               "NumberOfLeadingZeros must be static");
    130 static_assert(kIntrinsicIsStatic[kIntrinsicNumberOfTrailingZeros],
    131               "NumberOfTrailingZeros must be static");
    132 static_assert(kIntrinsicIsStatic[kIntrinsicRotateRight], "RotateRight must be static");
    133 static_assert(kIntrinsicIsStatic[kIntrinsicRotateLeft], "RotateLeft must be static");
    134 static_assert(kIntrinsicIsStatic[kIntrinsicSignum], "Signum must be static");
    135 static_assert(kIntrinsicIsStatic[kIntrinsicAbsInt], "AbsInt must be static");
    136 static_assert(kIntrinsicIsStatic[kIntrinsicAbsLong], "AbsLong must be static");
    137 static_assert(kIntrinsicIsStatic[kIntrinsicAbsFloat], "AbsFloat must be static");
    138 static_assert(kIntrinsicIsStatic[kIntrinsicAbsDouble], "AbsDouble must be static");
    139 static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxInt], "MinMaxInt must be static");
    140 static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxLong], "MinMaxLong must be static");
    141 static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxFloat], "MinMaxFloat must be static");
    142 static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxDouble], "MinMaxDouble must be static");
    143 static_assert(kIntrinsicIsStatic[kIntrinsicCos], "Cos must be static");
    144 static_assert(kIntrinsicIsStatic[kIntrinsicSin], "Sin must be static");
    145 static_assert(kIntrinsicIsStatic[kIntrinsicAcos], "Acos must be static");
    146 static_assert(kIntrinsicIsStatic[kIntrinsicAsin], "Asin must be static");
    147 static_assert(kIntrinsicIsStatic[kIntrinsicAtan], "Atan must be static");
    148 static_assert(kIntrinsicIsStatic[kIntrinsicAtan2], "Atan2 must be static");
    149 static_assert(kIntrinsicIsStatic[kIntrinsicCbrt], "Cbrt must be static");
    150 static_assert(kIntrinsicIsStatic[kIntrinsicCosh], "Cosh must be static");
    151 static_assert(kIntrinsicIsStatic[kIntrinsicExp], "Exp must be static");
    152 static_assert(kIntrinsicIsStatic[kIntrinsicExpm1], "Expm1 must be static");
    153 static_assert(kIntrinsicIsStatic[kIntrinsicHypot], "Hypot must be static");
    154 static_assert(kIntrinsicIsStatic[kIntrinsicLog], "Log must be static");
    155 static_assert(kIntrinsicIsStatic[kIntrinsicLog10], "Log10 must be static");
    156 static_assert(kIntrinsicIsStatic[kIntrinsicNextAfter], "NextAfter must be static");
    157 static_assert(kIntrinsicIsStatic[kIntrinsicSinh], "Sinh must be static");
    158 static_assert(kIntrinsicIsStatic[kIntrinsicTan], "Tan must be static");
    159 static_assert(kIntrinsicIsStatic[kIntrinsicTanh], "Tanh must be static");
    160 static_assert(kIntrinsicIsStatic[kIntrinsicSqrt], "Sqrt must be static");
    161 static_assert(kIntrinsicIsStatic[kIntrinsicCeil], "Ceil must be static");
    162 static_assert(kIntrinsicIsStatic[kIntrinsicFloor], "Floor must be static");
    163 static_assert(kIntrinsicIsStatic[kIntrinsicRint], "Rint must be static");
    164 static_assert(kIntrinsicIsStatic[kIntrinsicRoundFloat], "RoundFloat must be static");
    165 static_assert(kIntrinsicIsStatic[kIntrinsicRoundDouble], "RoundDouble must be static");
    166 static_assert(!kIntrinsicIsStatic[kIntrinsicReferenceGetReferent], "Get must not be static");
    167 static_assert(!kIntrinsicIsStatic[kIntrinsicCharAt], "CharAt must not be static");
    168 static_assert(!kIntrinsicIsStatic[kIntrinsicCompareTo], "CompareTo must not be static");
    169 static_assert(!kIntrinsicIsStatic[kIntrinsicEquals], "String equals must not be static");
    170 static_assert(!kIntrinsicIsStatic[kIntrinsicGetCharsNoCheck], "GetCharsNoCheck must not be static");
    171 static_assert(!kIntrinsicIsStatic[kIntrinsicIsEmptyOrLength], "IsEmptyOrLength must not be static");
    172 static_assert(!kIntrinsicIsStatic[kIntrinsicIndexOf], "IndexOf must not be static");
    173 static_assert(kIntrinsicIsStatic[kIntrinsicNewStringFromBytes],
    174               "NewStringFromBytes must be static");
    175 static_assert(kIntrinsicIsStatic[kIntrinsicNewStringFromChars],
    176               "NewStringFromChars must be static");
    177 static_assert(kIntrinsicIsStatic[kIntrinsicNewStringFromString],
    178               "NewStringFromString must be static");
    179 static_assert(kIntrinsicIsStatic[kIntrinsicCurrentThread], "CurrentThread must be static");
    180 static_assert(kIntrinsicIsStatic[kIntrinsicPeek], "Peek must be static");
    181 static_assert(kIntrinsicIsStatic[kIntrinsicPoke], "Poke must be static");
    182 static_assert(!kIntrinsicIsStatic[kIntrinsicCas], "Cas must not be static");
    183 static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGet], "UnsafeGet must not be static");
    184 static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafePut], "UnsafePut must not be static");
    185 static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndAddInt], "UnsafeGetAndAddInt must not be static");
    186 static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndAddLong], "UnsafeGetAndAddLong must not be static");
    187 static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetInt], "UnsafeGetAndSetInt must not be static");
    188 static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetLong], "UnsafeGetAndSetLong must not be static");
    189 static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetObject], "UnsafeGetAndSetObject must not be static");
    190 static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeLoadFence], "UnsafeLoadFence must not be static");
    191 static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeStoreFence], "UnsafeStoreFence must not be static");
    192 static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeFullFence], "UnsafeFullFence must not be static");
    193 static_assert(kIntrinsicIsStatic[kIntrinsicSystemArrayCopyCharArray],
    194               "SystemArrayCopyCharArray must be static");
    195 static_assert(kIntrinsicIsStatic[kIntrinsicSystemArrayCopy],
    196               "SystemArrayCopy must be static");
    197 
    198 }  // anonymous namespace
    199 
    200 const uint32_t DexFileMethodInliner::kIndexUnresolved;
    201 const char* const DexFileMethodInliner::kClassCacheNames[] = {
    202     "Z",                       // kClassCacheBoolean
    203     "B",                       // kClassCacheByte
    204     "C",                       // kClassCacheChar
    205     "S",                       // kClassCacheShort
    206     "I",                       // kClassCacheInt
    207     "J",                       // kClassCacheLong
    208     "F",                       // kClassCacheFloat
    209     "D",                       // kClassCacheDouble
    210     "V",                       // kClassCacheVoid
    211     "[B",                      // kClassCacheJavaLangByteArray
    212     "[C",                      // kClassCacheJavaLangCharArray
    213     "[I",                      // kClassCacheJavaLangIntArray
    214     "Ljava/lang/Object;",      // kClassCacheJavaLangObject
    215     "Ljava/lang/ref/Reference;",   // kClassCacheJavaLangRefReference
    216     "Ljava/lang/String;",      // kClassCacheJavaLangString
    217     "Ljava/lang/StringBuffer;",    // kClassCacheJavaLangStringBuffer
    218     "Ljava/lang/StringBuilder;",   // kClassCacheJavaLangStringBuilder
    219     "Ljava/lang/StringFactory;",   // kClassCacheJavaLangStringFactory
    220     "Ljava/lang/Double;",      // kClassCacheJavaLangDouble
    221     "Ljava/lang/Float;",       // kClassCacheJavaLangFloat
    222     "Ljava/lang/Integer;",     // kClassCacheJavaLangInteger
    223     "Ljava/lang/Long;",        // kClassCacheJavaLangLong
    224     "Ljava/lang/Short;",       // kClassCacheJavaLangShort
    225     "Ljava/lang/Math;",        // kClassCacheJavaLangMath
    226     "Ljava/lang/StrictMath;",  // kClassCacheJavaLangStrictMath
    227     "Ljava/lang/Thread;",      // kClassCacheJavaLangThread
    228     "Ljava/nio/charset/Charset;",  // kClassCacheJavaNioCharsetCharset
    229     "Llibcore/io/Memory;",     // kClassCacheLibcoreIoMemory
    230     "Lsun/misc/Unsafe;",       // kClassCacheSunMiscUnsafe
    231     "Ljava/lang/System;",      // kClassCacheJavaLangSystem
    232 };
    233 
    234 const char* const DexFileMethodInliner::kNameCacheNames[] = {
    235     "reverse",               // kNameCacheReverse
    236     "reverseBytes",          // kNameCacheReverseBytes
    237     "doubleToRawLongBits",   // kNameCacheDoubleToRawLongBits
    238     "longBitsToDouble",      // kNameCacheLongBitsToDouble
    239     "floatToRawIntBits",     // kNameCacheFloatToRawIntBits
    240     "intBitsToFloat",        // kNameCacheIntBitsToFloat
    241     "abs",                   // kNameCacheAbs
    242     "max",                   // kNameCacheMax
    243     "min",                   // kNameCacheMin
    244     "cos",                   // kNameCacheCos
    245     "sin",                   // kNameCacheSin
    246     "acos",                  // kNameCacheAcos
    247     "asin",                  // kNameCacheAsin
    248     "atan",                  // kNameCacheAtan
    249     "atan2",                 // kNameCacheAtan2
    250     "cbrt",                  // kNameCacheCbrt
    251     "cosh",                  // kNameCacheCosh
    252     "exp",                   // kNameCacheExp
    253     "expm1",                 // kNameCacheExpm1
    254     "hypot",                 // kNameCacheHypot
    255     "log",                   // kNameCacheLog
    256     "log10",                 // kNameCacheLog10
    257     "nextAfter",             // kNameCacheNextAfter
    258     "sinh",                  // kNameCacheSinh
    259     "tan",                   // kNameCacheTan
    260     "tanh",                  // kNameCacheTanh
    261     "sqrt",                  // kNameCacheSqrt
    262     "ceil",                  // kNameCacheCeil
    263     "floor",                 // kNameCacheFloor
    264     "rint",                  // kNameCacheRint
    265     "round",                 // kNameCacheRound
    266     "getReferent",           // kNameCacheReferenceGet
    267     "charAt",                // kNameCacheCharAt
    268     "compareTo",             // kNameCacheCompareTo
    269     "equals",                // kNameCacheEquals
    270     "getCharsNoCheck",       // kNameCacheGetCharsNoCheck
    271     "isEmpty",               // kNameCacheIsEmpty
    272     "floatToIntBits",        // kNameCacheFloatToIntBits
    273     "doubleToLongBits",      // kNameCacheDoubleToLongBits
    274     "isInfinite",            // kNameCacheIsInfinite
    275     "isNaN",                 // kNameCacheIsNaN
    276     "indexOf",               // kNameCacheIndexOf
    277     "length",                // kNameCacheLength
    278     "<init>",                // kNameCacheInit
    279     "newStringFromBytes",    // kNameCacheNewStringFromBytes
    280     "newStringFromChars",    // kNameCacheNewStringFromChars
    281     "newStringFromString",   // kNameCacheNewStringFromString
    282     "currentThread",         // kNameCacheCurrentThread
    283     "peekByte",              // kNameCachePeekByte
    284     "peekIntNative",         // kNameCachePeekIntNative
    285     "peekLongNative",        // kNameCachePeekLongNative
    286     "peekShortNative",       // kNameCachePeekShortNative
    287     "pokeByte",              // kNameCachePokeByte
    288     "pokeIntNative",         // kNameCachePokeIntNative
    289     "pokeLongNative",        // kNameCachePokeLongNative
    290     "pokeShortNative",       // kNameCachePokeShortNative
    291     "compareAndSwapInt",     // kNameCacheCompareAndSwapInt
    292     "compareAndSwapLong",    // kNameCacheCompareAndSwapLong
    293     "compareAndSwapObject",  // kNameCacheCompareAndSwapObject
    294     "getInt",                // kNameCacheGetInt
    295     "getIntVolatile",        // kNameCacheGetIntVolatile
    296     "putInt",                // kNameCachePutInt
    297     "putIntVolatile",        // kNameCachePutIntVolatile
    298     "putOrderedInt",         // kNameCachePutOrderedInt
    299     "getLong",               // kNameCacheGetLong
    300     "getLongVolatile",       // kNameCacheGetLongVolatile
    301     "putLong",               // kNameCachePutLong
    302     "putLongVolatile",       // kNameCachePutLongVolatile
    303     "putOrderedLong",        // kNameCachePutOrderedLong
    304     "getObject",             // kNameCacheGetObject
    305     "getObjectVolatile",     // kNameCacheGetObjectVolatile
    306     "putObject",             // kNameCachePutObject
    307     "putObjectVolatile",     // kNameCachePutObjectVolatile
    308     "putOrderedObject",      // kNameCachePutOrderedObject
    309     "getAndAddInt",          // kNameCacheGetAndAddInt,
    310     "getAndAddLong",         // kNameCacheGetAndAddLong,
    311     "getAndSetInt",          // kNameCacheGetAndSetInt,
    312     "getAndSetLong",         // kNameCacheGetAndSetLong,
    313     "getAndSetObject",       // kNameCacheGetAndSetObject,
    314     "loadFence",             // kNameCacheLoadFence,
    315     "storeFence",            // kNameCacheStoreFence,
    316     "fullFence",             // kNameCacheFullFence,
    317     "arraycopy",             // kNameCacheArrayCopy
    318     "bitCount",              // kNameCacheBitCount
    319     "compare",               // kNameCacheCompare
    320     "highestOneBit",         // kNameCacheHighestOneBit
    321     "lowestOneBit",          // kNameCacheLowestOneBit
    322     "numberOfLeadingZeros",  // kNameCacheNumberOfLeadingZeros
    323     "numberOfTrailingZeros",  // kNameCacheNumberOfTrailingZeros
    324     "rotateRight",           // kNameCacheRotateRight
    325     "rotateLeft",            // kNameCacheRotateLeft
    326     "signum",                // kNameCacheSignum
    327 };
    328 
    329 const DexFileMethodInliner::ProtoDef DexFileMethodInliner::kProtoCacheDefs[] = {
    330     // kProtoCacheI_I
    331     { kClassCacheInt, 1, { kClassCacheInt } },
    332     // kProtoCacheJ_J
    333     { kClassCacheLong, 1, { kClassCacheLong } },
    334     // kProtoCacheS_S
    335     { kClassCacheShort, 1, { kClassCacheShort } },
    336     // kProtoCacheD_D
    337     { kClassCacheDouble, 1, { kClassCacheDouble } },
    338     // kProtoCacheDD_D
    339     { kClassCacheDouble, 2, { kClassCacheDouble, kClassCacheDouble } },
    340     // kProtoCacheF_F
    341     { kClassCacheFloat, 1, { kClassCacheFloat } },
    342     // kProtoCacheFF_F
    343     { kClassCacheFloat, 2, { kClassCacheFloat, kClassCacheFloat } },
    344     // kProtoCacheD_J
    345     { kClassCacheLong, 1, { kClassCacheDouble } },
    346     // kProtoCacheD_Z
    347     { kClassCacheBoolean, 1, { kClassCacheDouble } },
    348     // kProtoCacheJ_D
    349     { kClassCacheDouble, 1, { kClassCacheLong } },
    350     // kProtoCacheF_I
    351     { kClassCacheInt, 1, { kClassCacheFloat } },
    352     // kProtoCacheF_Z
    353     { kClassCacheBoolean, 1, { kClassCacheFloat } },
    354     // kProtoCacheI_F
    355     { kClassCacheFloat, 1, { kClassCacheInt } },
    356     // kProtoCacheII_I
    357     { kClassCacheInt, 2, { kClassCacheInt, kClassCacheInt } },
    358     // kProtoCacheI_C
    359     { kClassCacheChar, 1, { kClassCacheInt } },
    360     // kProtoCacheString_I
    361     { kClassCacheInt, 1, { kClassCacheJavaLangString } },
    362     // kProtoCache_Z
    363     { kClassCacheBoolean, 0, { } },
    364     // kProtoCache_I
    365     { kClassCacheInt, 0, { } },
    366     // kProtoCache_Object
    367     { kClassCacheJavaLangObject, 0, { } },
    368     // kProtoCache_Thread
    369     { kClassCacheJavaLangThread, 0, { } },
    370     // kProtoCacheJ_B
    371     { kClassCacheByte, 1, { kClassCacheLong } },
    372     // kProtoCacheJ_I
    373     { kClassCacheInt, 1, { kClassCacheLong } },
    374     // kProtoCacheJ_S
    375     { kClassCacheShort, 1, { kClassCacheLong } },
    376     // kProtoCacheJB_V
    377     { kClassCacheVoid, 2, { kClassCacheLong, kClassCacheByte } },
    378     // kProtoCacheJI_V
    379     { kClassCacheVoid, 2, { kClassCacheLong, kClassCacheInt } },
    380     // kProtoCacheJJ_J
    381     { kClassCacheLong, 2, { kClassCacheLong, kClassCacheLong } },
    382     // kProtoCacheJJ_I
    383     { kClassCacheInt, 2, { kClassCacheLong, kClassCacheLong } },
    384     // kProtoCacheJJ_V
    385     { kClassCacheVoid, 2, { kClassCacheLong, kClassCacheLong } },
    386     // kProtoCacheJS_V
    387     { kClassCacheVoid, 2, { kClassCacheLong, kClassCacheShort } },
    388     // kProtoCacheObject_Z
    389     { kClassCacheBoolean, 1, { kClassCacheJavaLangObject } },
    390     // kProtoCacheJI_J
    391     { kClassCacheLong, 2, { kClassCacheLong, kClassCacheInt } },
    392     // kProtoCacheObjectJII_Z
    393     { kClassCacheBoolean, 4, { kClassCacheJavaLangObject, kClassCacheLong,
    394         kClassCacheInt, kClassCacheInt } },
    395     // kProtoCacheObjectJJJ_Z
    396     { kClassCacheBoolean, 4, { kClassCacheJavaLangObject, kClassCacheLong,
    397         kClassCacheLong, kClassCacheLong } },
    398     // kProtoCacheObjectJObjectObject_Z
    399     { kClassCacheBoolean, 4, { kClassCacheJavaLangObject, kClassCacheLong,
    400         kClassCacheJavaLangObject, kClassCacheJavaLangObject } },
    401     // kProtoCacheObjectJ_I
    402     { kClassCacheInt, 2, { kClassCacheJavaLangObject, kClassCacheLong } },
    403     // kProtoCacheObjectJI_I
    404     { kClassCacheInt, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheInt } },
    405     // kProtoCacheObjectJI_V
    406     { kClassCacheVoid, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheInt } },
    407     // kProtoCacheObjectJ_J
    408     { kClassCacheLong, 2, { kClassCacheJavaLangObject, kClassCacheLong } },
    409     // kProtoCacheObjectJJ_J
    410     { kClassCacheLong, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheLong } },
    411     // kProtoCacheObjectJJ_V
    412     { kClassCacheVoid, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheLong } },
    413     // kProtoCacheObjectJ_Object
    414     { kClassCacheJavaLangObject, 2, { kClassCacheJavaLangObject, kClassCacheLong } },
    415     // kProtoCacheObjectJObject_V
    416     { kClassCacheVoid, 3, { kClassCacheJavaLangObject, kClassCacheLong,
    417         kClassCacheJavaLangObject } },
    418     // kProtoCacheObjectJObject_Object
    419     { kClassCacheJavaLangObject, 3, { kClassCacheJavaLangObject, kClassCacheLong,
    420         kClassCacheJavaLangObject } },
    421     // kProtoCacheCharArrayICharArrayII_V
    422     { kClassCacheVoid, 5, {kClassCacheJavaLangCharArray, kClassCacheInt,
    423         kClassCacheJavaLangCharArray, kClassCacheInt, kClassCacheInt} },
    424     // kProtoCacheObjectIObjectII_V
    425     { kClassCacheVoid, 5, {kClassCacheJavaLangObject, kClassCacheInt,
    426         kClassCacheJavaLangObject, kClassCacheInt, kClassCacheInt} },
    427     // kProtoCacheIICharArrayI_V
    428     { kClassCacheVoid, 4, { kClassCacheInt, kClassCacheInt, kClassCacheJavaLangCharArray,
    429         kClassCacheInt } },
    430     // kProtoCacheByteArrayIII_String
    431     { kClassCacheJavaLangString, 4, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt,
    432         kClassCacheInt } },
    433     // kProtoCacheIICharArray_String
    434     { kClassCacheJavaLangString, 3, { kClassCacheInt, kClassCacheInt,
    435         kClassCacheJavaLangCharArray } },
    436     // kProtoCacheString_String
    437     { kClassCacheJavaLangString, 1, { kClassCacheJavaLangString } },
    438     // kProtoCache_V
    439     { kClassCacheVoid, 0, { } },
    440     // kProtoCacheByteArray_V
    441     { kClassCacheVoid, 1, { kClassCacheJavaLangByteArray } },
    442     // kProtoCacheByteArrayI_V
    443     { kClassCacheVoid, 2, { kClassCacheJavaLangByteArray, kClassCacheInt } },
    444     // kProtoCacheByteArrayII_V
    445     { kClassCacheVoid, 3, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt } },
    446     // kProtoCacheByteArrayIII_V
    447     { kClassCacheVoid, 4, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt,
    448         kClassCacheInt } },
    449     // kProtoCacheByteArrayIIString_V
    450     { kClassCacheVoid, 4, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt,
    451         kClassCacheJavaLangString } },
    452     // kProtoCacheByteArrayString_V
    453     { kClassCacheVoid, 2, { kClassCacheJavaLangByteArray, kClassCacheJavaLangString } },
    454     // kProtoCacheByteArrayIICharset_V
    455     { kClassCacheVoid, 4, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt,
    456         kClassCacheJavaNioCharsetCharset } },
    457     // kProtoCacheByteArrayCharset_V
    458     { kClassCacheVoid, 2, { kClassCacheJavaLangByteArray, kClassCacheJavaNioCharsetCharset } },
    459     // kProtoCacheCharArray_V
    460     { kClassCacheVoid, 1, { kClassCacheJavaLangCharArray } },
    461     // kProtoCacheCharArrayII_V
    462     { kClassCacheVoid, 3, { kClassCacheJavaLangCharArray, kClassCacheInt, kClassCacheInt } },
    463     // kProtoCacheIICharArray_V
    464     { kClassCacheVoid, 3, { kClassCacheInt, kClassCacheInt, kClassCacheJavaLangCharArray } },
    465     // kProtoCacheIntArrayII_V
    466     { kClassCacheVoid, 3, { kClassCacheJavaLangIntArray, kClassCacheInt, kClassCacheInt } },
    467     // kProtoCacheString_V
    468     { kClassCacheVoid, 1, { kClassCacheJavaLangString } },
    469     // kProtoCacheStringBuffer_V
    470     { kClassCacheVoid, 1, { kClassCacheJavaLangStringBuffer } },
    471     // kProtoCacheStringBuilder_V
    472     { kClassCacheVoid, 1, { kClassCacheJavaLangStringBuilder } },
    473 };
    474 
    475 const DexFileMethodInliner::IntrinsicDef DexFileMethodInliner::kIntrinsicMethods[] = {
    476 #define INTRINSIC(c, n, p, o, d) \
    477     { { kClassCache ## c, kNameCache ## n, kProtoCache ## p }, { o, kInlineIntrinsic, { d } } }
    478 
    479     INTRINSIC(JavaLangDouble, DoubleToRawLongBits, D_J, kIntrinsicDoubleCvt, 0),
    480     INTRINSIC(JavaLangDouble, LongBitsToDouble, J_D, kIntrinsicDoubleCvt, kIntrinsicFlagToFloatingPoint),
    481     INTRINSIC(JavaLangFloat, FloatToRawIntBits, F_I, kIntrinsicFloatCvt, 0),
    482     INTRINSIC(JavaLangFloat, IntBitsToFloat, I_F, kIntrinsicFloatCvt, kIntrinsicFlagToFloatingPoint),
    483 
    484     INTRINSIC(JavaLangFloat, FloatToIntBits, F_I, kIntrinsicFloat2Int, 0),
    485     INTRINSIC(JavaLangDouble, DoubleToLongBits, D_J, kIntrinsicDouble2Long, 0),
    486 
    487     INTRINSIC(JavaLangFloat, IsInfinite, F_Z, kIntrinsicFloatIsInfinite, 0),
    488     INTRINSIC(JavaLangDouble, IsInfinite, D_Z, kIntrinsicDoubleIsInfinite, 0),
    489     INTRINSIC(JavaLangFloat, IsNaN, F_Z, kIntrinsicFloatIsNaN, 0),
    490     INTRINSIC(JavaLangDouble, IsNaN, D_Z, kIntrinsicDoubleIsNaN, 0),
    491 
    492     INTRINSIC(JavaLangInteger, ReverseBytes, I_I, kIntrinsicReverseBytes, k32),
    493     INTRINSIC(JavaLangLong, ReverseBytes, J_J, kIntrinsicReverseBytes, k64),
    494     INTRINSIC(JavaLangShort, ReverseBytes, S_S, kIntrinsicReverseBytes, kSignedHalf),
    495     INTRINSIC(JavaLangInteger, Reverse, I_I, kIntrinsicReverseBits, k32),
    496     INTRINSIC(JavaLangLong, Reverse, J_J, kIntrinsicReverseBits, k64),
    497 
    498     INTRINSIC(JavaLangInteger, BitCount, I_I, kIntrinsicBitCount, k32),
    499     INTRINSIC(JavaLangLong, BitCount, J_I, kIntrinsicBitCount, k64),
    500     INTRINSIC(JavaLangInteger, Compare, II_I, kIntrinsicCompare, k32),
    501     INTRINSIC(JavaLangLong, Compare, JJ_I, kIntrinsicCompare, k64),
    502     INTRINSIC(JavaLangInteger, HighestOneBit, I_I, kIntrinsicHighestOneBit, k32),
    503     INTRINSIC(JavaLangLong, HighestOneBit, J_J, kIntrinsicHighestOneBit, k64),
    504     INTRINSIC(JavaLangInteger, LowestOneBit, I_I, kIntrinsicLowestOneBit, k32),
    505     INTRINSIC(JavaLangLong, LowestOneBit, J_J, kIntrinsicLowestOneBit, k64),
    506     INTRINSIC(JavaLangInteger, NumberOfLeadingZeros, I_I, kIntrinsicNumberOfLeadingZeros, k32),
    507     INTRINSIC(JavaLangLong, NumberOfLeadingZeros, J_I, kIntrinsicNumberOfLeadingZeros, k64),
    508     INTRINSIC(JavaLangInteger, NumberOfTrailingZeros, I_I, kIntrinsicNumberOfTrailingZeros, k32),
    509     INTRINSIC(JavaLangLong, NumberOfTrailingZeros, J_I, kIntrinsicNumberOfTrailingZeros, k64),
    510     INTRINSIC(JavaLangInteger, Signum, I_I, kIntrinsicSignum, k32),
    511     INTRINSIC(JavaLangLong, Signum, J_I, kIntrinsicSignum, k64),
    512 
    513     INTRINSIC(JavaLangMath,       Abs, I_I, kIntrinsicAbsInt, 0),
    514     INTRINSIC(JavaLangStrictMath, Abs, I_I, kIntrinsicAbsInt, 0),
    515     INTRINSIC(JavaLangMath,       Abs, J_J, kIntrinsicAbsLong, 0),
    516     INTRINSIC(JavaLangStrictMath, Abs, J_J, kIntrinsicAbsLong, 0),
    517     INTRINSIC(JavaLangMath,       Abs, F_F, kIntrinsicAbsFloat, 0),
    518     INTRINSIC(JavaLangStrictMath, Abs, F_F, kIntrinsicAbsFloat, 0),
    519     INTRINSIC(JavaLangMath,       Abs, D_D, kIntrinsicAbsDouble, 0),
    520     INTRINSIC(JavaLangStrictMath, Abs, D_D, kIntrinsicAbsDouble, 0),
    521     INTRINSIC(JavaLangMath,       Min, II_I, kIntrinsicMinMaxInt, kIntrinsicFlagMin),
    522     INTRINSIC(JavaLangStrictMath, Min, II_I, kIntrinsicMinMaxInt, kIntrinsicFlagMin),
    523     INTRINSIC(JavaLangMath,       Max, II_I, kIntrinsicMinMaxInt, kIntrinsicFlagMax),
    524     INTRINSIC(JavaLangStrictMath, Max, II_I, kIntrinsicMinMaxInt, kIntrinsicFlagMax),
    525     INTRINSIC(JavaLangMath,       Min, JJ_J, kIntrinsicMinMaxLong, kIntrinsicFlagMin),
    526     INTRINSIC(JavaLangStrictMath, Min, JJ_J, kIntrinsicMinMaxLong, kIntrinsicFlagMin),
    527     INTRINSIC(JavaLangMath,       Max, JJ_J, kIntrinsicMinMaxLong, kIntrinsicFlagMax),
    528     INTRINSIC(JavaLangStrictMath, Max, JJ_J, kIntrinsicMinMaxLong, kIntrinsicFlagMax),
    529     INTRINSIC(JavaLangMath,       Min, FF_F, kIntrinsicMinMaxFloat, kIntrinsicFlagMin),
    530     INTRINSIC(JavaLangStrictMath, Min, FF_F, kIntrinsicMinMaxFloat, kIntrinsicFlagMin),
    531     INTRINSIC(JavaLangMath,       Max, FF_F, kIntrinsicMinMaxFloat, kIntrinsicFlagMax),
    532     INTRINSIC(JavaLangStrictMath, Max, FF_F, kIntrinsicMinMaxFloat, kIntrinsicFlagMax),
    533     INTRINSIC(JavaLangMath,       Min, DD_D, kIntrinsicMinMaxDouble, kIntrinsicFlagMin),
    534     INTRINSIC(JavaLangStrictMath, Min, DD_D, kIntrinsicMinMaxDouble, kIntrinsicFlagMin),
    535     INTRINSIC(JavaLangMath,       Max, DD_D, kIntrinsicMinMaxDouble, kIntrinsicFlagMax),
    536     INTRINSIC(JavaLangStrictMath, Max, DD_D, kIntrinsicMinMaxDouble, kIntrinsicFlagMax),
    537 
    538     INTRINSIC(JavaLangMath,       Cos, D_D, kIntrinsicCos, 0),
    539     INTRINSIC(JavaLangMath,       Sin, D_D, kIntrinsicSin, 0),
    540     INTRINSIC(JavaLangMath,       Acos, D_D, kIntrinsicAcos, 0),
    541     INTRINSIC(JavaLangMath,       Asin, D_D, kIntrinsicAsin, 0),
    542     INTRINSIC(JavaLangMath,       Atan, D_D, kIntrinsicAtan, 0),
    543     INTRINSIC(JavaLangMath,       Atan2, DD_D, kIntrinsicAtan2, 0),
    544     INTRINSIC(JavaLangMath,       Cbrt, D_D, kIntrinsicCbrt, 0),
    545     INTRINSIC(JavaLangMath,       Cosh, D_D, kIntrinsicCosh, 0),
    546     INTRINSIC(JavaLangMath,       Exp, D_D, kIntrinsicExp, 0),
    547     INTRINSIC(JavaLangMath,       Expm1, D_D, kIntrinsicExpm1, 0),
    548     INTRINSIC(JavaLangMath,       Hypot, DD_D, kIntrinsicHypot, 0),
    549     INTRINSIC(JavaLangMath,       Log, D_D, kIntrinsicLog, 0),
    550     INTRINSIC(JavaLangMath,       Log10, D_D, kIntrinsicLog10, 0),
    551     INTRINSIC(JavaLangMath,       NextAfter, DD_D, kIntrinsicNextAfter, 0),
    552     INTRINSIC(JavaLangMath,       Sinh, D_D, kIntrinsicSinh, 0),
    553     INTRINSIC(JavaLangMath,       Tan, D_D, kIntrinsicTan, 0),
    554     INTRINSIC(JavaLangMath,       Tanh, D_D, kIntrinsicTanh, 0),
    555     INTRINSIC(JavaLangMath,       Sqrt, D_D, kIntrinsicSqrt, 0),
    556     INTRINSIC(JavaLangStrictMath, Sqrt, D_D, kIntrinsicSqrt, 0),
    557 
    558     INTRINSIC(JavaLangMath,       Ceil, D_D, kIntrinsicCeil, 0),
    559     INTRINSIC(JavaLangStrictMath, Ceil, D_D, kIntrinsicCeil, 0),
    560     INTRINSIC(JavaLangMath,       Floor, D_D, kIntrinsicFloor, 0),
    561     INTRINSIC(JavaLangStrictMath, Floor, D_D, kIntrinsicFloor, 0),
    562     INTRINSIC(JavaLangMath,       Rint, D_D, kIntrinsicRint, 0),
    563     INTRINSIC(JavaLangStrictMath, Rint, D_D, kIntrinsicRint, 0),
    564     INTRINSIC(JavaLangMath,       Round, F_I, kIntrinsicRoundFloat, 0),
    565     INTRINSIC(JavaLangStrictMath, Round, F_I, kIntrinsicRoundFloat, 0),
    566     INTRINSIC(JavaLangMath,       Round, D_J, kIntrinsicRoundDouble, 0),
    567     INTRINSIC(JavaLangStrictMath, Round, D_J, kIntrinsicRoundDouble, 0),
    568 
    569     INTRINSIC(JavaLangRefReference, ReferenceGetReferent, _Object, kIntrinsicReferenceGetReferent, 0),
    570 
    571     INTRINSIC(JavaLangString, CharAt, I_C, kIntrinsicCharAt, 0),
    572     INTRINSIC(JavaLangString, CompareTo, String_I, kIntrinsicCompareTo, 0),
    573     INTRINSIC(JavaLangString, Equals, Object_Z, kIntrinsicEquals, 0),
    574     INTRINSIC(JavaLangString, GetCharsNoCheck, IICharArrayI_V, kIntrinsicGetCharsNoCheck, 0),
    575     INTRINSIC(JavaLangString, IsEmpty, _Z, kIntrinsicIsEmptyOrLength, kIntrinsicFlagIsEmpty),
    576     INTRINSIC(JavaLangString, IndexOf, II_I, kIntrinsicIndexOf, kIntrinsicFlagNone),
    577     INTRINSIC(JavaLangString, IndexOf, I_I, kIntrinsicIndexOf, kIntrinsicFlagBase0),
    578     INTRINSIC(JavaLangString, Length, _I, kIntrinsicIsEmptyOrLength, kIntrinsicFlagLength),
    579 
    580     INTRINSIC(JavaLangStringFactory, NewStringFromBytes, ByteArrayIII_String,
    581               kIntrinsicNewStringFromBytes, kIntrinsicFlagNone),
    582     INTRINSIC(JavaLangStringFactory, NewStringFromChars, IICharArray_String,
    583               kIntrinsicNewStringFromChars, kIntrinsicFlagNone),
    584     INTRINSIC(JavaLangStringFactory, NewStringFromString, String_String,
    585               kIntrinsicNewStringFromString, kIntrinsicFlagNone),
    586 
    587     INTRINSIC(JavaLangThread, CurrentThread, _Thread, kIntrinsicCurrentThread, 0),
    588 
    589     INTRINSIC(LibcoreIoMemory, PeekByte, J_B, kIntrinsicPeek, kSignedByte),
    590     INTRINSIC(LibcoreIoMemory, PeekIntNative, J_I, kIntrinsicPeek, k32),
    591     INTRINSIC(LibcoreIoMemory, PeekLongNative, J_J, kIntrinsicPeek, k64),
    592     INTRINSIC(LibcoreIoMemory, PeekShortNative, J_S, kIntrinsicPeek, kSignedHalf),
    593     INTRINSIC(LibcoreIoMemory, PokeByte, JB_V, kIntrinsicPoke, kSignedByte),
    594     INTRINSIC(LibcoreIoMemory, PokeIntNative, JI_V, kIntrinsicPoke, k32),
    595     INTRINSIC(LibcoreIoMemory, PokeLongNative, JJ_V, kIntrinsicPoke, k64),
    596     INTRINSIC(LibcoreIoMemory, PokeShortNative, JS_V, kIntrinsicPoke, kSignedHalf),
    597 
    598     INTRINSIC(SunMiscUnsafe, CompareAndSwapInt, ObjectJII_Z, kIntrinsicCas,
    599               kIntrinsicFlagNone),
    600     INTRINSIC(SunMiscUnsafe, CompareAndSwapLong, ObjectJJJ_Z, kIntrinsicCas,
    601               kIntrinsicFlagIsLong),
    602     INTRINSIC(SunMiscUnsafe, CompareAndSwapObject, ObjectJObjectObject_Z, kIntrinsicCas,
    603               kIntrinsicFlagIsObject),
    604 
    605 #define UNSAFE_GET_PUT(type, code, type_flags) \
    606     INTRINSIC(SunMiscUnsafe, Get ## type, ObjectJ_ ## code, kIntrinsicUnsafeGet, \
    607               type_flags), \
    608     INTRINSIC(SunMiscUnsafe, Get ## type ## Volatile, ObjectJ_ ## code, kIntrinsicUnsafeGet, \
    609               type_flags | kIntrinsicFlagIsVolatile), \
    610     INTRINSIC(SunMiscUnsafe, Put ## type, ObjectJ ## code ## _V, kIntrinsicUnsafePut, \
    611               type_flags), \
    612     INTRINSIC(SunMiscUnsafe, Put ## type ## Volatile, ObjectJ ## code ## _V, kIntrinsicUnsafePut, \
    613               type_flags | kIntrinsicFlagIsVolatile), \
    614     INTRINSIC(SunMiscUnsafe, PutOrdered ## type, ObjectJ ## code ## _V, kIntrinsicUnsafePut, \
    615               type_flags | kIntrinsicFlagIsOrdered)
    616 
    617     UNSAFE_GET_PUT(Int, I, kIntrinsicFlagNone),
    618     UNSAFE_GET_PUT(Long, J, kIntrinsicFlagIsLong),
    619     UNSAFE_GET_PUT(Object, Object, kIntrinsicFlagIsObject),
    620 #undef UNSAFE_GET_PUT
    621 
    622     // 1.8
    623     INTRINSIC(SunMiscUnsafe, GetAndAddInt, ObjectJI_I, kIntrinsicUnsafeGetAndAddInt, 0),
    624     INTRINSIC(SunMiscUnsafe, GetAndAddLong, ObjectJJ_J, kIntrinsicUnsafeGetAndAddLong, 0),
    625     INTRINSIC(SunMiscUnsafe, GetAndSetInt, ObjectJI_I, kIntrinsicUnsafeGetAndSetInt, 0),
    626     INTRINSIC(SunMiscUnsafe, GetAndSetLong, ObjectJJ_J, kIntrinsicUnsafeGetAndSetLong, 0),
    627     INTRINSIC(SunMiscUnsafe, GetAndSetObject, ObjectJObject_Object, kIntrinsicUnsafeGetAndSetObject, 0),
    628     INTRINSIC(SunMiscUnsafe, LoadFence, _V, kIntrinsicUnsafeLoadFence, 0),
    629     INTRINSIC(SunMiscUnsafe, StoreFence, _V, kIntrinsicUnsafeStoreFence, 0),
    630     INTRINSIC(SunMiscUnsafe, FullFence, _V, kIntrinsicUnsafeFullFence, 0),
    631 
    632     INTRINSIC(JavaLangSystem, ArrayCopy, CharArrayICharArrayII_V , kIntrinsicSystemArrayCopyCharArray,
    633               0),
    634     INTRINSIC(JavaLangSystem, ArrayCopy, ObjectIObjectII_V , kIntrinsicSystemArrayCopy,
    635               0),
    636 
    637     INTRINSIC(JavaLangInteger, RotateRight, II_I, kIntrinsicRotateRight, k32),
    638     INTRINSIC(JavaLangLong, RotateRight, JI_J, kIntrinsicRotateRight, k64),
    639     INTRINSIC(JavaLangInteger, RotateLeft, II_I, kIntrinsicRotateLeft, k32),
    640     INTRINSIC(JavaLangLong, RotateLeft, JI_J, kIntrinsicRotateLeft, k64),
    641 
    642 #undef INTRINSIC
    643 
    644 #define SPECIAL(c, n, p, o, d) \
    645     { { kClassCache ## c, kNameCache ## n, kProtoCache ## p }, { o, kInlineSpecial, { d } } }
    646 
    647     SPECIAL(JavaLangString, Init, _V, kInlineStringInit, 0),
    648     SPECIAL(JavaLangString, Init, ByteArray_V, kInlineStringInit, 1),
    649     SPECIAL(JavaLangString, Init, ByteArrayI_V, kInlineStringInit, 2),
    650     SPECIAL(JavaLangString, Init, ByteArrayII_V, kInlineStringInit, 3),
    651     SPECIAL(JavaLangString, Init, ByteArrayIII_V, kInlineStringInit, 4),
    652     SPECIAL(JavaLangString, Init, ByteArrayIIString_V, kInlineStringInit, 5),
    653     SPECIAL(JavaLangString, Init, ByteArrayString_V, kInlineStringInit, 6),
    654     SPECIAL(JavaLangString, Init, ByteArrayIICharset_V, kInlineStringInit, 7),
    655     SPECIAL(JavaLangString, Init, ByteArrayCharset_V, kInlineStringInit, 8),
    656     SPECIAL(JavaLangString, Init, CharArray_V, kInlineStringInit, 9),
    657     SPECIAL(JavaLangString, Init, CharArrayII_V, kInlineStringInit, 10),
    658     SPECIAL(JavaLangString, Init, IICharArray_V, kInlineStringInit, 11),
    659     SPECIAL(JavaLangString, Init, IntArrayII_V, kInlineStringInit, 12),
    660     SPECIAL(JavaLangString, Init, String_V, kInlineStringInit, 13),
    661     SPECIAL(JavaLangString, Init, StringBuffer_V, kInlineStringInit, 14),
    662     SPECIAL(JavaLangString, Init, StringBuilder_V, kInlineStringInit, 15),
    663 
    664 #undef SPECIAL
    665 };
    666 
    667 DexFileMethodInliner::DexFileMethodInliner()
    668     : lock_("DexFileMethodInliner lock", kDexFileMethodInlinerLock),
    669       dex_file_(nullptr) {
    670   static_assert(kClassCacheFirst == 0, "kClassCacheFirst not 0");
    671   static_assert(arraysize(kClassCacheNames) == kClassCacheLast,
    672                 "bad arraysize for kClassCacheNames");
    673   static_assert(kNameCacheFirst == 0, "kNameCacheFirst not 0");
    674   static_assert(arraysize(kNameCacheNames) == kNameCacheLast,
    675                 "bad arraysize for kNameCacheNames");
    676   static_assert(kProtoCacheFirst == 0, "kProtoCacheFirst not 0");
    677   static_assert(arraysize(kProtoCacheDefs) == kProtoCacheLast,
    678                 "bad arraysize kProtoCacheNames");
    679 }
    680 
    681 DexFileMethodInliner::~DexFileMethodInliner() {
    682 }
    683 
    684 bool DexFileMethodInliner::AnalyseMethodCode(verifier::MethodVerifier* verifier) {
    685   InlineMethod method;
    686   bool success = InlineMethodAnalyser::AnalyseMethodCode(verifier, &method);
    687   return success && AddInlineMethod(verifier->GetMethodReference().dex_method_index, method);
    688 }
    689 
    690 InlineMethodFlags DexFileMethodInliner::IsIntrinsicOrSpecial(uint32_t method_index) {
    691   ReaderMutexLock mu(Thread::Current(), lock_);
    692   auto it = inline_methods_.find(method_index);
    693   if (it != inline_methods_.end()) {
    694     DCHECK_NE(it->second.flags & (kInlineIntrinsic | kInlineSpecial), 0);
    695     return it->second.flags;
    696   } else {
    697     return kNoInlineMethodFlags;
    698   }
    699 }
    700 
    701 bool DexFileMethodInliner::IsIntrinsic(uint32_t method_index, InlineMethod* intrinsic) {
    702   ReaderMutexLock mu(Thread::Current(), lock_);
    703   auto it = inline_methods_.find(method_index);
    704   bool res = (it != inline_methods_.end() && (it->second.flags & kInlineIntrinsic) != 0);
    705   if (res && intrinsic != nullptr) {
    706     *intrinsic = it->second;
    707   }
    708   return res;
    709 }
    710 
    711 bool DexFileMethodInliner::IsSpecial(uint32_t method_index) {
    712   ReaderMutexLock mu(Thread::Current(), lock_);
    713   auto it = inline_methods_.find(method_index);
    714   return it != inline_methods_.end() && (it->second.flags & kInlineSpecial) != 0;
    715 }
    716 
    717 uint32_t DexFileMethodInliner::FindClassIndex(const DexFile* dex_file, IndexCache* cache,
    718                                               ClassCacheIndex index) {
    719   uint32_t* class_index = &cache->class_indexes[index];
    720   if (*class_index != kIndexUnresolved) {
    721     return *class_index;
    722   }
    723 
    724   const DexFile::TypeId* type_id = dex_file->FindTypeId(kClassCacheNames[index]);
    725   if (type_id == nullptr) {
    726     *class_index = kIndexNotFound;
    727     return *class_index;
    728   }
    729   *class_index = dex_file->GetIndexForTypeId(*type_id);
    730   return *class_index;
    731 }
    732 
    733 uint32_t DexFileMethodInliner::FindNameIndex(const DexFile* dex_file, IndexCache* cache,
    734                                              NameCacheIndex index) {
    735   uint32_t* name_index = &cache->name_indexes[index];
    736   if (*name_index != kIndexUnresolved) {
    737     return *name_index;
    738   }
    739 
    740   const DexFile::StringId* string_id = dex_file->FindStringId(kNameCacheNames[index]);
    741   if (string_id == nullptr) {
    742     *name_index = kIndexNotFound;
    743     return *name_index;
    744   }
    745   *name_index = dex_file->GetIndexForStringId(*string_id);
    746   return *name_index;
    747 }
    748 
    749 uint32_t DexFileMethodInliner::FindProtoIndex(const DexFile* dex_file, IndexCache* cache,
    750                                               ProtoCacheIndex index) {
    751   uint32_t* proto_index = &cache->proto_indexes[index];
    752   if (*proto_index != kIndexUnresolved) {
    753     return *proto_index;
    754   }
    755 
    756   const ProtoDef& proto_def = kProtoCacheDefs[index];
    757   uint32_t return_index = FindClassIndex(dex_file, cache, proto_def.return_type);
    758   if (return_index == kIndexNotFound) {
    759     *proto_index = kIndexNotFound;
    760     return *proto_index;
    761   }
    762   uint16_t return_type = static_cast<uint16_t>(return_index);
    763   DCHECK_EQ(static_cast<uint32_t>(return_type), return_index);
    764 
    765   uint32_t signature_length = proto_def.param_count;
    766   uint16_t signature_type_idxs[kProtoMaxParams];
    767   for (uint32_t i = 0; i != signature_length; ++i) {
    768     uint32_t param_index = FindClassIndex(dex_file, cache, proto_def.params[i]);
    769     if (param_index == kIndexNotFound) {
    770       *proto_index = kIndexNotFound;
    771       return *proto_index;
    772     }
    773     signature_type_idxs[i] = static_cast<uint16_t>(param_index);
    774     DCHECK_EQ(static_cast<uint32_t>(signature_type_idxs[i]), param_index);
    775   }
    776 
    777   const DexFile::ProtoId* proto_id = dex_file->FindProtoId(return_type, signature_type_idxs,
    778                                                            signature_length);
    779   if (proto_id == nullptr) {
    780     *proto_index = kIndexNotFound;
    781     return *proto_index;
    782   }
    783   *proto_index = dex_file->GetIndexForProtoId(*proto_id);
    784   return *proto_index;
    785 }
    786 
    787 uint32_t DexFileMethodInliner::FindMethodIndex(const DexFile* dex_file, IndexCache* cache,
    788                                                const MethodDef& method_def) {
    789   uint32_t declaring_class_index = FindClassIndex(dex_file, cache, method_def.declaring_class);
    790   if (declaring_class_index == kIndexNotFound) {
    791     return kIndexNotFound;
    792   }
    793   uint32_t name_index = FindNameIndex(dex_file, cache, method_def.name);
    794   if (name_index == kIndexNotFound) {
    795     return kIndexNotFound;
    796   }
    797   uint32_t proto_index = FindProtoIndex(dex_file, cache, method_def.proto);
    798   if (proto_index == kIndexNotFound) {
    799     return kIndexNotFound;
    800   }
    801   const DexFile::MethodId* method_id =
    802       dex_file->FindMethodId(dex_file->GetTypeId(declaring_class_index),
    803                              dex_file->GetStringId(name_index),
    804                              dex_file->GetProtoId(proto_index));
    805   if (method_id == nullptr) {
    806     return kIndexNotFound;
    807   }
    808   return dex_file->GetIndexForMethodId(*method_id);
    809 }
    810 
    811 DexFileMethodInliner::IndexCache::IndexCache() {
    812   std::fill_n(class_indexes, arraysize(class_indexes), kIndexUnresolved);
    813   std::fill_n(name_indexes, arraysize(name_indexes), kIndexUnresolved);
    814   std::fill_n(proto_indexes, arraysize(proto_indexes), kIndexUnresolved);
    815 }
    816 
    817 void DexFileMethodInliner::FindIntrinsics(const DexFile* dex_file) {
    818   DCHECK(dex_file != nullptr);
    819   DCHECK(dex_file_ == nullptr);
    820   IndexCache cache;
    821   for (const IntrinsicDef& def : kIntrinsicMethods) {
    822     uint32_t method_idx = FindMethodIndex(dex_file, &cache, def.method_def);
    823     if (method_idx != kIndexNotFound) {
    824       DCHECK(inline_methods_.find(method_idx) == inline_methods_.end());
    825       inline_methods_.Put(method_idx, def.intrinsic);
    826     }
    827   }
    828   dex_file_ = dex_file;
    829 }
    830 
    831 bool DexFileMethodInliner::AddInlineMethod(int32_t method_idx, const InlineMethod& method) {
    832   WriterMutexLock mu(Thread::Current(), lock_);
    833   if (LIKELY(inline_methods_.find(method_idx) == inline_methods_.end())) {
    834     inline_methods_.Put(method_idx, method);
    835     return true;
    836   } else {
    837     if (PrettyMethod(method_idx, *dex_file_) == "int java.lang.String.length()") {
    838       // TODO: String.length is both kIntrinsicIsEmptyOrLength and kInlineOpIGet.
    839     } else {
    840       LOG(WARNING) << "Inliner: " << PrettyMethod(method_idx, *dex_file_) << " already inline";
    841     }
    842     return false;
    843   }
    844 }
    845 
    846 uint32_t DexFileMethodInliner::GetOffsetForStringInit(uint32_t method_index, size_t pointer_size) {
    847   ReaderMutexLock mu(Thread::Current(), lock_);
    848   auto it = inline_methods_.find(method_index);
    849   if (it != inline_methods_.end() && (it->second.opcode == kInlineStringInit)) {
    850     uint32_t string_init_base_offset = Thread::QuickEntryPointOffsetWithSize(
    851               OFFSETOF_MEMBER(QuickEntryPoints, pNewEmptyString), pointer_size);
    852     return string_init_base_offset + it->second.d.data * pointer_size;
    853   }
    854   return 0;
    855 }
    856 
    857 bool DexFileMethodInliner::IsStringInitMethodIndex(uint32_t method_index) {
    858   ReaderMutexLock mu(Thread::Current(), lock_);
    859   auto it = inline_methods_.find(method_index);
    860   return (it != inline_methods_.end()) && (it->second.opcode == kInlineStringInit);
    861 }
    862 
    863 }  // namespace art
    864