diff options
author | 2016-07-15 15:28:35 +0100 | |
---|---|---|
committer | 2016-09-30 10:44:31 +0100 | |
commit | 762869dee6e0eadab5be1c606792d6693bbabf4e (patch) | |
tree | 8c986c621e8a5f3cf4e4e3b2cc13b400401ad89b | |
parent | b4cf427734c6839b46d0d6037e3189a5e8aa1bdb (diff) |
Simplify our intrinsic recognizer.
- Use the modifiers for storing the intrinsic kind.
- Delete dex_file_method_inliner and its associated map.
This work was also motivated by the fact that the inline
method analyzer leaks intrinsic tables, and even worse, might re-use
a table from one dex file to another unrelated dex file in the presence
of class unloading and the unlikely event of the dex files getting
the same address.
test: m test-art-host m test-art-target
Change-Id: Ia653d2c72df13889dc85dd8c84997582c034ea4b
35 files changed, 323 insertions, 2036 deletions
diff --git a/compiler/Android.bp b/compiler/Android.bp index f264d3023b..7fb009adc0 100644 --- a/compiler/Android.bp +++ b/compiler/Android.bp @@ -31,8 +31,6 @@ art_cc_defaults { "dex/verified_method.cc", "dex/verification_results.cc", "dex/quick_compiler_callbacks.cc", - "dex/quick/dex_file_method_inliner.cc", - "dex/quick/dex_file_to_method_inliner_map.cc", "driver/compiled_method_storage.cc", "driver/compiler_driver.cc", "driver/compiler_options.cc", diff --git a/compiler/common_compiler_test.cc b/compiler/common_compiler_test.cc index 63abfeb71e..b726649138 100644 --- a/compiler/common_compiler_test.cc +++ b/compiler/common_compiler_test.cc @@ -23,7 +23,6 @@ #include "class_linker.h" #include "compiled_method.h" #include "dex/quick_compiler_callbacks.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "dex/verification_results.h" #include "driver/compiler_driver.h" #include "driver/compiler_options.h" @@ -177,7 +176,6 @@ void CommonCompilerTest::CreateCompilerDriver(Compiler::Kind kind, size_t number_of_threads) { compiler_driver_.reset(new CompilerDriver(compiler_options_.get(), verification_results_.get(), - method_inliner_map_.get(), kind, isa, instruction_set_features_.get(), @@ -201,9 +199,7 @@ void CommonCompilerTest::SetUpRuntimeOptions(RuntimeOptions* options) { compiler_options_.reset(new CompilerOptions); verification_results_.reset(new VerificationResults(compiler_options_.get())); - method_inliner_map_.reset(new DexFileToMethodInlinerMap); callbacks_.reset(new QuickCompilerCallbacks(verification_results_.get(), - method_inliner_map_.get(), CompilerCallbacks::CallbackMode::kCompileApp)); } @@ -224,7 +220,6 @@ void CommonCompilerTest::TearDown() { timer_.reset(); compiler_driver_.reset(); callbacks_.reset(); - method_inliner_map_.reset(); verification_results_.reset(); compiler_options_.reset(); image_reservation_.reset(); diff --git a/compiler/common_compiler_test.h b/compiler/common_compiler_test.h index 4a02fd5db1..f4838c1119 100644 --- a/compiler/common_compiler_test.h +++ b/compiler/common_compiler_test.h @@ -34,7 +34,6 @@ namespace mirror { class CompilerDriver; class CompilerOptions; class CumulativeLogger; -class DexFileToMethodInlinerMap; class VerificationResults; template<class T> class Handle; @@ -102,7 +101,6 @@ class CommonCompilerTest : public CommonRuntimeTest { Compiler::Kind compiler_kind_ = Compiler::kOptimizing; std::unique_ptr<CompilerOptions> compiler_options_; std::unique_ptr<VerificationResults> verification_results_; - std::unique_ptr<DexFileToMethodInlinerMap> method_inliner_map_; std::unique_ptr<CompilerDriver> compiler_driver_; std::unique_ptr<CumulativeLogger> timer_; std::unique_ptr<const InstructionSetFeatures> instruction_set_features_; diff --git a/compiler/dex/quick/dex_file_method_inliner.cc b/compiler/dex/quick/dex_file_method_inliner.cc deleted file mode 100644 index 67505541c2..0000000000 --- a/compiler/dex/quick/dex_file_method_inliner.cc +++ /dev/null @@ -1,824 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "dex_file_method_inliner.h" - -#include <algorithm> - -#include "base/logging.h" -#include "base/macros.h" -#include "base/mutex-inl.h" -#include "driver/compiler_driver.h" -#include "thread-inl.h" -#include "dex_instruction-inl.h" -#include "driver/dex_compilation_unit.h" -#include "verifier/method_verifier-inl.h" - -namespace art { - -namespace { // anonymous namespace - -static constexpr bool kIntrinsicIsStatic[] = { - true, // kIntrinsicDoubleCvt - true, // kIntrinsicFloatCvt - true, // kIntrinsicFloat2Int - true, // kIntrinsicDouble2Long - true, // kIntrinsicFloatIsInfinite - true, // kIntrinsicDoubleIsInfinite - true, // kIntrinsicFloatIsNaN - true, // kIntrinsicDoubleIsNaN - true, // kIntrinsicReverseBits - true, // kIntrinsicReverseBytes - true, // kIntrinsicBitCount - true, // kIntrinsicCompare, - true, // kIntrinsicHighestOneBit - true, // kIntrinsicLowestOneBit - true, // kIntrinsicNumberOfLeadingZeros - true, // kIntrinsicNumberOfTrailingZeros - true, // kIntrinsicRotateRight - true, // kIntrinsicRotateLeft - true, // kIntrinsicSignum - true, // kIntrinsicAbsInt - true, // kIntrinsicAbsLong - true, // kIntrinsicAbsFloat - true, // kIntrinsicAbsDouble - true, // kIntrinsicMinMaxInt - true, // kIntrinsicMinMaxLong - true, // kIntrinsicMinMaxFloat - true, // kIntrinsicMinMaxDouble - true, // kIntrinsicCos - true, // kIntrinsicSin - true, // kIntrinsicAcos - true, // kIntrinsicAsin - true, // kIntrinsicAtan - true, // kIntrinsicAtan2 - true, // kIntrinsicCbrt - true, // kIntrinsicCosh - true, // kIntrinsicExp - true, // kIntrinsicExpm1 - true, // kIntrinsicHypot - true, // kIntrinsicLog - true, // kIntrinsicLog10 - true, // kIntrinsicNextAfter - true, // kIntrinsicSinh - true, // kIntrinsicTan - true, // kIntrinsicTanh - true, // kIntrinsicSqrt - true, // kIntrinsicCeil - true, // kIntrinsicFloor - true, // kIntrinsicRint - true, // kIntrinsicRoundFloat - true, // kIntrinsicRoundDouble - false, // kIntrinsicReferenceGetReferent - false, // kIntrinsicCharAt - false, // kIntrinsicCompareTo - false, // kIntrinsicEquals - false, // kIntrinsicGetCharsNoCheck - false, // kIntrinsicIsEmptyOrLength - false, // kIntrinsicIndexOf - true, // kIntrinsicNewStringFromBytes - true, // kIntrinsicNewStringFromChars - true, // kIntrinsicNewStringFromString - true, // kIntrinsicCurrentThread - true, // kIntrinsicPeek - true, // kIntrinsicPoke - false, // kIntrinsicCas - false, // kIntrinsicUnsafeGet - false, // kIntrinsicUnsafePut - false, // kIntrinsicUnsafeGetAndAddInt, - false, // kIntrinsicUnsafeGetAndAddLong, - false, // kIntrinsicUnsafeGetAndSetInt, - false, // kIntrinsicUnsafeGetAndSetLong, - false, // kIntrinsicUnsafeGetAndSetObject, - false, // kIntrinsicUnsafeLoadFence, - false, // kIntrinsicUnsafeStoreFence, - false, // kIntrinsicUnsafeFullFence, - true, // kIntrinsicSystemArrayCopyCharArray - true, // kIntrinsicSystemArrayCopy -}; -static_assert(arraysize(kIntrinsicIsStatic) == kInlineOpNop, - "arraysize of kIntrinsicIsStatic unexpected"); -static_assert(kIntrinsicIsStatic[kIntrinsicDoubleCvt], "DoubleCvt must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicFloatCvt], "FloatCvt must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicFloat2Int], "Float2Int must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicDouble2Long], "Double2Long must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicFloatIsInfinite], "FloatIsInfinite must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicDoubleIsInfinite], "DoubleIsInfinite must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicFloatIsNaN], "FloatIsNaN must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicDoubleIsNaN], "DoubleIsNaN must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicReverseBits], "ReverseBits must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicReverseBytes], "ReverseBytes must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicBitCount], "BitCount must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicCompare], "Compare must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicHighestOneBit], "HighestOneBit must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicLowestOneBit], "LowestOneBit must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicNumberOfLeadingZeros], - "NumberOfLeadingZeros must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicNumberOfTrailingZeros], - "NumberOfTrailingZeros must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicRotateRight], "RotateRight must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicRotateLeft], "RotateLeft must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicSignum], "Signum must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAbsInt], "AbsInt must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAbsLong], "AbsLong must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAbsFloat], "AbsFloat must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAbsDouble], "AbsDouble must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxInt], "MinMaxInt must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxLong], "MinMaxLong must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxFloat], "MinMaxFloat must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicMinMaxDouble], "MinMaxDouble must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicCos], "Cos must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicSin], "Sin must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAcos], "Acos must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAsin], "Asin must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAtan], "Atan must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicAtan2], "Atan2 must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicCbrt], "Cbrt must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicCosh], "Cosh must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicExp], "Exp must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicExpm1], "Expm1 must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicHypot], "Hypot must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicLog], "Log must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicLog10], "Log10 must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicNextAfter], "NextAfter must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicSinh], "Sinh must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicTan], "Tan must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicTanh], "Tanh must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicSqrt], "Sqrt must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicCeil], "Ceil must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicFloor], "Floor must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicRint], "Rint must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicRoundFloat], "RoundFloat must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicRoundDouble], "RoundDouble must be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicReferenceGetReferent], "Get must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicCharAt], "CharAt must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicCompareTo], "CompareTo must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicEquals], "String equals must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicGetCharsNoCheck], "GetCharsNoCheck must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicIsEmptyOrLength], "IsEmptyOrLength must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicIndexOf], "IndexOf must not be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicNewStringFromBytes], - "NewStringFromBytes must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicNewStringFromChars], - "NewStringFromChars must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicNewStringFromString], - "NewStringFromString must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicCurrentThread], "CurrentThread must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicPeek], "Peek must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicPoke], "Poke must be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicCas], "Cas must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGet], "UnsafeGet must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafePut], "UnsafePut must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndAddInt], "UnsafeGetAndAddInt must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndAddLong], "UnsafeGetAndAddLong must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetInt], "UnsafeGetAndSetInt must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetLong], "UnsafeGetAndSetLong must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeGetAndSetObject], "UnsafeGetAndSetObject must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeLoadFence], "UnsafeLoadFence must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeStoreFence], "UnsafeStoreFence must not be static"); -static_assert(!kIntrinsicIsStatic[kIntrinsicUnsafeFullFence], "UnsafeFullFence must not be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicSystemArrayCopyCharArray], - "SystemArrayCopyCharArray must be static"); -static_assert(kIntrinsicIsStatic[kIntrinsicSystemArrayCopy], - "SystemArrayCopy must be static"); - -} // anonymous namespace - -const uint32_t DexFileMethodInliner::kIndexUnresolved; -const char* const DexFileMethodInliner::kClassCacheNames[] = { - "Z", // kClassCacheBoolean - "B", // kClassCacheByte - "C", // kClassCacheChar - "S", // kClassCacheShort - "I", // kClassCacheInt - "J", // kClassCacheLong - "F", // kClassCacheFloat - "D", // kClassCacheDouble - "V", // kClassCacheVoid - "[B", // kClassCacheJavaLangByteArray - "[C", // kClassCacheJavaLangCharArray - "[I", // kClassCacheJavaLangIntArray - "Ljava/lang/Object;", // kClassCacheJavaLangObject - "Ljava/lang/ref/Reference;", // kClassCacheJavaLangRefReference - "Ljava/lang/String;", // kClassCacheJavaLangString - "Ljava/lang/StringBuffer;", // kClassCacheJavaLangStringBuffer - "Ljava/lang/StringBuilder;", // kClassCacheJavaLangStringBuilder - "Ljava/lang/StringFactory;", // kClassCacheJavaLangStringFactory - "Ljava/lang/Double;", // kClassCacheJavaLangDouble - "Ljava/lang/Float;", // kClassCacheJavaLangFloat - "Ljava/lang/Integer;", // kClassCacheJavaLangInteger - "Ljava/lang/Long;", // kClassCacheJavaLangLong - "Ljava/lang/Short;", // kClassCacheJavaLangShort - "Ljava/lang/Math;", // kClassCacheJavaLangMath - "Ljava/lang/StrictMath;", // kClassCacheJavaLangStrictMath - "Ljava/lang/Thread;", // kClassCacheJavaLangThread - "Ljava/nio/charset/Charset;", // kClassCacheJavaNioCharsetCharset - "Llibcore/io/Memory;", // kClassCacheLibcoreIoMemory - "Lsun/misc/Unsafe;", // kClassCacheSunMiscUnsafe - "Ljava/lang/System;", // kClassCacheJavaLangSystem -}; - -const char* const DexFileMethodInliner::kNameCacheNames[] = { - "reverse", // kNameCacheReverse - "reverseBytes", // kNameCacheReverseBytes - "doubleToRawLongBits", // kNameCacheDoubleToRawLongBits - "longBitsToDouble", // kNameCacheLongBitsToDouble - "floatToRawIntBits", // kNameCacheFloatToRawIntBits - "intBitsToFloat", // kNameCacheIntBitsToFloat - "abs", // kNameCacheAbs - "max", // kNameCacheMax - "min", // kNameCacheMin - "cos", // kNameCacheCos - "sin", // kNameCacheSin - "acos", // kNameCacheAcos - "asin", // kNameCacheAsin - "atan", // kNameCacheAtan - "atan2", // kNameCacheAtan2 - "cbrt", // kNameCacheCbrt - "cosh", // kNameCacheCosh - "exp", // kNameCacheExp - "expm1", // kNameCacheExpm1 - "hypot", // kNameCacheHypot - "log", // kNameCacheLog - "log10", // kNameCacheLog10 - "nextAfter", // kNameCacheNextAfter - "sinh", // kNameCacheSinh - "tan", // kNameCacheTan - "tanh", // kNameCacheTanh - "sqrt", // kNameCacheSqrt - "ceil", // kNameCacheCeil - "floor", // kNameCacheFloor - "rint", // kNameCacheRint - "round", // kNameCacheRound - "getReferent", // kNameCacheReferenceGet - "charAt", // kNameCacheCharAt - "compareTo", // kNameCacheCompareTo - "equals", // kNameCacheEquals - "getCharsNoCheck", // kNameCacheGetCharsNoCheck - "isEmpty", // kNameCacheIsEmpty - "floatToIntBits", // kNameCacheFloatToIntBits - "doubleToLongBits", // kNameCacheDoubleToLongBits - "isInfinite", // kNameCacheIsInfinite - "isNaN", // kNameCacheIsNaN - "indexOf", // kNameCacheIndexOf - "length", // kNameCacheLength - "<init>", // kNameCacheInit - "newStringFromBytes", // kNameCacheNewStringFromBytes - "newStringFromChars", // kNameCacheNewStringFromChars - "newStringFromString", // kNameCacheNewStringFromString - "currentThread", // kNameCacheCurrentThread - "peekByte", // kNameCachePeekByte - "peekIntNative", // kNameCachePeekIntNative - "peekLongNative", // kNameCachePeekLongNative - "peekShortNative", // kNameCachePeekShortNative - "pokeByte", // kNameCachePokeByte - "pokeIntNative", // kNameCachePokeIntNative - "pokeLongNative", // kNameCachePokeLongNative - "pokeShortNative", // kNameCachePokeShortNative - "compareAndSwapInt", // kNameCacheCompareAndSwapInt - "compareAndSwapLong", // kNameCacheCompareAndSwapLong - "compareAndSwapObject", // kNameCacheCompareAndSwapObject - "getInt", // kNameCacheGetInt - "getIntVolatile", // kNameCacheGetIntVolatile - "putInt", // kNameCachePutInt - "putIntVolatile", // kNameCachePutIntVolatile - "putOrderedInt", // kNameCachePutOrderedInt - "getLong", // kNameCacheGetLong - "getLongVolatile", // kNameCacheGetLongVolatile - "putLong", // kNameCachePutLong - "putLongVolatile", // kNameCachePutLongVolatile - "putOrderedLong", // kNameCachePutOrderedLong - "getObject", // kNameCacheGetObject - "getObjectVolatile", // kNameCacheGetObjectVolatile - "putObject", // kNameCachePutObject - "putObjectVolatile", // kNameCachePutObjectVolatile - "putOrderedObject", // kNameCachePutOrderedObject - "getAndAddInt", // kNameCacheGetAndAddInt, - "getAndAddLong", // kNameCacheGetAndAddLong, - "getAndSetInt", // kNameCacheGetAndSetInt, - "getAndSetLong", // kNameCacheGetAndSetLong, - "getAndSetObject", // kNameCacheGetAndSetObject, - "loadFence", // kNameCacheLoadFence, - "storeFence", // kNameCacheStoreFence, - "fullFence", // kNameCacheFullFence, - "arraycopy", // kNameCacheArrayCopy - "bitCount", // kNameCacheBitCount - "compare", // kNameCacheCompare - "highestOneBit", // kNameCacheHighestOneBit - "lowestOneBit", // kNameCacheLowestOneBit - "numberOfLeadingZeros", // kNameCacheNumberOfLeadingZeros - "numberOfTrailingZeros", // kNameCacheNumberOfTrailingZeros - "rotateRight", // kNameCacheRotateRight - "rotateLeft", // kNameCacheRotateLeft - "signum", // kNameCacheSignum -}; - -const DexFileMethodInliner::ProtoDef DexFileMethodInliner::kProtoCacheDefs[] = { - // kProtoCacheI_I - { kClassCacheInt, 1, { kClassCacheInt } }, - // kProtoCacheJ_J - { kClassCacheLong, 1, { kClassCacheLong } }, - // kProtoCacheS_S - { kClassCacheShort, 1, { kClassCacheShort } }, - // kProtoCacheD_D - { kClassCacheDouble, 1, { kClassCacheDouble } }, - // kProtoCacheDD_D - { kClassCacheDouble, 2, { kClassCacheDouble, kClassCacheDouble } }, - // kProtoCacheF_F - { kClassCacheFloat, 1, { kClassCacheFloat } }, - // kProtoCacheFF_F - { kClassCacheFloat, 2, { kClassCacheFloat, kClassCacheFloat } }, - // kProtoCacheD_J - { kClassCacheLong, 1, { kClassCacheDouble } }, - // kProtoCacheD_Z - { kClassCacheBoolean, 1, { kClassCacheDouble } }, - // kProtoCacheJ_D - { kClassCacheDouble, 1, { kClassCacheLong } }, - // kProtoCacheF_I - { kClassCacheInt, 1, { kClassCacheFloat } }, - // kProtoCacheF_Z - { kClassCacheBoolean, 1, { kClassCacheFloat } }, - // kProtoCacheI_F - { kClassCacheFloat, 1, { kClassCacheInt } }, - // kProtoCacheII_I - { kClassCacheInt, 2, { kClassCacheInt, kClassCacheInt } }, - // kProtoCacheI_C - { kClassCacheChar, 1, { kClassCacheInt } }, - // kProtoCacheString_I - { kClassCacheInt, 1, { kClassCacheJavaLangString } }, - // kProtoCache_Z - { kClassCacheBoolean, 0, { } }, - // kProtoCache_I - { kClassCacheInt, 0, { } }, - // kProtoCache_Object - { kClassCacheJavaLangObject, 0, { } }, - // kProtoCache_Thread - { kClassCacheJavaLangThread, 0, { } }, - // kProtoCacheJ_B - { kClassCacheByte, 1, { kClassCacheLong } }, - // kProtoCacheJ_I - { kClassCacheInt, 1, { kClassCacheLong } }, - // kProtoCacheJ_S - { kClassCacheShort, 1, { kClassCacheLong } }, - // kProtoCacheJB_V - { kClassCacheVoid, 2, { kClassCacheLong, kClassCacheByte } }, - // kProtoCacheJI_V - { kClassCacheVoid, 2, { kClassCacheLong, kClassCacheInt } }, - // kProtoCacheJJ_J - { kClassCacheLong, 2, { kClassCacheLong, kClassCacheLong } }, - // kProtoCacheJJ_I - { kClassCacheInt, 2, { kClassCacheLong, kClassCacheLong } }, - // kProtoCacheJJ_V - { kClassCacheVoid, 2, { kClassCacheLong, kClassCacheLong } }, - // kProtoCacheJS_V - { kClassCacheVoid, 2, { kClassCacheLong, kClassCacheShort } }, - // kProtoCacheObject_Z - { kClassCacheBoolean, 1, { kClassCacheJavaLangObject } }, - // kProtoCacheJI_J - { kClassCacheLong, 2, { kClassCacheLong, kClassCacheInt } }, - // kProtoCacheObjectJII_Z - { kClassCacheBoolean, 4, { kClassCacheJavaLangObject, kClassCacheLong, - kClassCacheInt, kClassCacheInt } }, - // kProtoCacheObjectJJJ_Z - { kClassCacheBoolean, 4, { kClassCacheJavaLangObject, kClassCacheLong, - kClassCacheLong, kClassCacheLong } }, - // kProtoCacheObjectJObjectObject_Z - { kClassCacheBoolean, 4, { kClassCacheJavaLangObject, kClassCacheLong, - kClassCacheJavaLangObject, kClassCacheJavaLangObject } }, - // kProtoCacheObjectJ_I - { kClassCacheInt, 2, { kClassCacheJavaLangObject, kClassCacheLong } }, - // kProtoCacheObjectJI_I - { kClassCacheInt, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheInt } }, - // kProtoCacheObjectJI_V - { kClassCacheVoid, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheInt } }, - // kProtoCacheObjectJ_J - { kClassCacheLong, 2, { kClassCacheJavaLangObject, kClassCacheLong } }, - // kProtoCacheObjectJJ_J - { kClassCacheLong, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheLong } }, - // kProtoCacheObjectJJ_V - { kClassCacheVoid, 3, { kClassCacheJavaLangObject, kClassCacheLong, kClassCacheLong } }, - // kProtoCacheObjectJ_Object - { kClassCacheJavaLangObject, 2, { kClassCacheJavaLangObject, kClassCacheLong } }, - // kProtoCacheObjectJObject_V - { kClassCacheVoid, 3, { kClassCacheJavaLangObject, kClassCacheLong, - kClassCacheJavaLangObject } }, - // kProtoCacheObjectJObject_Object - { kClassCacheJavaLangObject, 3, { kClassCacheJavaLangObject, kClassCacheLong, - kClassCacheJavaLangObject } }, - // kProtoCacheCharArrayICharArrayII_V - { kClassCacheVoid, 5, {kClassCacheJavaLangCharArray, kClassCacheInt, - kClassCacheJavaLangCharArray, kClassCacheInt, kClassCacheInt} }, - // kProtoCacheObjectIObjectII_V - { kClassCacheVoid, 5, {kClassCacheJavaLangObject, kClassCacheInt, - kClassCacheJavaLangObject, kClassCacheInt, kClassCacheInt} }, - // kProtoCacheIICharArrayI_V - { kClassCacheVoid, 4, { kClassCacheInt, kClassCacheInt, kClassCacheJavaLangCharArray, - kClassCacheInt } }, - // kProtoCacheByteArrayIII_String - { kClassCacheJavaLangString, 4, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt, - kClassCacheInt } }, - // kProtoCacheIICharArray_String - { kClassCacheJavaLangString, 3, { kClassCacheInt, kClassCacheInt, - kClassCacheJavaLangCharArray } }, - // kProtoCacheString_String - { kClassCacheJavaLangString, 1, { kClassCacheJavaLangString } }, - // kProtoCache_V - { kClassCacheVoid, 0, { } }, - // kProtoCacheByteArray_V - { kClassCacheVoid, 1, { kClassCacheJavaLangByteArray } }, - // kProtoCacheByteArrayI_V - { kClassCacheVoid, 2, { kClassCacheJavaLangByteArray, kClassCacheInt } }, - // kProtoCacheByteArrayII_V - { kClassCacheVoid, 3, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt } }, - // kProtoCacheByteArrayIII_V - { kClassCacheVoid, 4, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt, - kClassCacheInt } }, - // kProtoCacheByteArrayIIString_V - { kClassCacheVoid, 4, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt, - kClassCacheJavaLangString } }, - // kProtoCacheByteArrayString_V - { kClassCacheVoid, 2, { kClassCacheJavaLangByteArray, kClassCacheJavaLangString } }, - // kProtoCacheByteArrayIICharset_V - { kClassCacheVoid, 4, { kClassCacheJavaLangByteArray, kClassCacheInt, kClassCacheInt, - kClassCacheJavaNioCharsetCharset } }, - // kProtoCacheByteArrayCharset_V - { kClassCacheVoid, 2, { kClassCacheJavaLangByteArray, kClassCacheJavaNioCharsetCharset } }, - // kProtoCacheCharArray_V - { kClassCacheVoid, 1, { kClassCacheJavaLangCharArray } }, - // kProtoCacheCharArrayII_V - { kClassCacheVoid, 3, { kClassCacheJavaLangCharArray, kClassCacheInt, kClassCacheInt } }, - // kProtoCacheIICharArray_V - { kClassCacheVoid, 3, { kClassCacheInt, kClassCacheInt, kClassCacheJavaLangCharArray } }, - // kProtoCacheIntArrayII_V - { kClassCacheVoid, 3, { kClassCacheJavaLangIntArray, kClassCacheInt, kClassCacheInt } }, - // kProtoCacheString_V - { kClassCacheVoid, 1, { kClassCacheJavaLangString } }, - // kProtoCacheStringBuffer_V - { kClassCacheVoid, 1, { kClassCacheJavaLangStringBuffer } }, - // kProtoCacheStringBuilder_V - { kClassCacheVoid, 1, { kClassCacheJavaLangStringBuilder } }, -}; - -const DexFileMethodInliner::IntrinsicDef DexFileMethodInliner::kIntrinsicMethods[] = { -#define INTRINSIC(c, n, p, o, d) \ - { { kClassCache ## c, kNameCache ## n, kProtoCache ## p }, { o, kInlineIntrinsic, { d } } } - - INTRINSIC(JavaLangDouble, DoubleToRawLongBits, D_J, kIntrinsicDoubleCvt, 0), - INTRINSIC(JavaLangDouble, LongBitsToDouble, J_D, kIntrinsicDoubleCvt, kIntrinsicFlagToFloatingPoint), - INTRINSIC(JavaLangFloat, FloatToRawIntBits, F_I, kIntrinsicFloatCvt, 0), - INTRINSIC(JavaLangFloat, IntBitsToFloat, I_F, kIntrinsicFloatCvt, kIntrinsicFlagToFloatingPoint), - - INTRINSIC(JavaLangFloat, FloatToIntBits, F_I, kIntrinsicFloat2Int, 0), - INTRINSIC(JavaLangDouble, DoubleToLongBits, D_J, kIntrinsicDouble2Long, 0), - - INTRINSIC(JavaLangFloat, IsInfinite, F_Z, kIntrinsicFloatIsInfinite, 0), - INTRINSIC(JavaLangDouble, IsInfinite, D_Z, kIntrinsicDoubleIsInfinite, 0), - INTRINSIC(JavaLangFloat, IsNaN, F_Z, kIntrinsicFloatIsNaN, 0), - INTRINSIC(JavaLangDouble, IsNaN, D_Z, kIntrinsicDoubleIsNaN, 0), - - INTRINSIC(JavaLangInteger, ReverseBytes, I_I, kIntrinsicReverseBytes, k32), - INTRINSIC(JavaLangLong, ReverseBytes, J_J, kIntrinsicReverseBytes, k64), - INTRINSIC(JavaLangShort, ReverseBytes, S_S, kIntrinsicReverseBytes, kSignedHalf), - INTRINSIC(JavaLangInteger, Reverse, I_I, kIntrinsicReverseBits, k32), - INTRINSIC(JavaLangLong, Reverse, J_J, kIntrinsicReverseBits, k64), - - INTRINSIC(JavaLangInteger, BitCount, I_I, kIntrinsicBitCount, k32), - INTRINSIC(JavaLangLong, BitCount, J_I, kIntrinsicBitCount, k64), - INTRINSIC(JavaLangInteger, Compare, II_I, kIntrinsicCompare, k32), - INTRINSIC(JavaLangLong, Compare, JJ_I, kIntrinsicCompare, k64), - INTRINSIC(JavaLangInteger, HighestOneBit, I_I, kIntrinsicHighestOneBit, k32), - INTRINSIC(JavaLangLong, HighestOneBit, J_J, kIntrinsicHighestOneBit, k64), - INTRINSIC(JavaLangInteger, LowestOneBit, I_I, kIntrinsicLowestOneBit, k32), - INTRINSIC(JavaLangLong, LowestOneBit, J_J, kIntrinsicLowestOneBit, k64), - INTRINSIC(JavaLangInteger, NumberOfLeadingZeros, I_I, kIntrinsicNumberOfLeadingZeros, k32), - INTRINSIC(JavaLangLong, NumberOfLeadingZeros, J_I, kIntrinsicNumberOfLeadingZeros, k64), - INTRINSIC(JavaLangInteger, NumberOfTrailingZeros, I_I, kIntrinsicNumberOfTrailingZeros, k32), - INTRINSIC(JavaLangLong, NumberOfTrailingZeros, J_I, kIntrinsicNumberOfTrailingZeros, k64), - INTRINSIC(JavaLangInteger, Signum, I_I, kIntrinsicSignum, k32), - INTRINSIC(JavaLangLong, Signum, J_I, kIntrinsicSignum, k64), - - INTRINSIC(JavaLangMath, Abs, I_I, kIntrinsicAbsInt, 0), - INTRINSIC(JavaLangStrictMath, Abs, I_I, kIntrinsicAbsInt, 0), - INTRINSIC(JavaLangMath, Abs, J_J, kIntrinsicAbsLong, 0), - INTRINSIC(JavaLangStrictMath, Abs, J_J, kIntrinsicAbsLong, 0), - INTRINSIC(JavaLangMath, Abs, F_F, kIntrinsicAbsFloat, 0), - INTRINSIC(JavaLangStrictMath, Abs, F_F, kIntrinsicAbsFloat, 0), - INTRINSIC(JavaLangMath, Abs, D_D, kIntrinsicAbsDouble, 0), - INTRINSIC(JavaLangStrictMath, Abs, D_D, kIntrinsicAbsDouble, 0), - INTRINSIC(JavaLangMath, Min, II_I, kIntrinsicMinMaxInt, kIntrinsicFlagMin), - INTRINSIC(JavaLangStrictMath, Min, II_I, kIntrinsicMinMaxInt, kIntrinsicFlagMin), - INTRINSIC(JavaLangMath, Max, II_I, kIntrinsicMinMaxInt, kIntrinsicFlagMax), - INTRINSIC(JavaLangStrictMath, Max, II_I, kIntrinsicMinMaxInt, kIntrinsicFlagMax), - INTRINSIC(JavaLangMath, Min, JJ_J, kIntrinsicMinMaxLong, kIntrinsicFlagMin), - INTRINSIC(JavaLangStrictMath, Min, JJ_J, kIntrinsicMinMaxLong, kIntrinsicFlagMin), - INTRINSIC(JavaLangMath, Max, JJ_J, kIntrinsicMinMaxLong, kIntrinsicFlagMax), - INTRINSIC(JavaLangStrictMath, Max, JJ_J, kIntrinsicMinMaxLong, kIntrinsicFlagMax), - INTRINSIC(JavaLangMath, Min, FF_F, kIntrinsicMinMaxFloat, kIntrinsicFlagMin), - INTRINSIC(JavaLangStrictMath, Min, FF_F, kIntrinsicMinMaxFloat, kIntrinsicFlagMin), - INTRINSIC(JavaLangMath, Max, FF_F, kIntrinsicMinMaxFloat, kIntrinsicFlagMax), - INTRINSIC(JavaLangStrictMath, Max, FF_F, kIntrinsicMinMaxFloat, kIntrinsicFlagMax), - INTRINSIC(JavaLangMath, Min, DD_D, kIntrinsicMinMaxDouble, kIntrinsicFlagMin), - INTRINSIC(JavaLangStrictMath, Min, DD_D, kIntrinsicMinMaxDouble, kIntrinsicFlagMin), - INTRINSIC(JavaLangMath, Max, DD_D, kIntrinsicMinMaxDouble, kIntrinsicFlagMax), - INTRINSIC(JavaLangStrictMath, Max, DD_D, kIntrinsicMinMaxDouble, kIntrinsicFlagMax), - - INTRINSIC(JavaLangMath, Cos, D_D, kIntrinsicCos, 0), - INTRINSIC(JavaLangMath, Sin, D_D, kIntrinsicSin, 0), - INTRINSIC(JavaLangMath, Acos, D_D, kIntrinsicAcos, 0), - INTRINSIC(JavaLangMath, Asin, D_D, kIntrinsicAsin, 0), - INTRINSIC(JavaLangMath, Atan, D_D, kIntrinsicAtan, 0), - INTRINSIC(JavaLangMath, Atan2, DD_D, kIntrinsicAtan2, 0), - INTRINSIC(JavaLangMath, Cbrt, D_D, kIntrinsicCbrt, 0), - INTRINSIC(JavaLangMath, Cosh, D_D, kIntrinsicCosh, 0), - INTRINSIC(JavaLangMath, Exp, D_D, kIntrinsicExp, 0), - INTRINSIC(JavaLangMath, Expm1, D_D, kIntrinsicExpm1, 0), - INTRINSIC(JavaLangMath, Hypot, DD_D, kIntrinsicHypot, 0), - INTRINSIC(JavaLangMath, Log, D_D, kIntrinsicLog, 0), - INTRINSIC(JavaLangMath, Log10, D_D, kIntrinsicLog10, 0), - INTRINSIC(JavaLangMath, NextAfter, DD_D, kIntrinsicNextAfter, 0), - INTRINSIC(JavaLangMath, Sinh, D_D, kIntrinsicSinh, 0), - INTRINSIC(JavaLangMath, Tan, D_D, kIntrinsicTan, 0), - INTRINSIC(JavaLangMath, Tanh, D_D, kIntrinsicTanh, 0), - INTRINSIC(JavaLangMath, Sqrt, D_D, kIntrinsicSqrt, 0), - INTRINSIC(JavaLangStrictMath, Sqrt, D_D, kIntrinsicSqrt, 0), - - INTRINSIC(JavaLangMath, Ceil, D_D, kIntrinsicCeil, 0), - INTRINSIC(JavaLangStrictMath, Ceil, D_D, kIntrinsicCeil, 0), - INTRINSIC(JavaLangMath, Floor, D_D, kIntrinsicFloor, 0), - INTRINSIC(JavaLangStrictMath, Floor, D_D, kIntrinsicFloor, 0), - INTRINSIC(JavaLangMath, Rint, D_D, kIntrinsicRint, 0), - INTRINSIC(JavaLangStrictMath, Rint, D_D, kIntrinsicRint, 0), - INTRINSIC(JavaLangMath, Round, F_I, kIntrinsicRoundFloat, 0), - INTRINSIC(JavaLangStrictMath, Round, F_I, kIntrinsicRoundFloat, 0), - INTRINSIC(JavaLangMath, Round, D_J, kIntrinsicRoundDouble, 0), - INTRINSIC(JavaLangStrictMath, Round, D_J, kIntrinsicRoundDouble, 0), - - INTRINSIC(JavaLangRefReference, ReferenceGetReferent, _Object, kIntrinsicReferenceGetReferent, 0), - - INTRINSIC(JavaLangString, CharAt, I_C, kIntrinsicCharAt, 0), - INTRINSIC(JavaLangString, CompareTo, String_I, kIntrinsicCompareTo, 0), - INTRINSIC(JavaLangString, Equals, Object_Z, kIntrinsicEquals, 0), - INTRINSIC(JavaLangString, GetCharsNoCheck, IICharArrayI_V, kIntrinsicGetCharsNoCheck, 0), - INTRINSIC(JavaLangString, IsEmpty, _Z, kIntrinsicIsEmptyOrLength, kIntrinsicFlagIsEmpty), - INTRINSIC(JavaLangString, IndexOf, II_I, kIntrinsicIndexOf, kIntrinsicFlagNone), - INTRINSIC(JavaLangString, IndexOf, I_I, kIntrinsicIndexOf, kIntrinsicFlagBase0), - INTRINSIC(JavaLangString, Length, _I, kIntrinsicIsEmptyOrLength, kIntrinsicFlagLength), - - INTRINSIC(JavaLangStringFactory, NewStringFromBytes, ByteArrayIII_String, - kIntrinsicNewStringFromBytes, kIntrinsicFlagNone), - INTRINSIC(JavaLangStringFactory, NewStringFromChars, IICharArray_String, - kIntrinsicNewStringFromChars, kIntrinsicFlagNone), - INTRINSIC(JavaLangStringFactory, NewStringFromString, String_String, - kIntrinsicNewStringFromString, kIntrinsicFlagNone), - - INTRINSIC(JavaLangThread, CurrentThread, _Thread, kIntrinsicCurrentThread, 0), - - INTRINSIC(LibcoreIoMemory, PeekByte, J_B, kIntrinsicPeek, kSignedByte), - INTRINSIC(LibcoreIoMemory, PeekIntNative, J_I, kIntrinsicPeek, k32), - INTRINSIC(LibcoreIoMemory, PeekLongNative, J_J, kIntrinsicPeek, k64), - INTRINSIC(LibcoreIoMemory, PeekShortNative, J_S, kIntrinsicPeek, kSignedHalf), - INTRINSIC(LibcoreIoMemory, PokeByte, JB_V, kIntrinsicPoke, kSignedByte), - INTRINSIC(LibcoreIoMemory, PokeIntNative, JI_V, kIntrinsicPoke, k32), - INTRINSIC(LibcoreIoMemory, PokeLongNative, JJ_V, kIntrinsicPoke, k64), - INTRINSIC(LibcoreIoMemory, PokeShortNative, JS_V, kIntrinsicPoke, kSignedHalf), - - INTRINSIC(SunMiscUnsafe, CompareAndSwapInt, ObjectJII_Z, kIntrinsicCas, - kIntrinsicFlagNone), - INTRINSIC(SunMiscUnsafe, CompareAndSwapLong, ObjectJJJ_Z, kIntrinsicCas, - kIntrinsicFlagIsLong), - INTRINSIC(SunMiscUnsafe, CompareAndSwapObject, ObjectJObjectObject_Z, kIntrinsicCas, - kIntrinsicFlagIsObject), - -#define UNSAFE_GET_PUT(type, code, type_flags) \ - INTRINSIC(SunMiscUnsafe, Get ## type, ObjectJ_ ## code, kIntrinsicUnsafeGet, \ - type_flags), \ - INTRINSIC(SunMiscUnsafe, Get ## type ## Volatile, ObjectJ_ ## code, kIntrinsicUnsafeGet, \ - (type_flags) | kIntrinsicFlagIsVolatile), \ - INTRINSIC(SunMiscUnsafe, Put ## type, ObjectJ ## code ## _V, kIntrinsicUnsafePut, \ - type_flags), \ - INTRINSIC(SunMiscUnsafe, Put ## type ## Volatile, ObjectJ ## code ## _V, kIntrinsicUnsafePut, \ - (type_flags) | kIntrinsicFlagIsVolatile), \ - INTRINSIC(SunMiscUnsafe, PutOrdered ## type, ObjectJ ## code ## _V, kIntrinsicUnsafePut, \ - (type_flags) | kIntrinsicFlagIsOrdered) - - UNSAFE_GET_PUT(Int, I, kIntrinsicFlagNone), - UNSAFE_GET_PUT(Long, J, kIntrinsicFlagIsLong), - UNSAFE_GET_PUT(Object, Object, kIntrinsicFlagIsObject), -#undef UNSAFE_GET_PUT - - // 1.8 - INTRINSIC(SunMiscUnsafe, GetAndAddInt, ObjectJI_I, kIntrinsicUnsafeGetAndAddInt, 0), - INTRINSIC(SunMiscUnsafe, GetAndAddLong, ObjectJJ_J, kIntrinsicUnsafeGetAndAddLong, 0), - INTRINSIC(SunMiscUnsafe, GetAndSetInt, ObjectJI_I, kIntrinsicUnsafeGetAndSetInt, 0), - INTRINSIC(SunMiscUnsafe, GetAndSetLong, ObjectJJ_J, kIntrinsicUnsafeGetAndSetLong, 0), - INTRINSIC(SunMiscUnsafe, GetAndSetObject, ObjectJObject_Object, kIntrinsicUnsafeGetAndSetObject, 0), - INTRINSIC(SunMiscUnsafe, LoadFence, _V, kIntrinsicUnsafeLoadFence, 0), - INTRINSIC(SunMiscUnsafe, StoreFence, _V, kIntrinsicUnsafeStoreFence, 0), - INTRINSIC(SunMiscUnsafe, FullFence, _V, kIntrinsicUnsafeFullFence, 0), - - INTRINSIC(JavaLangSystem, ArrayCopy, CharArrayICharArrayII_V , kIntrinsicSystemArrayCopyCharArray, - 0), - INTRINSIC(JavaLangSystem, ArrayCopy, ObjectIObjectII_V , kIntrinsicSystemArrayCopy, - 0), - - INTRINSIC(JavaLangInteger, RotateRight, II_I, kIntrinsicRotateRight, k32), - INTRINSIC(JavaLangLong, RotateRight, JI_J, kIntrinsicRotateRight, k64), - INTRINSIC(JavaLangInteger, RotateLeft, II_I, kIntrinsicRotateLeft, k32), - INTRINSIC(JavaLangLong, RotateLeft, JI_J, kIntrinsicRotateLeft, k64), - -#undef INTRINSIC -}; - -DexFileMethodInliner::DexFileMethodInliner() - : lock_("DexFileMethodInliner lock", kDexFileMethodInlinerLock), - dex_file_(nullptr) { - static_assert(kClassCacheFirst == 0, "kClassCacheFirst not 0"); - static_assert(arraysize(kClassCacheNames) == kClassCacheLast, - "bad arraysize for kClassCacheNames"); - static_assert(kNameCacheFirst == 0, "kNameCacheFirst not 0"); - static_assert(arraysize(kNameCacheNames) == kNameCacheLast, - "bad arraysize for kNameCacheNames"); - static_assert(kProtoCacheFirst == 0, "kProtoCacheFirst not 0"); - static_assert(arraysize(kProtoCacheDefs) == kProtoCacheLast, - "bad arraysize kProtoCacheNames"); -} - -DexFileMethodInliner::~DexFileMethodInliner() { -} - -bool DexFileMethodInliner::AnalyseMethodCode(verifier::MethodVerifier* verifier) { - InlineMethod method; - bool success = InlineMethodAnalyser::AnalyseMethodCode(verifier, &method); - return success && AddInlineMethod(verifier->GetMethodReference().dex_method_index, method); -} - -InlineMethodFlags DexFileMethodInliner::IsIntrinsicOrSpecial(uint32_t method_index) { - ReaderMutexLock mu(Thread::Current(), lock_); - auto it = inline_methods_.find(method_index); - if (it != inline_methods_.end()) { - DCHECK_NE(it->second.flags & (kInlineIntrinsic | kInlineSpecial), 0); - return it->second.flags; - } else { - return kNoInlineMethodFlags; - } -} - -bool DexFileMethodInliner::IsIntrinsic(uint32_t method_index, InlineMethod* intrinsic) { - ReaderMutexLock mu(Thread::Current(), lock_); - auto it = inline_methods_.find(method_index); - bool res = (it != inline_methods_.end() && (it->second.flags & kInlineIntrinsic) != 0); - if (res && intrinsic != nullptr) { - *intrinsic = it->second; - } - return res; -} - -bool DexFileMethodInliner::IsSpecial(uint32_t method_index) { - ReaderMutexLock mu(Thread::Current(), lock_); - auto it = inline_methods_.find(method_index); - return it != inline_methods_.end() && (it->second.flags & kInlineSpecial) != 0; -} - -uint32_t DexFileMethodInliner::FindClassIndex(const DexFile* dex_file, IndexCache* cache, - ClassCacheIndex index) { - uint32_t* class_index = &cache->class_indexes[index]; - if (*class_index != kIndexUnresolved) { - return *class_index; - } - - const DexFile::TypeId* type_id = dex_file->FindTypeId(kClassCacheNames[index]); - if (type_id == nullptr) { - *class_index = kIndexNotFound; - return *class_index; - } - *class_index = dex_file->GetIndexForTypeId(*type_id); - return *class_index; -} - -uint32_t DexFileMethodInliner::FindNameIndex(const DexFile* dex_file, IndexCache* cache, - NameCacheIndex index) { - uint32_t* name_index = &cache->name_indexes[index]; - if (*name_index != kIndexUnresolved) { - return *name_index; - } - - const DexFile::StringId* string_id = dex_file->FindStringId(kNameCacheNames[index]); - if (string_id == nullptr) { - *name_index = kIndexNotFound; - return *name_index; - } - *name_index = dex_file->GetIndexForStringId(*string_id); - return *name_index; -} - -uint32_t DexFileMethodInliner::FindProtoIndex(const DexFile* dex_file, IndexCache* cache, - ProtoCacheIndex index) { - uint32_t* proto_index = &cache->proto_indexes[index]; - if (*proto_index != kIndexUnresolved) { - return *proto_index; - } - - const ProtoDef& proto_def = kProtoCacheDefs[index]; - uint32_t return_index = FindClassIndex(dex_file, cache, proto_def.return_type); - if (return_index == kIndexNotFound) { - *proto_index = kIndexNotFound; - return *proto_index; - } - uint16_t return_type = static_cast<uint16_t>(return_index); - DCHECK_EQ(static_cast<uint32_t>(return_type), return_index); - - uint32_t signature_length = proto_def.param_count; - uint16_t signature_type_idxs[kProtoMaxParams]; - for (uint32_t i = 0; i != signature_length; ++i) { - uint32_t param_index = FindClassIndex(dex_file, cache, proto_def.params[i]); - if (param_index == kIndexNotFound) { - *proto_index = kIndexNotFound; - return *proto_index; - } - signature_type_idxs[i] = static_cast<uint16_t>(param_index); - DCHECK_EQ(static_cast<uint32_t>(signature_type_idxs[i]), param_index); - } - - const DexFile::ProtoId* proto_id = dex_file->FindProtoId(return_type, signature_type_idxs, - signature_length); - if (proto_id == nullptr) { - *proto_index = kIndexNotFound; - return *proto_index; - } - *proto_index = dex_file->GetIndexForProtoId(*proto_id); - return *proto_index; -} - -uint32_t DexFileMethodInliner::FindMethodIndex(const DexFile* dex_file, IndexCache* cache, - const MethodDef& method_def) { - uint32_t declaring_class_index = FindClassIndex(dex_file, cache, method_def.declaring_class); - if (declaring_class_index == kIndexNotFound) { - return kIndexNotFound; - } - uint32_t name_index = FindNameIndex(dex_file, cache, method_def.name); - if (name_index == kIndexNotFound) { - return kIndexNotFound; - } - uint32_t proto_index = FindProtoIndex(dex_file, cache, method_def.proto); - if (proto_index == kIndexNotFound) { - return kIndexNotFound; - } - const DexFile::MethodId* method_id = - dex_file->FindMethodId(dex_file->GetTypeId(declaring_class_index), - dex_file->GetStringId(name_index), - dex_file->GetProtoId(proto_index)); - if (method_id == nullptr) { - return kIndexNotFound; - } - return dex_file->GetIndexForMethodId(*method_id); -} - -DexFileMethodInliner::IndexCache::IndexCache() { - std::fill_n(class_indexes, arraysize(class_indexes), kIndexUnresolved); - std::fill_n(name_indexes, arraysize(name_indexes), kIndexUnresolved); - std::fill_n(proto_indexes, arraysize(proto_indexes), kIndexUnresolved); -} - -void DexFileMethodInliner::FindIntrinsics(const DexFile* dex_file) { - DCHECK(dex_file != nullptr); - DCHECK(dex_file_ == nullptr); - IndexCache cache; - for (const IntrinsicDef& def : kIntrinsicMethods) { - uint32_t method_idx = FindMethodIndex(dex_file, &cache, def.method_def); - if (method_idx != kIndexNotFound) { - DCHECK(inline_methods_.find(method_idx) == inline_methods_.end()); - inline_methods_.Put(method_idx, def.intrinsic); - } - } - dex_file_ = dex_file; -} - -bool DexFileMethodInliner::AddInlineMethod(int32_t method_idx, const InlineMethod& method) { - WriterMutexLock mu(Thread::Current(), lock_); - if (LIKELY(inline_methods_.find(method_idx) == inline_methods_.end())) { - inline_methods_.Put(method_idx, method); - return true; - } else { - if (PrettyMethod(method_idx, *dex_file_) == "int java.lang.String.length()") { - // TODO: String.length is both kIntrinsicIsEmptyOrLength and kInlineOpIGet. - } else { - LOG(WARNING) << "Inliner: " << PrettyMethod(method_idx, *dex_file_) << " already inline"; - } - return false; - } -} - -} // namespace art diff --git a/compiler/dex/quick/dex_file_method_inliner.h b/compiler/dex/quick/dex_file_method_inliner.h deleted file mode 100644 index f4ae5a548e..0000000000 --- a/compiler/dex/quick/dex_file_method_inliner.h +++ /dev/null @@ -1,395 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_COMPILER_DEX_QUICK_DEX_FILE_METHOD_INLINER_H_ -#define ART_COMPILER_DEX_QUICK_DEX_FILE_METHOD_INLINER_H_ - -#include <stdint.h> - -#include "base/enums.h" -#include "base/mutex.h" -#include "base/macros.h" -#include "safe_map.h" -#include "dex_file.h" -#include "quick/inline_method_analyser.h" - -namespace art { - -namespace verifier { -class MethodVerifier; -} // namespace verifier - -enum OpSize { - k32, - k64, - kSignedHalf, - kSignedByte, -}; - -/** - * Handles inlining of methods from a particular DexFile. - * - * Intrinsics are a special case of inline methods. The DexFile indices for - * all the supported intrinsic methods are looked up once by the FindIntrinsics - * function and cached by this class for quick lookup by the method index. - * - * TODO: Detect short methods (at least getters, setters and empty functions) - * from the verifier and mark them for inlining. Inline these methods early - * during compilation to allow further optimizations. Similarly, provide - * additional information about intrinsics to the early phases of compilation. - */ -class DexFileMethodInliner { - public: - DexFileMethodInliner(); - ~DexFileMethodInliner(); - - /** - * Analyse method code to determine if the method is a candidate for inlining. - * If it is, record its data for later. - * - * @param verifier the method verifier holding data about the method to analyse. - * @return true if the method is a candidate for inlining, false otherwise. - */ - bool AnalyseMethodCode(verifier::MethodVerifier* verifier) - REQUIRES_SHARED(Locks::mutator_lock_) REQUIRES(!lock_); - - /** - * Check whether a particular method index corresponds to an intrinsic or special function. - */ - InlineMethodFlags IsIntrinsicOrSpecial(uint32_t method_index) REQUIRES(!lock_); - - /** - * Check whether a particular method index corresponds to an intrinsic function. - */ - bool IsIntrinsic(uint32_t method_index, InlineMethod* intrinsic) REQUIRES(!lock_); - - /** - * Check whether a particular method index corresponds to a special function. - */ - bool IsSpecial(uint32_t method_index) REQUIRES(!lock_); - - /** - * To avoid multiple lookups of a class by its descriptor, we cache its - * type index in the IndexCache. These are the indexes into the IndexCache - * class_indexes array. - */ - enum ClassCacheIndex : uint8_t { // unit8_t to save space, make larger if needed - kClassCacheFirst = 0, - kClassCacheBoolean = kClassCacheFirst, - kClassCacheByte, - kClassCacheChar, - kClassCacheShort, - kClassCacheInt, - kClassCacheLong, - kClassCacheFloat, - kClassCacheDouble, - kClassCacheVoid, - kClassCacheJavaLangByteArray, - kClassCacheJavaLangCharArray, - kClassCacheJavaLangIntArray, - kClassCacheJavaLangObject, - kClassCacheJavaLangRefReference, - kClassCacheJavaLangString, - kClassCacheJavaLangStringBuffer, - kClassCacheJavaLangStringBuilder, - kClassCacheJavaLangStringFactory, - kClassCacheJavaLangDouble, - kClassCacheJavaLangFloat, - kClassCacheJavaLangInteger, - kClassCacheJavaLangLong, - kClassCacheJavaLangShort, - kClassCacheJavaLangMath, - kClassCacheJavaLangStrictMath, - kClassCacheJavaLangThread, - kClassCacheJavaNioCharsetCharset, - kClassCacheLibcoreIoMemory, - kClassCacheSunMiscUnsafe, - kClassCacheJavaLangSystem, - kClassCacheLast - }; - - /** - * To avoid multiple lookups of a method name string, we cache its string - * index in the IndexCache. These are the indexes into the IndexCache - * name_indexes array. - */ - enum NameCacheIndex : uint8_t { // unit8_t to save space, make larger if needed - kNameCacheFirst = 0, - kNameCacheReverse = kNameCacheFirst, - kNameCacheReverseBytes, - kNameCacheDoubleToRawLongBits, - kNameCacheLongBitsToDouble, - kNameCacheFloatToRawIntBits, - kNameCacheIntBitsToFloat, - kNameCacheAbs, - kNameCacheMax, - kNameCacheMin, - kNameCacheCos, - kNameCacheSin, - kNameCacheAcos, - kNameCacheAsin, - kNameCacheAtan, - kNameCacheAtan2, - kNameCacheCbrt, - kNameCacheCosh, - kNameCacheExp, - kNameCacheExpm1, - kNameCacheHypot, - kNameCacheLog, - kNameCacheLog10, - kNameCacheNextAfter, - kNameCacheSinh, - kNameCacheTan, - kNameCacheTanh, - kNameCacheSqrt, - kNameCacheCeil, - kNameCacheFloor, - kNameCacheRint, - kNameCacheRound, - kNameCacheReferenceGetReferent, - kNameCacheCharAt, - kNameCacheCompareTo, - kNameCacheEquals, - kNameCacheGetCharsNoCheck, - kNameCacheIsEmpty, - kNameCacheFloatToIntBits, - kNameCacheDoubleToLongBits, - kNameCacheIsInfinite, - kNameCacheIsNaN, - kNameCacheIndexOf, - kNameCacheLength, - kNameCacheInit, - kNameCacheNewStringFromBytes, - kNameCacheNewStringFromChars, - kNameCacheNewStringFromString, - kNameCacheCurrentThread, - kNameCachePeekByte, - kNameCachePeekIntNative, - kNameCachePeekLongNative, - kNameCachePeekShortNative, - kNameCachePokeByte, - kNameCachePokeIntNative, - kNameCachePokeLongNative, - kNameCachePokeShortNative, - kNameCacheCompareAndSwapInt, - kNameCacheCompareAndSwapLong, - kNameCacheCompareAndSwapObject, - kNameCacheGetInt, - kNameCacheGetIntVolatile, - kNameCachePutInt, - kNameCachePutIntVolatile, - kNameCachePutOrderedInt, - kNameCacheGetLong, - kNameCacheGetLongVolatile, - kNameCachePutLong, - kNameCachePutLongVolatile, - kNameCachePutOrderedLong, - kNameCacheGetObject, - kNameCacheGetObjectVolatile, - kNameCachePutObject, - kNameCachePutObjectVolatile, - kNameCachePutOrderedObject, - kNameCacheGetAndAddInt, - kNameCacheGetAndAddLong, - kNameCacheGetAndSetInt, - kNameCacheGetAndSetLong, - kNameCacheGetAndSetObject, - kNameCacheLoadFence, - kNameCacheStoreFence, - kNameCacheFullFence, - kNameCacheArrayCopy, - kNameCacheBitCount, - kNameCacheCompare, - kNameCacheHighestOneBit, - kNameCacheLowestOneBit, - kNameCacheNumberOfLeadingZeros, - kNameCacheNumberOfTrailingZeros, - kNameCacheRotateRight, - kNameCacheRotateLeft, - kNameCacheSignum, - kNameCacheLast - }; - - /** - * To avoid multiple lookups of a method signature, we cache its proto - * index in the IndexCache. These are the indexes into the IndexCache - * proto_indexes array. - */ - enum ProtoCacheIndex : uint8_t { // unit8_t to save space, make larger if needed - kProtoCacheFirst = 0, - kProtoCacheI_I = kProtoCacheFirst, - kProtoCacheJ_J, - kProtoCacheS_S, - kProtoCacheD_D, - kProtoCacheDD_D, - kProtoCacheF_F, - kProtoCacheFF_F, - kProtoCacheD_J, - kProtoCacheD_Z, - kProtoCacheJ_D, - kProtoCacheF_I, - kProtoCacheF_Z, - kProtoCacheI_F, - kProtoCacheII_I, - kProtoCacheI_C, - kProtoCacheString_I, - kProtoCache_Z, - kProtoCache_I, - kProtoCache_Object, - kProtoCache_Thread, - kProtoCacheJ_B, - kProtoCacheJ_I, - kProtoCacheJ_S, - kProtoCacheJB_V, - kProtoCacheJI_V, - kProtoCacheJJ_J, - kProtoCacheJJ_I, - kProtoCacheJJ_V, - kProtoCacheJS_V, - kProtoCacheObject_Z, - kProtoCacheJI_J, - kProtoCacheObjectJII_Z, - kProtoCacheObjectJJJ_Z, - kProtoCacheObjectJObjectObject_Z, - kProtoCacheObjectJ_I, - kProtoCacheObjectJI_I, - kProtoCacheObjectJI_V, - kProtoCacheObjectJ_J, - kProtoCacheObjectJJ_J, - kProtoCacheObjectJJ_V, - kProtoCacheObjectJ_Object, - kProtoCacheObjectJObject_V, - kProtoCacheObjectJObject_Object, - kProtoCacheCharArrayICharArrayII_V, - kProtoCacheObjectIObjectII_V, - kProtoCacheIICharArrayI_V, - kProtoCacheByteArrayIII_String, - kProtoCacheIICharArray_String, - kProtoCacheString_String, - kProtoCache_V, - kProtoCacheByteArray_V, - kProtoCacheByteArrayI_V, - kProtoCacheByteArrayII_V, - kProtoCacheByteArrayIII_V, - kProtoCacheByteArrayIIString_V, - kProtoCacheByteArrayString_V, - kProtoCacheByteArrayIICharset_V, - kProtoCacheByteArrayCharset_V, - kProtoCacheCharArray_V, - kProtoCacheCharArrayII_V, - kProtoCacheIICharArray_V, - kProtoCacheIntArrayII_V, - kProtoCacheString_V, - kProtoCacheStringBuffer_V, - kProtoCacheStringBuilder_V, - kProtoCacheLast - }; - - private: - /** - * The maximum number of method parameters we support in the ProtoDef. - */ - static constexpr uint32_t kProtoMaxParams = 6; - - /** - * The method signature (proto) definition using cached class indexes. - * The return_type and params are used with the IndexCache to look up - * appropriate class indexes to be passed to DexFile::FindProtoId(). - */ - struct ProtoDef { - ClassCacheIndex return_type; - uint8_t param_count; - ClassCacheIndex params[kProtoMaxParams]; - }; - - /** - * The method definition using cached class, name and proto indexes. - * The class index, method name index and proto index are used with - * IndexCache to look up appropriate parameters for DexFile::FindMethodId(). - */ - struct MethodDef { - ClassCacheIndex declaring_class; - NameCacheIndex name; - ProtoCacheIndex proto; - }; - - /** - * The definition of an intrinsic function binds the method definition - * to an Intrinsic. - */ - struct IntrinsicDef { - MethodDef method_def; - InlineMethod intrinsic; - }; - - /** - * Cache for class, method name and method signature indexes used during - * intrinsic function lookup to avoid multiple lookups of the same items. - * - * Many classes have multiple intrinsics and/or they are used in multiple - * method signatures and we want to avoid repeated lookups since they are - * not exactly cheap. The method names and method signatures are sometimes - * reused and therefore cached as well. - */ - struct IndexCache { - IndexCache(); - - uint32_t class_indexes[kClassCacheLast - kClassCacheFirst]; - uint32_t name_indexes[kNameCacheLast - kNameCacheFirst]; - uint32_t proto_indexes[kProtoCacheLast - kProtoCacheFirst]; - }; - - static const char* const kClassCacheNames[]; - static const char* const kNameCacheNames[]; - static const ProtoDef kProtoCacheDefs[]; - static const IntrinsicDef kIntrinsicMethods[]; - - static const uint32_t kIndexNotFound = static_cast<uint32_t>(-1); - static const uint32_t kIndexUnresolved = static_cast<uint32_t>(-2); - - static uint32_t FindClassIndex(const DexFile* dex_file, IndexCache* cache, - ClassCacheIndex index); - static uint32_t FindNameIndex(const DexFile* dex_file, IndexCache* cache, - NameCacheIndex index); - static uint32_t FindProtoIndex(const DexFile* dex_file, IndexCache* cache, - ProtoCacheIndex index); - static uint32_t FindMethodIndex(const DexFile* dex_file, IndexCache* cache, - const MethodDef& method_def); - - /** - * Find all known intrinsic methods in the dex_file and cache their indices. - * - * Only DexFileToMethodInlinerMap may call this function to initialize the inliner. - */ - void FindIntrinsics(const DexFile* dex_file) REQUIRES(lock_); - - friend class DexFileToMethodInlinerMap; - - bool AddInlineMethod(int32_t method_idx, const InlineMethod& method) REQUIRES(!lock_); - - ReaderWriterMutex lock_; - /* - * Maps method indexes (for the particular DexFile) to Intrinsic defintions. - */ - SafeMap<uint32_t, InlineMethod> inline_methods_ GUARDED_BY(lock_); - const DexFile* dex_file_; - - DISALLOW_COPY_AND_ASSIGN(DexFileMethodInliner); -}; - -} // namespace art - -#endif // ART_COMPILER_DEX_QUICK_DEX_FILE_METHOD_INLINER_H_ diff --git a/compiler/dex/quick/dex_file_to_method_inliner_map.cc b/compiler/dex/quick/dex_file_to_method_inliner_map.cc deleted file mode 100644 index 2fec183289..0000000000 --- a/compiler/dex/quick/dex_file_to_method_inliner_map.cc +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include <algorithm> -#include <utility> -#include "thread.h" -#include "thread-inl.h" -#include "base/mutex.h" -#include "base/mutex-inl.h" -#include "base/logging.h" -#include "driver/compiler_driver.h" - -#include "dex_file_to_method_inliner_map.h" - -namespace art { - -DexFileToMethodInlinerMap::DexFileToMethodInlinerMap() - : lock_("DexFileToMethodInlinerMap lock", kDexFileToMethodInlinerMapLock) { -} - -DexFileToMethodInlinerMap::~DexFileToMethodInlinerMap() { - for (auto& entry : inliners_) { - delete entry.second; - } -} - -DexFileMethodInliner* DexFileToMethodInlinerMap::GetMethodInliner(const DexFile* dex_file) { - Thread* self = Thread::Current(); - { - ReaderMutexLock mu(self, lock_); - auto it = inliners_.find(dex_file); - if (it != inliners_.end()) { - return it->second; - } - } - - // We need to acquire our lock_ to modify inliners_ but we want to release it - // before we initialize the new inliner. However, we need to acquire the - // new inliner's lock_ before we release our lock_ to prevent another thread - // from using the uninitialized inliner. This requires explicit calls to - // ExclusiveLock()/ExclusiveUnlock() on one of the locks, the other one - // can use WriterMutexLock. - DexFileMethodInliner* locked_inliner; - { - WriterMutexLock mu(self, lock_); - DexFileMethodInliner** inliner = &inliners_[dex_file]; // inserts new entry if not found - if (*inliner) { - return *inliner; - } - *inliner = new DexFileMethodInliner; - DCHECK(*inliner != nullptr); - locked_inliner = *inliner; - locked_inliner->lock_.ExclusiveLock(self); // Acquire inliner's lock_ before releasing lock_. - } - locked_inliner->FindIntrinsics(dex_file); - locked_inliner->lock_.ExclusiveUnlock(self); - return locked_inliner; -} - -} // namespace art diff --git a/compiler/dex/quick/dex_file_to_method_inliner_map.h b/compiler/dex/quick/dex_file_to_method_inliner_map.h deleted file mode 100644 index 215dc12b26..0000000000 --- a/compiler/dex/quick/dex_file_to_method_inliner_map.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2013 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_COMPILER_DEX_QUICK_DEX_FILE_TO_METHOD_INLINER_MAP_H_ -#define ART_COMPILER_DEX_QUICK_DEX_FILE_TO_METHOD_INLINER_MAP_H_ - -#include <map> -#include <vector> -#include "base/macros.h" -#include "base/mutex.h" - -#include "dex/quick/dex_file_method_inliner.h" - -namespace art { - -class CompilerDriver; -class DexFile; - -/** - * Map each DexFile to its DexFileMethodInliner. - * - * The method inliner is created and initialized the first time it's requested - * for a particular DexFile. - */ -class DexFileToMethodInlinerMap { - public: - DexFileToMethodInlinerMap(); - ~DexFileToMethodInlinerMap(); - - DexFileMethodInliner* GetMethodInliner(const DexFile* dex_file) NO_THREAD_SAFETY_ANALYSIS; - // TODO: There is an irregular non-scoped use of locks that defeats annotalysis with -O0. - // Fix the NO_THREAD_SAFETY_ANALYSIS when this works and add the appropriate LOCKS_EXCLUDED. - - private: - ReaderWriterMutex lock_; - std::map<const DexFile*, DexFileMethodInliner*> inliners_ GUARDED_BY(lock_); - - DISALLOW_COPY_AND_ASSIGN(DexFileToMethodInlinerMap); -}; - -} // namespace art - -#endif // ART_COMPILER_DEX_QUICK_DEX_FILE_TO_METHOD_INLINER_MAP_H_ diff --git a/compiler/dex/quick_compiler_callbacks.cc b/compiler/dex/quick_compiler_callbacks.cc index 2532bda632..932eb51aee 100644 --- a/compiler/dex/quick_compiler_callbacks.cc +++ b/compiler/dex/quick_compiler_callbacks.cc @@ -16,7 +16,6 @@ #include "quick_compiler_callbacks.h" -#include "quick/dex_file_to_method_inliner_map.h" #include "verifier/method_verifier-inl.h" #include "verification_results.h" @@ -24,8 +23,6 @@ namespace art { void QuickCompilerCallbacks::MethodVerified(verifier::MethodVerifier* verifier) { verification_results_->ProcessVerifiedMethod(verifier); - MethodReference ref = verifier->GetMethodReference(); - method_inliner_map_->GetMethodInliner(ref.dex_file)->AnalyseMethodCode(verifier); } void QuickCompilerCallbacks::ClassRejected(ClassReference ref) { diff --git a/compiler/dex/quick_compiler_callbacks.h b/compiler/dex/quick_compiler_callbacks.h index 824194c7bd..34fd88b498 100644 --- a/compiler/dex/quick_compiler_callbacks.h +++ b/compiler/dex/quick_compiler_callbacks.h @@ -22,19 +22,15 @@ namespace art { class VerificationResults; -class DexFileToMethodInlinerMap; class QuickCompilerCallbacks FINAL : public CompilerCallbacks { public: QuickCompilerCallbacks(VerificationResults* verification_results, - DexFileToMethodInlinerMap* method_inliner_map, CompilerCallbacks::CallbackMode mode) : CompilerCallbacks(mode), verification_results_(verification_results), - method_inliner_map_(method_inliner_map), verifier_deps_(nullptr) { CHECK(verification_results != nullptr); - CHECK(method_inliner_map != nullptr); } ~QuickCompilerCallbacks() { } @@ -59,7 +55,6 @@ class QuickCompilerCallbacks FINAL : public CompilerCallbacks { private: VerificationResults* const verification_results_; - DexFileToMethodInlinerMap* const method_inliner_map_; verifier::VerifierDeps* verifier_deps_; }; diff --git a/compiler/driver/compiled_method_storage_test.cc b/compiler/driver/compiled_method_storage_test.cc index 6863f42d11..5063d716d5 100644 --- a/compiler/driver/compiled_method_storage_test.cc +++ b/compiler/driver/compiled_method_storage_test.cc @@ -21,17 +21,14 @@ #include "compiler_driver.h" #include "compiler_options.h" #include "dex/verification_results.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" namespace art { TEST(CompiledMethodStorage, Deduplicate) { CompilerOptions compiler_options; VerificationResults verification_results(&compiler_options); - DexFileToMethodInlinerMap method_inliner_map; CompilerDriver driver(&compiler_options, &verification_results, - &method_inliner_map, Compiler::kOptimizing, /* instruction_set_ */ kNone, /* instruction_set_features */ nullptr, diff --git a/compiler/driver/compiler_driver.cc b/compiler/driver/compiler_driver.cc index 4f764209f2..2ec3f164e3 100644 --- a/compiler/driver/compiler_driver.cc +++ b/compiler/driver/compiler_driver.cc @@ -44,9 +44,8 @@ #include "dex/dex_to_dex_compiler.h" #include "dex/verification_results.h" #include "dex/verified_method.h" -#include "dex/quick/dex_file_method_inliner.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "driver/compiler_options.h" +#include "intrinsics_enum.h" #include "jni_internal.h" #include "object_lock.h" #include "runtime.h" @@ -353,7 +352,6 @@ class CompilerDriver::DexFileMethodSet { CompilerDriver::CompilerDriver( const CompilerOptions* compiler_options, VerificationResults* verification_results, - DexFileToMethodInlinerMap* method_inliner_map, Compiler::Kind compiler_kind, InstructionSet instruction_set, const InstructionSetFeatures* instruction_set_features, @@ -370,7 +368,6 @@ CompilerDriver::CompilerDriver( const ProfileCompilationInfo* profile_compilation_info) : compiler_options_(compiler_options), verification_results_(verification_results), - method_inliner_map_(method_inliner_map), compiler_(Compiler::Create(this, compiler_kind)), compiler_kind_(compiler_kind), instruction_set_(instruction_set == kArm ? kThumb2: instruction_set), @@ -401,7 +398,6 @@ CompilerDriver::CompilerDriver( dex_to_dex_references_(), current_dex_to_dex_methods_(nullptr) { DCHECK(compiler_options_ != nullptr); - DCHECK(method_inliner_map_ != nullptr); compiler_->Init(); @@ -463,6 +459,29 @@ std::unique_ptr<const std::vector<uint8_t>> CompilerDriver::CreateQuickToInterpr } #undef CREATE_TRAMPOLINE +static void SetupIntrinsic(Thread* self, + Intrinsics intrinsic, + InvokeType invoke_type, + const char* class_name, + const char* method_name, + const char* signature) + REQUIRES_SHARED(Locks::mutator_lock_) { + ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + PointerSize image_size = class_linker->GetImagePointerSize(); + mirror::Class* cls = class_linker->FindSystemClass(self, class_name); + if (cls == nullptr) { + LOG(FATAL) << "Could not find class of intrinsic " << class_name; + } + ArtMethod* method = (invoke_type == kStatic || invoke_type == kDirect) + ? cls->FindDeclaredDirectMethod(method_name, signature, image_size) + : cls->FindDeclaredVirtualMethod(method_name, signature, image_size); + if (method == nullptr) { + LOG(FATAL) << "Could not find method of intrinsic " << class_name << method_name << signature; + } + DCHECK_EQ(method->GetInvokeType(), invoke_type); + method->SetIntrinsic(static_cast<uint32_t>(intrinsic)); +} + void CompilerDriver::CompileAll(jobject class_loader, const std::vector<const DexFile*>& dex_files, TimingLogger* timings) { @@ -477,6 +496,17 @@ void CompilerDriver::CompileAll(jobject class_loader, // 3) Attempt to verify all classes // 4) Attempt to initialize image classes, and trivially initialized classes PreCompile(class_loader, dex_files, timings); + if (IsBootImage()) { + // We don't need to setup the intrinsics for non boot image compilation, as + // those compilations will pick up a boot image that have the ArtMethod already + // set with the intrinsics flag. + ScopedObjectAccess soa(Thread::Current()); +#define OPTIMIZING_INTRINSICS(Name, InvokeType, NeedsEnvironmentOrCache, SideEffects, Exceptions, ClassName, MethodName, Signature) \ + SetupIntrinsic(soa.Self(), Intrinsics::k##Name, InvokeType, ClassName, MethodName, Signature); +#include "intrinsics_list.h" +INTRINSICS_LIST(OPTIMIZING_INTRINSICS) +#undef INTRINSICS_LIST + } // Compile: // 1) Compile all classes and methods enabled for compilation. May fall back to dex-to-dex // compilation. diff --git a/compiler/driver/compiler_driver.h b/compiler/driver/compiler_driver.h index 41f0d36c79..52a04cc46b 100644 --- a/compiler/driver/compiler_driver.h +++ b/compiler/driver/compiler_driver.h @@ -57,7 +57,6 @@ class CompiledClass; class CompiledMethod; class CompilerOptions; class DexCompilationUnit; -class DexFileToMethodInlinerMap; struct InlineIGetIPutData; class InstructionSetFeatures; class ParallelCompilationManager; @@ -88,7 +87,6 @@ class CompilerDriver { // classes. CompilerDriver(const CompilerOptions* compiler_options, VerificationResults* verification_results, - DexFileToMethodInlinerMap* method_inliner_map, Compiler::Kind compiler_kind, InstructionSet instruction_set, const InstructionSetFeatures* instruction_set_features, @@ -133,10 +131,6 @@ class CompilerDriver { return verification_results_; } - DexFileToMethodInlinerMap* GetMethodInlinerMap() const { - return method_inliner_map_; - } - InstructionSet GetInstructionSet() const { return instruction_set_; } @@ -603,7 +597,6 @@ class CompilerDriver { const CompilerOptions* const compiler_options_; VerificationResults* const verification_results_; - DexFileToMethodInlinerMap* const method_inliner_map_; std::unique_ptr<Compiler> compiler_; Compiler::Kind compiler_kind_; diff --git a/compiler/intrinsics_enum.h b/compiler/intrinsics_enum.h new file mode 100644 index 0000000000..55281812e4 --- /dev/null +++ b/compiler/intrinsics_enum.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_COMPILER_INTRINSICS_ENUM_H_ +#define ART_COMPILER_INTRINSICS_ENUM_H_ + +namespace art { + +enum class Intrinsics { +#define OPTIMIZING_INTRINSICS(Name, ...) \ + k ## Name, +#include "intrinsics_list.h" + kNone, + INTRINSICS_LIST(OPTIMIZING_INTRINSICS) +#undef INTRINSICS_LIST +#undef OPTIMIZING_INTRINSICS +}; +std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic); + +} // namespace art + +#endif // ART_COMPILER_INTRINSICS_ENUM_H_ diff --git a/compiler/intrinsics_list.h b/compiler/intrinsics_list.h new file mode 100644 index 0000000000..5877f57b74 --- /dev/null +++ b/compiler/intrinsics_list.h @@ -0,0 +1,147 @@ +/* + * Copyright (C, "", "", "") 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License", "", "", ""); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef ART_COMPILER_INTRINSICS_LIST_H_ +#define ART_COMPILER_INTRINSICS_LIST_H_ + +// All intrinsics supported by ART. Format is name, then whether it is expected +// to be a HInvokeStaticOrDirect node (compared to HInvokeVirtual), then whether it requires an +// environment, may have side effects, or may throw exceptions. + +// Note: adding a new intrinsic requires an art image version change, +// as the modifiers flag for some ArtMethods will need to be changed. + +#define INTRINSICS_LIST(V) \ + V(DoubleDoubleToRawLongBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Double;", "doubleToRawLongBits", "(D)J") \ + V(DoubleDoubleToLongBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Double;", "doubleToLongBits", "(D)J") \ + V(DoubleIsInfinite, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Double;", "isInfinite", "(D)Z") \ + V(DoubleIsNaN, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Double;", "isNaN", "(D)Z") \ + V(DoubleLongBitsToDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Double;", "longBitsToDouble", "(J)D") \ + V(FloatFloatToRawIntBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Float;", "floatToRawIntBits", "(F)I") \ + V(FloatFloatToIntBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Float;", "floatToIntBits", "(F)I") \ + V(FloatIsInfinite, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Float;", "isInfinite", "(F)Z") \ + V(FloatIsNaN, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Float;", "isNaN", "(F)Z") \ + V(FloatIntBitsToFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Float;", "intBitsToFloat", "(I)F") \ + V(IntegerReverse, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "reverse", "(I)I") \ + V(IntegerReverseBytes, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "reverseBytes", "(I)I") \ + V(IntegerBitCount, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "bitCount", "(I)I") \ + V(IntegerCompare, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "compare", "(II)I") \ + V(IntegerHighestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "highestOneBit", "(I)I") \ + V(IntegerLowestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "lowestOneBit", "(I)I") \ + V(IntegerNumberOfLeadingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "numberOfLeadingZeros", "(I)I") \ + V(IntegerNumberOfTrailingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "numberOfTrailingZeros", "(I)I") \ + V(IntegerRotateRight, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "rotateRight", "(II)I") \ + V(IntegerRotateLeft, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "rotateLeft", "(II)I") \ + V(IntegerSignum, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Integer;", "signum", "(I)I") \ + V(LongReverse, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "reverse", "(J)J") \ + V(LongReverseBytes, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "reverseBytes", "(J)J") \ + V(LongBitCount, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "bitCount", "(J)I") \ + V(LongCompare, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "compare", "(JJ)I") \ + V(LongHighestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "highestOneBit", "(J)J") \ + V(LongLowestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "lowestOneBit", "(J)J") \ + V(LongNumberOfLeadingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "numberOfLeadingZeros", "(J)I") \ + V(LongNumberOfTrailingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "numberOfTrailingZeros", "(J)I") \ + V(LongRotateRight, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "rotateRight", "(JI)J") \ + V(LongRotateLeft, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "rotateLeft", "(JI)J") \ + V(LongSignum, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Long;", "signum", "(J)I") \ + V(ShortReverseBytes, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Short;", "reverseBytes", "(S)S") \ + V(MathAbsDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "abs", "(D)D") \ + V(MathAbsFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "abs", "(F)F") \ + V(MathAbsLong, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "abs", "(J)J") \ + V(MathAbsInt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "abs", "(I)I") \ + V(MathMinDoubleDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "min", "(DD)D") \ + V(MathMinFloatFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "min", "(FF)F") \ + V(MathMinLongLong, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "min", "(JJ)J") \ + V(MathMinIntInt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "min", "(II)I") \ + V(MathMaxDoubleDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "max", "(DD)D") \ + V(MathMaxFloatFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "max", "(FF)F") \ + V(MathMaxLongLong, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "max", "(JJ)J") \ + V(MathMaxIntInt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "max", "(II)I") \ + V(MathCos, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "cos", "(D)D") \ + V(MathSin, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "sin", "(D)D") \ + V(MathAcos, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "acos", "(D)D") \ + V(MathAsin, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "asin", "(D)D") \ + V(MathAtan, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "atan", "(D)D") \ + V(MathAtan2, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "atan2", "(DD)D") \ + V(MathCbrt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "cbrt", "(D)D") \ + V(MathCosh, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "cosh", "(D)D") \ + V(MathExp, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "exp", "(D)D") \ + V(MathExpm1, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "expm1", "(D)D") \ + V(MathHypot, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "hypot", "(DD)D") \ + V(MathLog, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "log", "(D)D") \ + V(MathLog10, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "log10", "(D)D") \ + V(MathNextAfter, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "nextAfter", "(DD)D") \ + V(MathSinh, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "sinh", "(D)D") \ + V(MathTan, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "tan", "(D)D") \ + V(MathTanh, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "tanh", "(D)D") \ + V(MathSqrt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "sqrt", "(D)D") \ + V(MathCeil, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "ceil", "(D)D") \ + V(MathFloor, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "floor", "(D)D") \ + V(MathRint, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "rint", "(D)D") \ + V(MathRoundDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "round", "(D)J") \ + V(MathRoundFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Math;", "round", "(F)I") \ + V(SystemArrayCopyChar, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Ljava/lang/System;", "arraycopy", "([CI[CII)V") \ + V(SystemArrayCopy, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Ljava/lang/System;", "arraycopy", "(Ljava/lang/Object;ILjava/lang/Object;II)V") \ + V(ThreadCurrentThread, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow, "Ljava/lang/Thread;", "currentThread", "()Ljava/lang/Thread;") \ + V(MemoryPeekByte, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Llibcore/io/Memory;", "peekByte", "(J)B") \ + V(MemoryPeekIntNative, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Llibcore/io/Memory;", "peekIntNative", "(J)I") \ + V(MemoryPeekLongNative, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Llibcore/io/Memory;", "peekLongNative", "(J)J") \ + V(MemoryPeekShortNative, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Llibcore/io/Memory;", "peekShortNative", "(J)S") \ + V(MemoryPokeByte, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow, "Llibcore/io/Memory;", "pokeByte", "(JB)V") \ + V(MemoryPokeIntNative, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow, "Llibcore/io/Memory;", "pokeIntNative", "(JI)V") \ + V(MemoryPokeLongNative, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow, "Llibcore/io/Memory;", "pokeLongNative", "(JJ)V") \ + V(MemoryPokeShortNative, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow, "Llibcore/io/Memory;", "pokeShortNative", "(JS)V") \ + V(StringCharAt, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Ljava/lang/String;", "charAt", "(I)C") \ + V(StringCompareTo, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Ljava/lang/String;", "compareTo", "(Ljava/lang/String;)I") \ + V(StringEquals, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Ljava/lang/String;", "equals", "(Ljava/lang/Object;)Z") \ + V(StringGetCharsNoCheck, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Ljava/lang/String;", "getCharsNoCheck", "(II[CI)V") \ + V(StringIndexOf, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Ljava/lang/String;", "indexOf", "(I)I") \ + V(StringIndexOfAfter, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow, "Ljava/lang/String;", "indexOf", "(II)I") \ + V(StringIsEmpty, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kNoThrow, "Ljava/lang/String;", "isEmpty", "()Z") \ + V(StringLength, kVirtual, kNeedsEnvironmentOrCache, kReadSideEffects, kNoThrow, "Ljava/lang/String;", "length", "()I") \ + V(StringNewStringFromBytes, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Ljava/lang/StringFactory;", "newStringFromBytes", "([BIII)Ljava/lang/String;") \ + V(StringNewStringFromChars, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Ljava/lang/StringFactory;", "newStringFromChars", "(II[C)Ljava/lang/String;") \ + V(StringNewStringFromString, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Ljava/lang/StringFactory;", "newStringFromString", "(Ljava/lang/String;)Ljava/lang/String;") \ + V(UnsafeCASInt, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "compareAndSwapInt", "(Ljava/lang/Object;JII)Z") \ + V(UnsafeCASLong, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "compareAndSwapLong", "(Ljava/lang/Object;JJJ)Z") \ + V(UnsafeCASObject, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "compareAndSwapObject", "(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z") \ + V(UnsafeGet, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getInt", "(Ljava/lang/Object;J)I") \ + V(UnsafeGetVolatile, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getIntVolatile", "(Ljava/lang/Object;J)I") \ + V(UnsafeGetObject, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getObject", "(Ljava/lang/Object;J)Ljava/lang/Object;") \ + V(UnsafeGetObjectVolatile, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getObjectVolatile", "(Ljava/lang/Object;J)Ljava/lang/Object;") \ + V(UnsafeGetLong, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getLong", "(Ljava/lang/Object;J)J") \ + V(UnsafeGetLongVolatile, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getLongVolatile", "(Ljava/lang/Object;J)J") \ + V(UnsafePut, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putInt", "(Ljava/lang/Object;JI)V") \ + V(UnsafePutOrdered, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putOrderedInt", "(Ljava/lang/Object;JI)V") \ + V(UnsafePutVolatile, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putIntVolatile", "(Ljava/lang/Object;JI)V") \ + V(UnsafePutObject, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putObject", "(Ljava/lang/Object;JLjava/lang/Object;)V") \ + V(UnsafePutObjectOrdered, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putOrderedObject", "(Ljava/lang/Object;JLjava/lang/Object;)V") \ + V(UnsafePutObjectVolatile, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putObjectVolatile", "(Ljava/lang/Object;JLjava/lang/Object;)V") \ + V(UnsafePutLong, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putLong", "(Ljava/lang/Object;JJ)V") \ + V(UnsafePutLongOrdered, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putOrderedLong", "(Ljava/lang/Object;JJ)V") \ + V(UnsafePutLongVolatile, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "putLongVolatile", "(Ljava/lang/Object;JJ)V") \ + V(UnsafeGetAndAddInt, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getAndAddInt", "(Ljava/lang/Object;JI)I") \ + V(UnsafeGetAndAddLong, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getAndAddLong", "(Ljava/lang/Object;JJ)J") \ + V(UnsafeGetAndSetInt, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getAndSetInt", "(Ljava/lang/Object;JI)I") \ + V(UnsafeGetAndSetLong, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getAndSetLong", "(Ljava/lang/Object;JJ)J") \ + V(UnsafeGetAndSetObject, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "getAndSetObject", "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;") \ + V(UnsafeLoadFence, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "loadFence", "()V") \ + V(UnsafeStoreFence, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "storeFence", "()V") \ + V(UnsafeFullFence, kVirtual, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Lsun/misc/Unsafe;", "fullFence", "()V") \ + V(ReferenceGetReferent, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow, "Ljava/lang/ref/Reference;", "getReferent", "()Ljava/lang/Object;") + +#endif // ART_COMPILER_INTRINSICS_LIST_H_ +#undef ART_COMPILER_INTRINSICS_LIST_H_ // #define is only for lint. diff --git a/compiler/jit/jit_compiler.cc b/compiler/jit/jit_compiler.cc index 7246acebd2..4f8690530b 100644 --- a/compiler/jit/jit_compiler.cc +++ b/compiler/jit/jit_compiler.cc @@ -150,11 +150,9 @@ JitCompiler::JitCompiler() { instruction_set_features_.reset(InstructionSetFeatures::FromCppDefines()); } cumulative_logger_.reset(new CumulativeLogger("jit times")); - method_inliner_map_.reset(new DexFileToMethodInlinerMap); compiler_driver_.reset(new CompilerDriver( compiler_options_.get(), /* verification_results */ nullptr, - method_inliner_map_.get(), Compiler::kOptimizing, instruction_set, instruction_set_features_.get(), diff --git a/compiler/jit/jit_compiler.h b/compiler/jit/jit_compiler.h index 18e3155040..ea2747c085 100644 --- a/compiler/jit/jit_compiler.h +++ b/compiler/jit/jit_compiler.h @@ -19,7 +19,6 @@ #include "base/mutex.h" #include "compiled_method.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "driver/compiler_driver.h" #include "driver/compiler_options.h" @@ -49,7 +48,6 @@ class JitCompiler { private: std::unique_ptr<CompilerOptions> compiler_options_; std::unique_ptr<CumulativeLogger> cumulative_logger_; - std::unique_ptr<DexFileToMethodInlinerMap> method_inliner_map_; std::unique_ptr<CompilerDriver> compiler_driver_; std::unique_ptr<const InstructionSetFeatures> instruction_set_features_; std::unique_ptr<File> perf_file_; diff --git a/compiler/linker/relative_patcher_test.h b/compiler/linker/relative_patcher_test.h index 304b31ca84..62b3a0a167 100644 --- a/compiler/linker/relative_patcher_test.h +++ b/compiler/linker/relative_patcher_test.h @@ -22,7 +22,6 @@ #include "base/array_ref.h" #include "base/macros.h" #include "compiled_method.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "dex/verification_results.h" #include "driver/compiler_driver.h" #include "driver/compiler_options.h" @@ -43,10 +42,8 @@ class RelativePatcherTest : public testing::Test { RelativePatcherTest(InstructionSet instruction_set, const std::string& variant) : compiler_options_(), verification_results_(&compiler_options_), - inliner_map_(), driver_(&compiler_options_, &verification_results_, - &inliner_map_, Compiler::kQuick, instruction_set, /* instruction_set_features*/ nullptr, @@ -269,7 +266,6 @@ class RelativePatcherTest : public testing::Test { CompilerOptions compiler_options_; VerificationResults verification_results_; - DexFileToMethodInlinerMap inliner_map_; CompilerDriver driver_; // Needed for constructing CompiledMethod. std::string error_msg_; InstructionSet instruction_set_; diff --git a/compiler/oat_test.cc b/compiler/oat_test.cc index c392dc504d..e8bc67d967 100644 --- a/compiler/oat_test.cc +++ b/compiler/oat_test.cc @@ -23,7 +23,6 @@ #include "compiled_method.h" #include "compiler.h" #include "debug/method_debug_info.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "dex/quick_compiler_callbacks.h" #include "dex/verification_results.h" #include "driver/compiler_driver.h" @@ -100,15 +99,12 @@ class OatTest : public CommonCompilerTest { compiler_options_->ParseCompilerOption(option, Usage); } verification_results_.reset(new VerificationResults(compiler_options_.get())); - method_inliner_map_.reset(new DexFileToMethodInlinerMap); callbacks_.reset(new QuickCompilerCallbacks(verification_results_.get(), - method_inliner_map_.get(), CompilerCallbacks::CallbackMode::kCompileApp)); Runtime::Current()->SetCompilerCallbacks(callbacks_.get()); timer_.reset(new CumulativeLogger("Compilation times")); compiler_driver_.reset(new CompilerDriver(compiler_options_.get(), verification_results_.get(), - method_inliner_map_.get(), compiler_kind, insn_set, insn_features_.get(), diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc index 31d1704a8a..af2fe9cb1f 100644 --- a/compiler/optimizing/inliner.cc +++ b/compiler/optimizing/inliner.cc @@ -1321,7 +1321,7 @@ size_t HInliner::RunOptimizations(HGraph* callee_graph, HConstantFolding fold(callee_graph); HSharpening sharpening(callee_graph, codegen_, dex_compilation_unit, compiler_driver_); InstructionSimplifier simplify(callee_graph, stats_); - IntrinsicsRecognizer intrinsics(callee_graph, compiler_driver_, stats_); + IntrinsicsRecognizer intrinsics(callee_graph, stats_); HOptimization* optimizations[] = { &intrinsics, diff --git a/compiler/optimizing/intrinsics.cc b/compiler/optimizing/intrinsics.cc index 2131279e79..412ccfcf4f 100644 --- a/compiler/optimizing/intrinsics.cc +++ b/compiler/optimizing/intrinsics.cc @@ -18,13 +18,10 @@ #include "art_method.h" #include "class_linker.h" -#include "dex/quick/dex_file_method_inliner.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "driver/compiler_driver.h" #include "invoke_type.h" #include "mirror/dex_cache-inl.h" #include "nodes.h" -#include "quick/inline_method_analyser.h" #include "scoped_thread_state_change-inl.h" #include "thread-inl.h" #include "utils.h" @@ -36,7 +33,7 @@ static inline InvokeType GetIntrinsicInvokeType(Intrinsics i) { switch (i) { case Intrinsics::kNone: return kInterface; // Non-sensical for intrinsic. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ case Intrinsics::k ## Name: \ return IsStatic; #include "intrinsics_list.h" @@ -52,7 +49,7 @@ static inline IntrinsicNeedsEnvironmentOrCache NeedsEnvironmentOrCache(Intrinsic switch (i) { case Intrinsics::kNone: return kNeedsEnvironmentOrCache; // Non-sensical for intrinsic. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ case Intrinsics::k ## Name: \ return NeedsEnvironmentOrCache; #include "intrinsics_list.h" @@ -68,7 +65,7 @@ static inline IntrinsicSideEffects GetSideEffects(Intrinsics i) { switch (i) { case Intrinsics::kNone: return kAllSideEffects; -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ case Intrinsics::k ## Name: \ return SideEffects; #include "intrinsics_list.h" @@ -84,7 +81,7 @@ static inline IntrinsicExceptions GetExceptions(Intrinsics i) { switch (i) { case Intrinsics::kNone: return kCanThrow; -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ case Intrinsics::k ## Name: \ return Exceptions; #include "intrinsics_list.h" @@ -95,430 +92,7 @@ INTRINSICS_LIST(OPTIMIZING_INTRINSICS) return kCanThrow; } -static Primitive::Type GetType(uint64_t data, bool is_op_size) { - if (is_op_size) { - switch (static_cast<OpSize>(data)) { - case kSignedByte: - return Primitive::kPrimByte; - case kSignedHalf: - return Primitive::kPrimShort; - case k32: - return Primitive::kPrimInt; - case k64: - return Primitive::kPrimLong; - default: - LOG(FATAL) << "Unknown/unsupported op size " << data; - UNREACHABLE(); - } - } else { - if ((data & kIntrinsicFlagIsLong) != 0) { - return Primitive::kPrimLong; - } - if ((data & kIntrinsicFlagIsObject) != 0) { - return Primitive::kPrimNot; - } - return Primitive::kPrimInt; - } -} - -static Intrinsics GetIntrinsic(InlineMethod method) { - switch (method.opcode) { - // Floating-point conversions. - case kIntrinsicDoubleCvt: - return ((method.d.data & kIntrinsicFlagToFloatingPoint) == 0) ? - Intrinsics::kDoubleDoubleToRawLongBits : Intrinsics::kDoubleLongBitsToDouble; - case kIntrinsicFloatCvt: - return ((method.d.data & kIntrinsicFlagToFloatingPoint) == 0) ? - Intrinsics::kFloatFloatToRawIntBits : Intrinsics::kFloatIntBitsToFloat; - case kIntrinsicFloat2Int: - return Intrinsics::kFloatFloatToIntBits; - case kIntrinsicDouble2Long: - return Intrinsics::kDoubleDoubleToLongBits; - - // Floating-point tests. - case kIntrinsicFloatIsInfinite: - return Intrinsics::kFloatIsInfinite; - case kIntrinsicDoubleIsInfinite: - return Intrinsics::kDoubleIsInfinite; - case kIntrinsicFloatIsNaN: - return Intrinsics::kFloatIsNaN; - case kIntrinsicDoubleIsNaN: - return Intrinsics::kDoubleIsNaN; - - // Bit manipulations. - case kIntrinsicReverseBits: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerReverse; - case Primitive::kPrimLong: - return Intrinsics::kLongReverse; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicReverseBytes: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimShort: - return Intrinsics::kShortReverseBytes; - case Primitive::kPrimInt: - return Intrinsics::kIntegerReverseBytes; - case Primitive::kPrimLong: - return Intrinsics::kLongReverseBytes; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicRotateRight: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerRotateRight; - case Primitive::kPrimLong: - return Intrinsics::kLongRotateRight; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicRotateLeft: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerRotateLeft; - case Primitive::kPrimLong: - return Intrinsics::kLongRotateLeft; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - - // Misc data processing. - case kIntrinsicBitCount: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerBitCount; - case Primitive::kPrimLong: - return Intrinsics::kLongBitCount; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicCompare: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerCompare; - case Primitive::kPrimLong: - return Intrinsics::kLongCompare; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicHighestOneBit: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerHighestOneBit; - case Primitive::kPrimLong: - return Intrinsics::kLongHighestOneBit; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicLowestOneBit: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerLowestOneBit; - case Primitive::kPrimLong: - return Intrinsics::kLongLowestOneBit; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicNumberOfLeadingZeros: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerNumberOfLeadingZeros; - case Primitive::kPrimLong: - return Intrinsics::kLongNumberOfLeadingZeros; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicNumberOfTrailingZeros: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerNumberOfTrailingZeros; - case Primitive::kPrimLong: - return Intrinsics::kLongNumberOfTrailingZeros; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicSignum: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimInt: - return Intrinsics::kIntegerSignum; - case Primitive::kPrimLong: - return Intrinsics::kLongSignum; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - - // Abs. - case kIntrinsicAbsDouble: - return Intrinsics::kMathAbsDouble; - case kIntrinsicAbsFloat: - return Intrinsics::kMathAbsFloat; - case kIntrinsicAbsInt: - return Intrinsics::kMathAbsInt; - case kIntrinsicAbsLong: - return Intrinsics::kMathAbsLong; - - // Min/max. - case kIntrinsicMinMaxDouble: - return ((method.d.data & kIntrinsicFlagMin) == 0) ? - Intrinsics::kMathMaxDoubleDouble : Intrinsics::kMathMinDoubleDouble; - case kIntrinsicMinMaxFloat: - return ((method.d.data & kIntrinsicFlagMin) == 0) ? - Intrinsics::kMathMaxFloatFloat : Intrinsics::kMathMinFloatFloat; - case kIntrinsicMinMaxInt: - return ((method.d.data & kIntrinsicFlagMin) == 0) ? - Intrinsics::kMathMaxIntInt : Intrinsics::kMathMinIntInt; - case kIntrinsicMinMaxLong: - return ((method.d.data & kIntrinsicFlagMin) == 0) ? - Intrinsics::kMathMaxLongLong : Intrinsics::kMathMinLongLong; - - // More math builtins. - case kIntrinsicCos: - return Intrinsics::kMathCos; - case kIntrinsicSin: - return Intrinsics::kMathSin; - case kIntrinsicAcos: - return Intrinsics::kMathAcos; - case kIntrinsicAsin: - return Intrinsics::kMathAsin; - case kIntrinsicAtan: - return Intrinsics::kMathAtan; - case kIntrinsicAtan2: - return Intrinsics::kMathAtan2; - case kIntrinsicCbrt: - return Intrinsics::kMathCbrt; - case kIntrinsicCosh: - return Intrinsics::kMathCosh; - case kIntrinsicExp: - return Intrinsics::kMathExp; - case kIntrinsicExpm1: - return Intrinsics::kMathExpm1; - case kIntrinsicHypot: - return Intrinsics::kMathHypot; - case kIntrinsicLog: - return Intrinsics::kMathLog; - case kIntrinsicLog10: - return Intrinsics::kMathLog10; - case kIntrinsicNextAfter: - return Intrinsics::kMathNextAfter; - case kIntrinsicSinh: - return Intrinsics::kMathSinh; - case kIntrinsicTan: - return Intrinsics::kMathTan; - case kIntrinsicTanh: - return Intrinsics::kMathTanh; - - // Misc math. - case kIntrinsicSqrt: - return Intrinsics::kMathSqrt; - case kIntrinsicCeil: - return Intrinsics::kMathCeil; - case kIntrinsicFloor: - return Intrinsics::kMathFloor; - case kIntrinsicRint: - return Intrinsics::kMathRint; - case kIntrinsicRoundDouble: - return Intrinsics::kMathRoundDouble; - case kIntrinsicRoundFloat: - return Intrinsics::kMathRoundFloat; - - // System.arraycopy. - case kIntrinsicSystemArrayCopyCharArray: - return Intrinsics::kSystemArrayCopyChar; - - case kIntrinsicSystemArrayCopy: - return Intrinsics::kSystemArrayCopy; - - // Thread.currentThread. - case kIntrinsicCurrentThread: - return Intrinsics::kThreadCurrentThread; - - // Memory.peek. - case kIntrinsicPeek: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimByte: - return Intrinsics::kMemoryPeekByte; - case Primitive::kPrimShort: - return Intrinsics::kMemoryPeekShortNative; - case Primitive::kPrimInt: - return Intrinsics::kMemoryPeekIntNative; - case Primitive::kPrimLong: - return Intrinsics::kMemoryPeekLongNative; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - - // Memory.poke. - case kIntrinsicPoke: - switch (GetType(method.d.data, true)) { - case Primitive::kPrimByte: - return Intrinsics::kMemoryPokeByte; - case Primitive::kPrimShort: - return Intrinsics::kMemoryPokeShortNative; - case Primitive::kPrimInt: - return Intrinsics::kMemoryPokeIntNative; - case Primitive::kPrimLong: - return Intrinsics::kMemoryPokeLongNative; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - - // String. - case kIntrinsicCharAt: - return Intrinsics::kStringCharAt; - case kIntrinsicCompareTo: - return Intrinsics::kStringCompareTo; - case kIntrinsicEquals: - return Intrinsics::kStringEquals; - case kIntrinsicGetCharsNoCheck: - return Intrinsics::kStringGetCharsNoCheck; - case kIntrinsicIsEmptyOrLength: - return ((method.d.data & kIntrinsicFlagIsEmpty) == 0) ? - Intrinsics::kStringLength : Intrinsics::kStringIsEmpty; - case kIntrinsicIndexOf: - return ((method.d.data & kIntrinsicFlagBase0) == 0) ? - Intrinsics::kStringIndexOfAfter : Intrinsics::kStringIndexOf; - case kIntrinsicNewStringFromBytes: - return Intrinsics::kStringNewStringFromBytes; - case kIntrinsicNewStringFromChars: - return Intrinsics::kStringNewStringFromChars; - case kIntrinsicNewStringFromString: - return Intrinsics::kStringNewStringFromString; - - case kIntrinsicCas: - switch (GetType(method.d.data, false)) { - case Primitive::kPrimNot: - return Intrinsics::kUnsafeCASObject; - case Primitive::kPrimInt: - return Intrinsics::kUnsafeCASInt; - case Primitive::kPrimLong: - return Intrinsics::kUnsafeCASLong; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - case kIntrinsicUnsafeGet: { - const bool is_volatile = (method.d.data & kIntrinsicFlagIsVolatile); - switch (GetType(method.d.data, false)) { - case Primitive::kPrimInt: - return is_volatile ? Intrinsics::kUnsafeGetVolatile : Intrinsics::kUnsafeGet; - case Primitive::kPrimLong: - return is_volatile ? Intrinsics::kUnsafeGetLongVolatile : Intrinsics::kUnsafeGetLong; - case Primitive::kPrimNot: - return is_volatile ? Intrinsics::kUnsafeGetObjectVolatile : Intrinsics::kUnsafeGetObject; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - } - case kIntrinsicUnsafePut: { - enum Sync { kNoSync, kVolatile, kOrdered }; - const Sync sync = - ((method.d.data & kIntrinsicFlagIsVolatile) != 0) ? kVolatile : - ((method.d.data & kIntrinsicFlagIsOrdered) != 0) ? kOrdered : - kNoSync; - switch (GetType(method.d.data, false)) { - case Primitive::kPrimInt: - switch (sync) { - case kNoSync: - return Intrinsics::kUnsafePut; - case kVolatile: - return Intrinsics::kUnsafePutVolatile; - case kOrdered: - return Intrinsics::kUnsafePutOrdered; - } - break; - case Primitive::kPrimLong: - switch (sync) { - case kNoSync: - return Intrinsics::kUnsafePutLong; - case kVolatile: - return Intrinsics::kUnsafePutLongVolatile; - case kOrdered: - return Intrinsics::kUnsafePutLongOrdered; - } - break; - case Primitive::kPrimNot: - switch (sync) { - case kNoSync: - return Intrinsics::kUnsafePutObject; - case kVolatile: - return Intrinsics::kUnsafePutObjectVolatile; - case kOrdered: - return Intrinsics::kUnsafePutObjectOrdered; - } - break; - default: - LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; - UNREACHABLE(); - } - break; - } - - // 1.8. - case kIntrinsicUnsafeGetAndAddInt: - return Intrinsics::kUnsafeGetAndAddInt; - case kIntrinsicUnsafeGetAndAddLong: - return Intrinsics::kUnsafeGetAndAddLong; - case kIntrinsicUnsafeGetAndSetInt: - return Intrinsics::kUnsafeGetAndSetInt; - case kIntrinsicUnsafeGetAndSetLong: - return Intrinsics::kUnsafeGetAndSetLong; - case kIntrinsicUnsafeGetAndSetObject: - return Intrinsics::kUnsafeGetAndSetObject; - case kIntrinsicUnsafeLoadFence: - return Intrinsics::kUnsafeLoadFence; - case kIntrinsicUnsafeStoreFence: - return Intrinsics::kUnsafeStoreFence; - case kIntrinsicUnsafeFullFence: - return Intrinsics::kUnsafeFullFence; - - // Virtual cases. - - case kIntrinsicReferenceGetReferent: - return Intrinsics::kReferenceGetReferent; - - // Quick inliner cases. Remove after refactoring. They are here so that we can use the - // compiler to warn on missing cases. - - case kInlineOpNop: - case kInlineOpReturnArg: - case kInlineOpNonWideConst: - case kInlineOpIGet: - case kInlineOpIPut: - case kInlineOpConstructor: - return Intrinsics::kNone; - - // String init cases, not intrinsics. - - case kInlineStringInit: - return Intrinsics::kNone; - - // No default case to make the compiler warn on missing cases. - } - return Intrinsics::kNone; -} - -static bool CheckInvokeType(Intrinsics intrinsic, HInvoke* invoke, const DexFile& dex_file) { - // The DexFileMethodInliner should have checked whether the methods are agreeing with - // what we expect, i.e., static methods are called as such. Add another check here for - // our expectations: - // +static bool CheckInvokeType(Intrinsics intrinsic, HInvoke* invoke) { // Whenever the intrinsic is marked as static, report an error if we find an InvokeVirtual. // // Whenever the intrinsic is marked as direct and we find an InvokeVirtual, a devirtualization @@ -542,13 +116,9 @@ static bool CheckInvokeType(Intrinsics intrinsic, HInvoke* invoke, const DexFile return true; } if (invoke_type == kVirtual) { - ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); + ArtMethod* art_method = invoke->GetResolvedMethod(); ScopedObjectAccess soa(Thread::Current()); - ArtMethod* art_method = - class_linker->FindDexCache(soa.Self(), dex_file)->GetResolvedMethod( - invoke->GetDexMethodIndex(), class_linker->GetImagePointerSize()); - return art_method != nullptr && - (art_method->IsFinal() || art_method->GetDeclaringClass()->IsFinal()); + return (art_method->IsFinal() || art_method->GetDeclaringClass()->IsFinal()); } return false; @@ -561,8 +131,8 @@ static bool CheckInvokeType(Intrinsics intrinsic, HInvoke* invoke, const DexFile } } -// TODO: Refactor DexFileMethodInliner and have something nicer than InlineMethod. void IntrinsicsRecognizer::Run() { + ScopedObjectAccess soa(Thread::Current()); for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) { HBasicBlock* block = it.Current(); for (HInstructionIterator inst_it(block->GetInstructions()); !inst_it.Done(); @@ -570,26 +140,20 @@ void IntrinsicsRecognizer::Run() { HInstruction* inst = inst_it.Current(); if (inst->IsInvoke()) { HInvoke* invoke = inst->AsInvoke(); - InlineMethod method; - const DexFile& dex_file = invoke->GetDexFile(); - DexFileMethodInliner* inliner = driver_->GetMethodInlinerMap()->GetMethodInliner(&dex_file); - DCHECK(inliner != nullptr); - if (inliner->IsIntrinsic(invoke->GetDexMethodIndex(), &method)) { - Intrinsics intrinsic = GetIntrinsic(method); - - if (intrinsic != Intrinsics::kNone) { - if (!CheckInvokeType(intrinsic, invoke, dex_file)) { - LOG(WARNING) << "Found an intrinsic with unexpected invoke type: " - << intrinsic << " for " - << PrettyMethod(invoke->GetDexMethodIndex(), invoke->GetDexFile()) - << invoke->DebugName(); - } else { - invoke->SetIntrinsic(intrinsic, - NeedsEnvironmentOrCache(intrinsic), - GetSideEffects(intrinsic), - GetExceptions(intrinsic)); - MaybeRecordStat(MethodCompilationStat::kIntrinsicRecognized); - } + ArtMethod* art_method = invoke->GetResolvedMethod(); + if (art_method != nullptr && art_method->IsIntrinsic()) { + Intrinsics intrinsic = static_cast<Intrinsics>(art_method->GetIntrinsic()); + if (!CheckInvokeType(intrinsic, invoke)) { + LOG(WARNING) << "Found an intrinsic with unexpected invoke type: " + << intrinsic << " for " + << PrettyMethod(invoke->GetDexMethodIndex(), invoke->GetDexFile()) + << invoke->DebugName(); + } else { + invoke->SetIntrinsic(intrinsic, + NeedsEnvironmentOrCache(intrinsic), + GetSideEffects(intrinsic), + GetExceptions(intrinsic)); + MaybeRecordStat(MethodCompilationStat::kIntrinsicRecognized); } } } @@ -602,7 +166,7 @@ std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic) { case Intrinsics::kNone: os << "None"; break; -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ case Intrinsics::k ## Name: \ os << # Name; \ break; diff --git a/compiler/optimizing/intrinsics.h b/compiler/optimizing/intrinsics.h index 62f731d03f..1e73cf67df 100644 --- a/compiler/optimizing/intrinsics.h +++ b/compiler/optimizing/intrinsics.h @@ -34,17 +34,14 @@ static constexpr uint64_t kPositiveInfinityDouble = UINT64_C(0x7ff0000000000000) // Recognize intrinsics from HInvoke nodes. class IntrinsicsRecognizer : public HOptimization { public: - IntrinsicsRecognizer(HGraph* graph, CompilerDriver* driver, OptimizingCompilerStats* stats) - : HOptimization(graph, kIntrinsicsRecognizerPassName, stats), - driver_(driver) {} + IntrinsicsRecognizer(HGraph* graph, OptimizingCompilerStats* stats) + : HOptimization(graph, kIntrinsicsRecognizerPassName, stats) {} void Run() OVERRIDE; static constexpr const char* kIntrinsicsRecognizerPassName = "intrinsics_recognition"; private: - CompilerDriver* driver_; - DISALLOW_COPY_AND_ASSIGN(IntrinsicsRecognizer); }; @@ -58,7 +55,7 @@ class IntrinsicVisitor : public ValueObject { switch (invoke->GetIntrinsic()) { case Intrinsics::kNone: return; -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, ...) \ case Intrinsics::k ## Name: \ Visit ## Name(invoke); \ return; @@ -73,7 +70,7 @@ INTRINSICS_LIST(OPTIMIZING_INTRINSICS) // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironment, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, ...) \ virtual void Visit ## Name(HInvoke* invoke ATTRIBUTE_UNUSED) { \ } #include "intrinsics_list.h" diff --git a/compiler/optimizing/intrinsics_arm.h b/compiler/optimizing/intrinsics_arm.h index c671700615..7f20ea4b1f 100644 --- a/compiler/optimizing/intrinsics_arm.h +++ b/compiler/optimizing/intrinsics_arm.h @@ -37,7 +37,7 @@ class IntrinsicLocationsBuilderARM FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) @@ -64,7 +64,7 @@ class IntrinsicCodeGeneratorARM FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) diff --git a/compiler/optimizing/intrinsics_arm64.h b/compiler/optimizing/intrinsics_arm64.h index 525153621b..28e41cb086 100644 --- a/compiler/optimizing/intrinsics_arm64.h +++ b/compiler/optimizing/intrinsics_arm64.h @@ -42,7 +42,7 @@ class IntrinsicLocationsBuilderARM64 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) @@ -66,7 +66,7 @@ class IntrinsicCodeGeneratorARM64 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) diff --git a/compiler/optimizing/intrinsics_list.h b/compiler/optimizing/intrinsics_list.h deleted file mode 100644 index db60238fb4..0000000000 --- a/compiler/optimizing/intrinsics_list.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2015 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ART_COMPILER_OPTIMIZING_INTRINSICS_LIST_H_ -#define ART_COMPILER_OPTIMIZING_INTRINSICS_LIST_H_ - -// All intrinsics supported by the optimizing compiler. Format is name, then whether it is expected -// to be a HInvokeStaticOrDirect node (compared to HInvokeVirtual), then whether it requires an -// environment, may have side effects, or may throw exceptions. - -#define INTRINSICS_LIST(V) \ - V(DoubleDoubleToRawLongBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(DoubleDoubleToLongBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(DoubleIsInfinite, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(DoubleIsNaN, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(DoubleLongBitsToDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(FloatFloatToRawIntBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(FloatFloatToIntBits, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(FloatIsInfinite, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(FloatIsNaN, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(FloatIntBitsToFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerReverse, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerReverseBytes, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerBitCount, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerCompare, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerHighestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerLowestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerNumberOfLeadingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerNumberOfTrailingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerRotateRight, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerRotateLeft, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(IntegerSignum, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongReverse, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongReverseBytes, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongBitCount, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongCompare, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongHighestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongLowestOneBit, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongNumberOfLeadingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongNumberOfTrailingZeros, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongRotateRight, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongRotateLeft, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(LongSignum, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(ShortReverseBytes, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAbsDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAbsFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAbsLong, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAbsInt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMinDoubleDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMinFloatFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMinLongLong, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMinIntInt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMaxDoubleDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMaxFloatFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMaxLongLong, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathMaxIntInt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathCos, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathSin, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAcos, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAsin, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAtan, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathAtan2, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathCbrt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathCosh, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathExp, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathExpm1, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathHypot, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathLog, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathLog10, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathNextAfter, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathSinh, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathTan, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathTanh, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathSqrt, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathCeil, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathFloor, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathRint, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathRoundDouble, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MathRoundFloat, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(SystemArrayCopyChar, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(SystemArrayCopy, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(ThreadCurrentThread, kStatic, kNeedsEnvironmentOrCache, kNoSideEffects, kNoThrow) \ - V(MemoryPeekByte, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(MemoryPeekIntNative, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(MemoryPeekLongNative, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(MemoryPeekShortNative, kStatic, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(MemoryPokeByte, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow) \ - V(MemoryPokeIntNative, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow) \ - V(MemoryPokeLongNative, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow) \ - V(MemoryPokeShortNative, kStatic, kNeedsEnvironmentOrCache, kWriteSideEffects, kCanThrow) \ - V(StringCharAt, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(StringCompareTo, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(StringEquals, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(StringGetCharsNoCheck, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(StringIndexOf, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(StringIndexOfAfter, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kCanThrow) \ - V(StringIsEmpty, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kNoThrow) \ - V(StringLength, kDirect, kNeedsEnvironmentOrCache, kReadSideEffects, kNoThrow) \ - V(StringNewStringFromBytes, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(StringNewStringFromChars, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(StringNewStringFromString, kStatic, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeCASInt, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeCASLong, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeCASObject, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGet, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetVolatile, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetObject, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetObjectVolatile, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetLong, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetLongVolatile, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePut, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutOrdered, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutVolatile, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutObject, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutObjectOrdered, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutObjectVolatile, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutLong, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutLongOrdered, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafePutLongVolatile, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetAndAddInt, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetAndAddLong, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetAndSetInt, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetAndSetLong, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeGetAndSetObject, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeLoadFence, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeStoreFence, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(UnsafeFullFence, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) \ - V(ReferenceGetReferent, kDirect, kNeedsEnvironmentOrCache, kAllSideEffects, kCanThrow) - -#endif // ART_COMPILER_OPTIMIZING_INTRINSICS_LIST_H_ -#undef ART_COMPILER_OPTIMIZING_INTRINSICS_LIST_H_ // #define is only for lint. diff --git a/compiler/optimizing/intrinsics_mips.h b/compiler/optimizing/intrinsics_mips.h index 575a7d0a23..e134cb882e 100644 --- a/compiler/optimizing/intrinsics_mips.h +++ b/compiler/optimizing/intrinsics_mips.h @@ -36,7 +36,7 @@ class IntrinsicLocationsBuilderMIPS FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) @@ -60,7 +60,7 @@ class IntrinsicCodeGeneratorMIPS FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) diff --git a/compiler/optimizing/intrinsics_mips64.h b/compiler/optimizing/intrinsics_mips64.h index 4137fbd1b6..5b95c26a21 100644 --- a/compiler/optimizing/intrinsics_mips64.h +++ b/compiler/optimizing/intrinsics_mips64.h @@ -36,7 +36,7 @@ class IntrinsicLocationsBuilderMIPS64 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) @@ -60,7 +60,7 @@ class IntrinsicCodeGeneratorMIPS64 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) diff --git a/compiler/optimizing/intrinsics_x86.h b/compiler/optimizing/intrinsics_x86.h index 08bd197400..3743cb1371 100644 --- a/compiler/optimizing/intrinsics_x86.h +++ b/compiler/optimizing/intrinsics_x86.h @@ -36,7 +36,7 @@ class IntrinsicLocationsBuilderX86 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) @@ -61,7 +61,7 @@ class IntrinsicCodeGeneratorX86 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) diff --git a/compiler/optimizing/intrinsics_x86_64.h b/compiler/optimizing/intrinsics_x86_64.h index 155ff6548b..97404aa568 100644 --- a/compiler/optimizing/intrinsics_x86_64.h +++ b/compiler/optimizing/intrinsics_x86_64.h @@ -36,7 +36,7 @@ class IntrinsicLocationsBuilderX86_64 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) @@ -61,7 +61,7 @@ class IntrinsicCodeGeneratorX86_64 FINAL : public IntrinsicVisitor { // Define visitor methods. -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ +#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions, ...) \ void Visit ## Name(HInvoke* invoke) OVERRIDE; #include "intrinsics_list.h" INTRINSICS_LIST(OPTIMIZING_INTRINSICS) diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h index 4dc4c20003..397abded27 100644 --- a/compiler/optimizing/nodes.h +++ b/compiler/optimizing/nodes.h @@ -32,6 +32,7 @@ #include "handle.h" #include "handle_scope.h" #include "invoke_type.h" +#include "intrinsics_enum.h" #include "locations.h" #include "method_reference.h" #include "mirror/class.h" @@ -3690,17 +3691,6 @@ class HNewInstance FINAL : public HExpression<2> { DISALLOW_COPY_AND_ASSIGN(HNewInstance); }; -enum class Intrinsics { -#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ - k ## Name, -#include "intrinsics_list.h" - kNone, - INTRINSICS_LIST(OPTIMIZING_INTRINSICS) -#undef INTRINSICS_LIST -#undef OPTIMIZING_INTRINSICS -}; -std::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic); - enum IntrinsicNeedsEnvironmentOrCache { kNoEnvironmentOrCache, // Intrinsic does not require an environment or dex cache. kNeedsEnvironmentOrCache // Intrinsic requires an environment or requires a dex cache. diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 84356e884e..d3a55dd365 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -56,7 +56,6 @@ #include "dead_code_elimination.h" #include "debug/elf_debug_writer.h" #include "debug/method_debug_info.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "dex/verification_results.h" #include "dex/verified_method.h" #include "driver/compiler_driver-inl.h" @@ -479,7 +478,7 @@ static HOptimization* BuildOptimization( } else if (opt_name == InstructionSimplifier::kInstructionSimplifierPassName) { return new (arena) InstructionSimplifier(graph, stats, pass_name.c_str()); } else if (opt_name == IntrinsicsRecognizer::kIntrinsicsRecognizerPassName) { - return new (arena) IntrinsicsRecognizer(graph, driver, stats); + return new (arena) IntrinsicsRecognizer(graph, stats); } else if (opt_name == LICM::kLoopInvariantCodeMotionPassName) { CHECK(most_recent_side_effects != nullptr); return new (arena) LICM(graph, *most_recent_side_effects, stats); @@ -743,7 +742,7 @@ void OptimizingCompiler::RunOptimizations(HGraph* graph, graph, stats, "instruction_simplifier$after_bce"); InstructionSimplifier* simplify3 = new (arena) InstructionSimplifier( graph, stats, "instruction_simplifier$before_codegen"); - IntrinsicsRecognizer* intrinsics = new (arena) IntrinsicsRecognizer(graph, driver, stats); + IntrinsicsRecognizer* intrinsics = new (arena) IntrinsicsRecognizer(graph, stats); HOptimization* optimizations1[] = { intrinsics, diff --git a/dex2oat/dex2oat.cc b/dex2oat/dex2oat.cc index b706420f73..5d44cc1b9f 100644 --- a/dex2oat/dex2oat.cc +++ b/dex2oat/dex2oat.cc @@ -49,7 +49,6 @@ #include "compiler_callbacks.h" #include "debug/elf_debug_writer.h" #include "debug/method_debug_info.h" -#include "dex/quick/dex_file_to_method_inliner_map.h" #include "dex/quick_compiler_callbacks.h" #include "dex/verification_results.h" #include "dex_file-inl.h" @@ -509,7 +508,6 @@ class Dex2Oat FINAL { image_patch_delta_(0), key_value_store_(nullptr), verification_results_(nullptr), - method_inliner_map_(), runtime_(nullptr), thread_count_(sysconf(_SC_NPROCESSORS_CONF)), start_ns_(NanoTime()), @@ -1372,7 +1370,6 @@ class Dex2Oat FINAL { verification_results_.reset(new VerificationResults(compiler_options_.get())); callbacks_.reset(new QuickCompilerCallbacks( verification_results_.get(), - &method_inliner_map_, IsBootImage() ? CompilerCallbacks::CallbackMode::kCompileBootImage : CompilerCallbacks::CallbackMode::kCompileApp)); @@ -1632,7 +1629,6 @@ class Dex2Oat FINAL { driver_.reset(new CompilerDriver(compiler_options_.get(), verification_results_.get(), - &method_inliner_map_, compiler_kind_, instruction_set_, instruction_set_features_.get(), @@ -2540,7 +2536,6 @@ class Dex2Oat FINAL { std::unique_ptr<VerificationResults> verification_results_; - DexFileToMethodInlinerMap method_inliner_map_; std::unique_ptr<QuickCompilerCallbacks> callbacks_; std::unique_ptr<Runtime> runtime_; diff --git a/runtime/art_method.h b/runtime/art_method.h index 3d2db690a7..7a8f479d19 100644 --- a/runtime/art_method.h +++ b/runtime/art_method.h @@ -137,7 +137,52 @@ class ArtMethod FINAL { return (GetAccessFlags() & kAccFinal) != 0; } + bool IsIntrinsic() { + return (GetAccessFlags() & kAccIntrinsic) != 0; + } + + void SetIntrinsic(uint32_t intrinsic) { + DCHECK(IsUint<8>(intrinsic)); + uint32_t new_value = (GetAccessFlags() & kAccFlagsNotUsedByIntrinsic) | + kAccIntrinsic | + (intrinsic << POPCOUNT(kAccFlagsNotUsedByIntrinsic)); + if (kIsDebugBuild) { + uint32_t java_flags = (GetAccessFlags() & kAccJavaFlagsMask); + bool is_constructor = IsConstructor(); + bool is_synchronized = IsSynchronized(); + bool skip_access_checks = SkipAccessChecks(); + bool is_fast_native = IsFastNative(); + bool is_copied = IsCopied(); + bool is_miranda = IsMiranda(); + bool is_default = IsDefault(); + bool is_default_conflict = IsDefaultConflicting(); + bool is_compilable = IsCompilable(); + bool must_count_locks = MustCountLocks(); + SetAccessFlags(new_value); + DCHECK_EQ(java_flags, (GetAccessFlags() & kAccJavaFlagsMask)); + DCHECK_EQ(is_constructor, IsConstructor()); + DCHECK_EQ(is_synchronized, IsSynchronized()); + DCHECK_EQ(skip_access_checks, SkipAccessChecks()); + DCHECK_EQ(is_fast_native, IsFastNative()); + DCHECK_EQ(is_copied, IsCopied()); + DCHECK_EQ(is_miranda, IsMiranda()); + DCHECK_EQ(is_default, IsDefault()); + DCHECK_EQ(is_default_conflict, IsDefaultConflicting()); + DCHECK_EQ(is_compilable, IsCompilable()); + DCHECK_EQ(must_count_locks, MustCountLocks()); + } else { + SetAccessFlags(new_value); + } + } + + uint32_t GetIntrinsic() { + DCHECK(IsIntrinsic()); + return (GetAccessFlags() >> POPCOUNT(kAccFlagsNotUsedByIntrinsic)) & kAccMaxIntrinsic; + } + bool IsCopied() { + static_assert((kAccCopied & kAccFlagsNotUsedByIntrinsic) == kAccCopied, + "kAccCopied conflicts with intrinsic modifier"); const bool copied = (GetAccessFlags() & kAccCopied) != 0; // (IsMiranda() || IsDefaultConflicting()) implies copied DCHECK(!(IsMiranda() || IsDefaultConflicting()) || copied) @@ -146,6 +191,8 @@ class ArtMethod FINAL { } bool IsMiranda() { + static_assert((kAccMiranda & kAccFlagsNotUsedByIntrinsic) == kAccMiranda, + "kAccMiranda conflicts with intrinsic modifier"); return (GetAccessFlags() & kAccMiranda) != 0; } @@ -156,6 +203,9 @@ class ArtMethod FINAL { } bool IsCompilable() { + if (IsIntrinsic()) { + return true; + } return (GetAccessFlags() & kAccCompileDontBother) == 0; } @@ -163,11 +213,16 @@ class ArtMethod FINAL { // multiple default methods. It cannot be invoked, throwing an IncompatibleClassChangeError if one // attempts to do so. bool IsDefaultConflicting() { + if (IsIntrinsic()) { + return false; + } return (GetAccessFlags() & kAccDefaultConflict) != 0u; } // This is set by the class linker. bool IsDefault() { + static_assert((kAccDefault & kAccFlagsNotUsedByIntrinsic) == kAccDefault, + "kAccDefault conflicts with intrinsic modifier"); return (GetAccessFlags() & kAccDefault) != 0; } @@ -204,6 +259,9 @@ class ArtMethod FINAL { // Should this method be run in the interpreter and count locks (e.g., failed structured- // locking verification)? bool MustCountLocks() { + if (IsIntrinsic()) { + return false; + } return (GetAccessFlags() & kAccMustCountLocks) != 0; } diff --git a/runtime/base/mutex.h b/runtime/base/mutex.h index 8af9fa5c46..91e31d8d0d 100644 --- a/runtime/base/mutex.h +++ b/runtime/base/mutex.h @@ -78,7 +78,6 @@ enum LockLevel { kAllocSpaceLock, kBumpPointerSpaceBlockLock, kArenaPoolLock, - kDexFileMethodInlinerLock, kDexFileToMethodInlinerMapLock, kInternTableLock, kOatFileSecondaryLookupLock, diff --git a/runtime/image.cc b/runtime/image.cc index 7e6790a551..299d5fd13f 100644 --- a/runtime/image.cc +++ b/runtime/image.cc @@ -25,7 +25,7 @@ namespace art { const uint8_t ImageHeader::kImageMagic[] = { 'a', 'r', 't', '\n' }; -const uint8_t ImageHeader::kImageVersion[] = { '0', '3', '0', '\0' }; +const uint8_t ImageHeader::kImageVersion[] = { '0', '3', '1', '\0' }; ImageHeader::ImageHeader(uint32_t image_begin, uint32_t image_size, diff --git a/runtime/modifiers.h b/runtime/modifiers.h index fd7a125bc3..dd32df69d7 100644 --- a/runtime/modifiers.h +++ b/runtime/modifiers.h @@ -67,6 +67,7 @@ static constexpr uint32_t kAccCompileDontBother = 0x01000000; // method (ru // Set by the verifier for a method that could not be verified to follow structured locking. static constexpr uint32_t kAccMustCountLocks = 0x02000000; // method (runtime) +static constexpr uint32_t kAccIntrinsic = 0x80000000; // method (runtime) // Special runtime-only flags. // Interface and all its super-interfaces with default methods have been recursively initialized. @@ -76,6 +77,9 @@ static constexpr uint32_t kAccHasDefaultMethod = 0x40000000; // class/ancestor overrides finalize() static constexpr uint32_t kAccClassIsFinalizable = 0x80000000; +static constexpr uint32_t kAccFlagsNotUsedByIntrinsic = 0x007FFFFF; +static constexpr uint32_t kAccMaxIntrinsic = 0xFF; + // Valid (meaningful) bits for a field. static constexpr uint32_t kAccValidFieldFlags = kAccPublic | kAccPrivate | kAccProtected | kAccStatic | kAccFinal | kAccVolatile | kAccTransient | kAccSynthetic | kAccEnum; |