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