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 30namespace art { 31 32namespace { // anonymous namespace 33 34static 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}; 112static_assert(arraysize(kIntrinsicIsStatic) == kInlineOpNop, 113 "arraysize of kIntrinsicIsStatic unexpected"); 114static_assert(kIntrinsicIsStatic[kIntrinsicDoubleCvt], "DoubleCvt must be static"); 115static_assert(kIntrinsicIsStatic[kIntrinsicFloatCvt], "FloatCvt must be static"); 116static_assert(kIntrinsicIsStatic[kIntrinsicFloat2Int], "Float2Int must be static"); 117static_assert(kIntrinsicIsStatic[kIntrinsicDouble2Long], "Double2Long must be static"); 118static_assert(kIntrinsicIsStatic[kIntrinsicFloatIsInfinite], "FloatIsInfinite must be static"); 119static_assert(kIntrinsicIsStatic[kIntrinsicDoubleIsInfinite], "DoubleIsInfinite must be static"); 120static_assert(kIntrinsicIsStatic[kIntrinsicFloatIsNaN], "FloatIsNaN must be static"); 121static_assert(kIntrinsicIsStatic[kIntrinsicDoubleIsNaN], "DoubleIsNaN must be static"); 122static_assert(kIntrinsicIsStatic[kIntrinsicReverseBits], "ReverseBits must be static"); 123static_assert(kIntrinsicIsStatic[kIntrinsicReverseBytes], "ReverseBytes must be static"); 124static_assert(kIntrinsicIsStatic[kIntrinsicBitCount], "BitCount must be static"); 125static_assert(kIntrinsicIsStatic[kIntrinsicCompare], "Compare must be static"); 126static_assert(kIntrinsicIsStatic[kIntrinsicHighestOneBit], "HighestOneBit must be static"); 127static_assert(kIntrinsicIsStatic[kIntrinsicLowestOneBit], "LowestOneBit must be static"); 128static_assert(kIntrinsicIsStatic[kIntrinsicNumberOfLeadingZeros], 129 "NumberOfLeadingZeros must be static"); 130static_assert(kIntrinsicIsStatic[kIntrinsicNumberOfTrailingZeros], 131 "NumberOfTrailingZeros must be static"); 132static_assert(kIntrinsicIsStatic[kIntrinsicRotateRight], "RotateRight must be static"); 133static_assert(kIntrinsicIsStatic[kIntrinsicRotateLeft], "RotateLeft must be static"); 134static_assert(kIntrinsicIsStatic[kIntrinsicSignum], "Signum must be static"); 135static_assert(kIntrinsicIsStatic[kIntrinsicAbsInt], "AbsInt must be static"); 136static_assert(kIntrinsicIsStatic[kIntrinsicAbsLong], "AbsLong must be static"); 137static_assert(kIntrinsicIsStatic[kIntrinsicAbsFloat], "AbsFloat must be static"); 138static_assert(kIntrinsicIsStatic[kIntrinsicAbsDouble], "AbsDouble must be static"); 139static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxInt], "MinMaxInt must be static"); 140static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxLong], "MinMaxLong must be static"); 141static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxFloat], "MinMaxFloat must be static"); 142static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxDouble], "MinMaxDouble must be static"); 143static_assert(kIntrinsicIsStatic[kIntrinsicCos], "Cos must be static"); 144static_assert(kIntrinsicIsStatic[kIntrinsicSin], "Sin must be static"); 145static_assert(kIntrinsicIsStatic[kIntrinsicAcos], "Acos must be static"); 146static_assert(kIntrinsicIsStatic[kIntrinsicAsin], "Asin must be static"); 147static_assert(kIntrinsicIsStatic[kIntrinsicAtan], "Atan must be static"); 148static_assert(kIntrinsicIsStatic[kIntrinsicAtan2], "Atan2 must be static"); 149static_assert(kIntrinsicIsStatic[kIntrinsicCbrt], "Cbrt must be static"); 150static_assert(kIntrinsicIsStatic[kIntrinsicCosh], "Cosh must be static"); 151static_assert(kIntrinsicIsStatic[kIntrinsicExp], "Exp must be static"); 152static_assert(kIntrinsicIsStatic[kIntrinsicExpm1], "Expm1 must be static"); 153static_assert(kIntrinsicIsStatic[kIntrinsicHypot], "Hypot must be static"); 154static_assert(kIntrinsicIsStatic[kIntrinsicLog], "Log must be static"); 155static_assert(kIntrinsicIsStatic[kIntrinsicLog10], "Log10 must be static"); 156static_assert(kIntrinsicIsStatic[kIntrinsicNextAfter], "NextAfter must be static"); 157static_assert(kIntrinsicIsStatic[kIntrinsicSinh], "Sinh must be static"); 158static_assert(kIntrinsicIsStatic[kIntrinsicTan], "Tan must be static"); 159static_assert(kIntrinsicIsStatic[kIntrinsicTanh], "Tanh must be static"); 160static_assert(kIntrinsicIsStatic[kIntrinsicSqrt], "Sqrt must be static"); 161static_assert(kIntrinsicIsStatic[kIntrinsicCeil], "Ceil must be static"); 162static_assert(kIntrinsicIsStatic[kIntrinsicFloor], "Floor must be static"); 163static_assert(kIntrinsicIsStatic[kIntrinsicRint], "Rint must be static"); 164static_assert(kIntrinsicIsStatic[kIntrinsicRoundFloat], "RoundFloat must be static"); 165static_assert(kIntrinsicIsStatic[kIntrinsicRoundDouble], "RoundDouble must be static"); 166static_assert(!kIntrinsicIsStatic[kIntrinsicReferenceGetReferent], "Get must not be static"); 167static_assert(!kIntrinsicIsStatic[kIntrinsicCharAt], "CharAt must not be static"); 168static_assert(!kIntrinsicIsStatic[kIntrinsicCompareTo], "CompareTo must not be static"); 169static_assert(!kIntrinsicIsStatic[kIntrinsicEquals], "String equals must not be static"); 170static_assert(!kIntrinsicIsStatic[kIntrinsicGetCharsNoCheck], "GetCharsNoCheck must not be static"); 171static_assert(!kIntrinsicIsStatic[kIntrinsicIsEmptyOrLength], "IsEmptyOrLength must not be static"); 172static_assert(!kIntrinsicIsStatic[kIntrinsicIndexOf], "IndexOf must not be static"); 173static_assert(kIntrinsicIsStatic[kIntrinsicNewStringFromBytes], 174 "NewStringFromBytes must be static"); 175static_assert(kIntrinsicIsStatic[kIntrinsicNewStringFromChars], 176 "NewStringFromChars must be static"); 177static_assert(kIntrinsicIsStatic[kIntrinsicNewStringFromString], 178 "NewStringFromString must be static"); 179static_assert(kIntrinsicIsStatic[kIntrinsicCurrentThread], "CurrentThread must be static"); 180static_assert(kIntrinsicIsStatic[kIntrinsicPeek], "Peek must be static"); 181static_assert(kIntrinsicIsStatic[kIntrinsicPoke], "Poke must be static"); 182static_assert(!kIntrinsicIsStatic[kIntrinsicCas], "Cas must not be static"); 183static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGet], "UnsafeGet must not be static"); 184static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafePut], "UnsafePut must not be static"); 185static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndAddInt], "UnsafeGetAndAddInt must not be static"); 186static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndAddLong], "UnsafeGetAndAddLong must not be static"); 187static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetInt], "UnsafeGetAndSetInt must not be static"); 188static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetLong], "UnsafeGetAndSetLong must not be static"); 189static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetObject], "UnsafeGetAndSetObject must not be static"); 190static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeLoadFence], "UnsafeLoadFence must not be static"); 191static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeStoreFence], "UnsafeStoreFence must not be static"); 192static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeFullFence], "UnsafeFullFence must not be static"); 193static_assert(kIntrinsicIsStatic[kIntrinsicSystemArrayCopyCharArray], 194 "SystemArrayCopyCharArray must be static"); 195static_assert(kIntrinsicIsStatic[kIntrinsicSystemArrayCopy], 196 "SystemArrayCopy must be static"); 197 198} // anonymous namespace 199 200const uint32_t DexFileMethodInliner::kIndexUnresolved; 201const 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 234const 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 329const 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 475const 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 667DexFileMethodInliner::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 681DexFileMethodInliner::~DexFileMethodInliner() { 682} 683 684bool 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 690InlineMethodFlags 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 701bool 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 711bool 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 717uint32_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 733uint32_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 749uint32_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 787uint32_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 811DexFileMethodInliner::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 817void 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 831bool 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 846uint32_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 857bool 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