171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe/* 271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * Copyright (C) 2015 The Android Open Source Project 371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * 471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * Licensed under the Apache License, Version 2.0 (the "License"); 571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * you may not use this file except in compliance with the License. 671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * You may obtain a copy of the License at 771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * 871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * http://www.apache.org/licenses/LICENSE-2.0 971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * 1071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * Unless required by applicable law or agreed to in writing, software 1171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * distributed under the License is distributed on an "AS IS" BASIS, 1271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * See the License for the specific language governing permissions and 1471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe * limitations under the License. 1571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe */ 1671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 1771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "intrinsics.h" 1871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 19bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe#include "art_method.h" 20bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe#include "class_linker.h" 2171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "dex/quick/dex_file_method_inliner.h" 2271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "dex/quick/dex_file_to_method_inliner_map.h" 2371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "driver/compiler_driver.h" 2471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "invoke_type.h" 25bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe#include "mirror/dex_cache-inl.h" 2671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "nodes.h" 2771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "quick/inline_method_analyser.h" 28bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe#include "scoped_thread_state_change.h" 29bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe#include "thread-inl.h" 3080afd02024d20e60b197d3adfbb43cc303cf29e0Vladimir Marko#include "utils.h" 3171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 3271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampenamespace art { 3371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 3471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe// Function that returns whether an intrinsic is static/direct or virtual. 3571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampestatic inline InvokeType GetIntrinsicInvokeType(Intrinsics i) { 3671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (i) { 3771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case Intrinsics::kNone: 3871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return kInterface; // Non-sensical for intrinsic. 395d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ 405d75afe333f57546786686d9bee16b52f1bbe971Aart Bik case Intrinsics::k ## Name: \ 4171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return IsStatic; 4271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "intrinsics_list.h" 4371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas GampeINTRINSICS_LIST(OPTIMIZING_INTRINSICS) 4471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#undef INTRINSICS_LIST 4571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#undef OPTIMIZING_INTRINSICS 4671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 4771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return kInterface; 4871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe} 4971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 5057b81ecbe74138992dd447251e94ed06cd5eb802agicsaki// Function that returns whether an intrinsic needs an environment or not. 5105f2056b4f11e0b2bac92b2655abe7030771f5dcAgi Csakistatic inline IntrinsicNeedsEnvironmentOrCache NeedsEnvironmentOrCache(Intrinsics i) { 5257b81ecbe74138992dd447251e94ed06cd5eb802agicsaki switch (i) { 5357b81ecbe74138992dd447251e94ed06cd5eb802agicsaki case Intrinsics::kNone: 5405f2056b4f11e0b2bac92b2655abe7030771f5dcAgi Csaki return kNeedsEnvironmentOrCache; // Non-sensical for intrinsic. 555d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ 565d75afe333f57546786686d9bee16b52f1bbe971Aart Bik case Intrinsics::k ## Name: \ 5705f2056b4f11e0b2bac92b2655abe7030771f5dcAgi Csaki return NeedsEnvironmentOrCache; 5857b81ecbe74138992dd447251e94ed06cd5eb802agicsaki#include "intrinsics_list.h" 5957b81ecbe74138992dd447251e94ed06cd5eb802agicsakiINTRINSICS_LIST(OPTIMIZING_INTRINSICS) 6057b81ecbe74138992dd447251e94ed06cd5eb802agicsaki#undef INTRINSICS_LIST 6157b81ecbe74138992dd447251e94ed06cd5eb802agicsaki#undef OPTIMIZING_INTRINSICS 6257b81ecbe74138992dd447251e94ed06cd5eb802agicsaki } 6305f2056b4f11e0b2bac92b2655abe7030771f5dcAgi Csaki return kNeedsEnvironmentOrCache; 6457b81ecbe74138992dd447251e94ed06cd5eb802agicsaki} 6571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 665d75afe333f57546786686d9bee16b52f1bbe971Aart Bik// Function that returns whether an intrinsic has side effects. 675d75afe333f57546786686d9bee16b52f1bbe971Aart Bikstatic inline IntrinsicSideEffects GetSideEffects(Intrinsics i) { 685d75afe333f57546786686d9bee16b52f1bbe971Aart Bik switch (i) { 695d75afe333f57546786686d9bee16b52f1bbe971Aart Bik case Intrinsics::kNone: 705d75afe333f57546786686d9bee16b52f1bbe971Aart Bik return kAllSideEffects; 715d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ 725d75afe333f57546786686d9bee16b52f1bbe971Aart Bik case Intrinsics::k ## Name: \ 735d75afe333f57546786686d9bee16b52f1bbe971Aart Bik return SideEffects; 745d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#include "intrinsics_list.h" 755d75afe333f57546786686d9bee16b52f1bbe971Aart BikINTRINSICS_LIST(OPTIMIZING_INTRINSICS) 765d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#undef INTRINSICS_LIST 775d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#undef OPTIMIZING_INTRINSICS 785d75afe333f57546786686d9bee16b52f1bbe971Aart Bik } 795d75afe333f57546786686d9bee16b52f1bbe971Aart Bik return kAllSideEffects; 805d75afe333f57546786686d9bee16b52f1bbe971Aart Bik} 815d75afe333f57546786686d9bee16b52f1bbe971Aart Bik 825d75afe333f57546786686d9bee16b52f1bbe971Aart Bik// Function that returns whether an intrinsic can throw exceptions. 835d75afe333f57546786686d9bee16b52f1bbe971Aart Bikstatic inline IntrinsicExceptions GetExceptions(Intrinsics i) { 845d75afe333f57546786686d9bee16b52f1bbe971Aart Bik switch (i) { 855d75afe333f57546786686d9bee16b52f1bbe971Aart Bik case Intrinsics::kNone: 865d75afe333f57546786686d9bee16b52f1bbe971Aart Bik return kCanThrow; 875d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ 885d75afe333f57546786686d9bee16b52f1bbe971Aart Bik case Intrinsics::k ## Name: \ 895d75afe333f57546786686d9bee16b52f1bbe971Aart Bik return Exceptions; 905d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#include "intrinsics_list.h" 915d75afe333f57546786686d9bee16b52f1bbe971Aart BikINTRINSICS_LIST(OPTIMIZING_INTRINSICS) 925d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#undef INTRINSICS_LIST 935d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#undef OPTIMIZING_INTRINSICS 945d75afe333f57546786686d9bee16b52f1bbe971Aart Bik } 955d75afe333f57546786686d9bee16b52f1bbe971Aart Bik return kCanThrow; 965d75afe333f57546786686d9bee16b52f1bbe971Aart Bik} 975d75afe333f57546786686d9bee16b52f1bbe971Aart Bik 9871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampestatic Primitive::Type GetType(uint64_t data, bool is_op_size) { 9971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe if (is_op_size) { 10071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (static_cast<OpSize>(data)) { 10171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kSignedByte: 102878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe return Primitive::kPrimByte; 10371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kSignedHalf: 104878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe return Primitive::kPrimShort; 10571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case k32: 106878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe return Primitive::kPrimInt; 10771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case k64: 108878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe return Primitive::kPrimLong; 10971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe default: 11071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe LOG(FATAL) << "Unknown/unsupported op size " << data; 11171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe UNREACHABLE(); 11271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 11371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } else { 11471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe if ((data & kIntrinsicFlagIsLong) != 0) { 115878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe return Primitive::kPrimLong; 11671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 11771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe if ((data & kIntrinsicFlagIsObject) != 0) { 118878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe return Primitive::kPrimNot; 11971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 120878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe return Primitive::kPrimInt; 12171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 12271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe} 12371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 12416ba2b4726cafc2d83cae4a65132aac15f372689Chris Larsenstatic Intrinsics GetIntrinsic(InlineMethod method) { 12571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (method.opcode) { 12671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // Floating-point conversions. 12771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicDoubleCvt: 12871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return ((method.d.data & kIntrinsicFlagToFloatingPoint) == 0) ? 12971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe Intrinsics::kDoubleDoubleToRawLongBits : Intrinsics::kDoubleLongBitsToDouble; 13071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicFloatCvt: 13171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return ((method.d.data & kIntrinsicFlagToFloatingPoint) == 0) ? 13271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe Intrinsics::kFloatFloatToRawIntBits : Intrinsics::kFloatIntBitsToFloat; 1332a6aad9d388bd29bff04aeec3eb9429d436d1873Aart Bik case kIntrinsicFloat2Int: 1342a6aad9d388bd29bff04aeec3eb9429d436d1873Aart Bik return Intrinsics::kFloatFloatToIntBits; 1352a6aad9d388bd29bff04aeec3eb9429d436d1873Aart Bik case kIntrinsicDouble2Long: 1362a6aad9d388bd29bff04aeec3eb9429d436d1873Aart Bik return Intrinsics::kDoubleDoubleToLongBits; 13771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 13859c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik // Floating-point tests. 13959c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case kIntrinsicFloatIsInfinite: 14059c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik return Intrinsics::kFloatIsInfinite; 14159c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case kIntrinsicDoubleIsInfinite: 14259c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik return Intrinsics::kDoubleIsInfinite; 14359c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case kIntrinsicFloatIsNaN: 14459c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik return Intrinsics::kFloatIsNaN; 14559c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case kIntrinsicDoubleIsNaN: 14659c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik return Intrinsics::kDoubleIsNaN; 14759c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik 14871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // Bit manipulations. 14971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicReverseBits: 15071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (GetType(method.d.data, true)) { 151878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimInt: 15271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kIntegerReverse; 153878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimLong: 15471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kLongReverse; 15571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe default: 15671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 15771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe UNREACHABLE(); 15871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 15971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicReverseBytes: 16071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (GetType(method.d.data, true)) { 161878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimShort: 16271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kShortReverseBytes; 163878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimInt: 16471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kIntegerReverseBytes; 165878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimLong: 16671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kLongReverseBytes; 16771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe default: 16871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 16971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe UNREACHABLE(); 17071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 1719ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling case kIntrinsicRotateRight: 1729ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling switch (GetType(method.d.data, true)) { 1739ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling case Primitive::kPrimInt: 1749ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling return Intrinsics::kIntegerRotateRight; 1759ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling case Primitive::kPrimLong: 1769ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling return Intrinsics::kLongRotateRight; 1779ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling default: 1789ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 1799ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling UNREACHABLE(); 1809ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling } 1819ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling case kIntrinsicRotateLeft: 1829ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling switch (GetType(method.d.data, true)) { 1839ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling case Primitive::kPrimInt: 1849ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling return Intrinsics::kIntegerRotateLeft; 1859ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling case Primitive::kPrimLong: 1869ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling return Intrinsics::kLongRotateLeft; 1879ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling default: 1889ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 1899ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling UNREACHABLE(); 1909ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling } 1919ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling 1929ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling // Misc data processing. 1933f67e692860d281858485d48a4f1f81b907f1444Aart Bik case kIntrinsicBitCount: 1943f67e692860d281858485d48a4f1f81b907f1444Aart Bik switch (GetType(method.d.data, true)) { 1953f67e692860d281858485d48a4f1f81b907f1444Aart Bik case Primitive::kPrimInt: 1963f67e692860d281858485d48a4f1f81b907f1444Aart Bik return Intrinsics::kIntegerBitCount; 1973f67e692860d281858485d48a4f1f81b907f1444Aart Bik case Primitive::kPrimLong: 1983f67e692860d281858485d48a4f1f81b907f1444Aart Bik return Intrinsics::kLongBitCount; 1993f67e692860d281858485d48a4f1f81b907f1444Aart Bik default: 2003f67e692860d281858485d48a4f1f81b907f1444Aart Bik LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 2013f67e692860d281858485d48a4f1f81b907f1444Aart Bik UNREACHABLE(); 2023f67e692860d281858485d48a4f1f81b907f1444Aart Bik } 20359c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case kIntrinsicCompare: 20459c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik switch (GetType(method.d.data, true)) { 20559c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case Primitive::kPrimInt: 20659c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik return Intrinsics::kIntegerCompare; 20759c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case Primitive::kPrimLong: 20859c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik return Intrinsics::kLongCompare; 20959c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik default: 21059c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 21159c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik UNREACHABLE(); 21259c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik } 21359c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case kIntrinsicHighestOneBit: 21459c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik switch (GetType(method.d.data, true)) { 21559c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case Primitive::kPrimInt: 21659c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik return Intrinsics::kIntegerHighestOneBit; 21759c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case Primitive::kPrimLong: 21859c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik return Intrinsics::kLongHighestOneBit; 21959c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik default: 22059c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 22159c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik UNREACHABLE(); 22259c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik } 22359c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case kIntrinsicLowestOneBit: 22459c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik switch (GetType(method.d.data, true)) { 22559c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case Primitive::kPrimInt: 22659c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik return Intrinsics::kIntegerLowestOneBit; 22759c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case Primitive::kPrimLong: 22859c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik return Intrinsics::kLongLowestOneBit; 22959c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik default: 23059c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 23159c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik UNREACHABLE(); 23259c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik } 233611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling case kIntrinsicNumberOfLeadingZeros: 234611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling switch (GetType(method.d.data, true)) { 235611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling case Primitive::kPrimInt: 236611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling return Intrinsics::kIntegerNumberOfLeadingZeros; 237611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling case Primitive::kPrimLong: 238611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling return Intrinsics::kLongNumberOfLeadingZeros; 239611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling default: 240611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 241611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling UNREACHABLE(); 242611d3395e9efc0ab8dbfa4a197fa022fbd8c7204Scott Wakeling } 2439ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling case kIntrinsicNumberOfTrailingZeros: 2449ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling switch (GetType(method.d.data, true)) { 2459ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling case Primitive::kPrimInt: 2469ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling return Intrinsics::kIntegerNumberOfTrailingZeros; 2479ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling case Primitive::kPrimLong: 2489ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling return Intrinsics::kLongNumberOfTrailingZeros; 2499ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling default: 2509ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 2519ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling UNREACHABLE(); 2529ee23f4273efed8d6378f6ad8e63c65e30a17139Scott Wakeling } 25359c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case kIntrinsicSignum: 25459c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik switch (GetType(method.d.data, true)) { 25559c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case Primitive::kPrimInt: 25659c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik return Intrinsics::kIntegerSignum; 25759c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik case Primitive::kPrimLong: 25859c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik return Intrinsics::kLongSignum; 25959c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik default: 26059c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 26159c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik UNREACHABLE(); 26259c9454b92c2096a30a2bbdffb64edf33dbdd916Aart Bik } 26371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 26471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // Abs. 26571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicAbsDouble: 26671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMathAbsDouble; 26771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicAbsFloat: 26871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMathAbsFloat; 26971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicAbsInt: 27071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMathAbsInt; 27171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicAbsLong: 27271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMathAbsLong; 27371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 27471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // Min/max. 27571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicMinMaxDouble: 27671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return ((method.d.data & kIntrinsicFlagMin) == 0) ? 27771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe Intrinsics::kMathMaxDoubleDouble : Intrinsics::kMathMinDoubleDouble; 27871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicMinMaxFloat: 27971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return ((method.d.data & kIntrinsicFlagMin) == 0) ? 28071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe Intrinsics::kMathMaxFloatFloat : Intrinsics::kMathMinFloatFloat; 28171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicMinMaxInt: 28271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return ((method.d.data & kIntrinsicFlagMin) == 0) ? 28371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe Intrinsics::kMathMaxIntInt : Intrinsics::kMathMinIntInt; 28471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicMinMaxLong: 28571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return ((method.d.data & kIntrinsicFlagMin) == 0) ? 28671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe Intrinsics::kMathMaxLongLong : Intrinsics::kMathMinLongLong; 28771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 288a4f1220c1518074db18ca1044e9201492975750bMark Mendell // More math builtins. 289a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicCos: 290a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathCos; 291a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicSin: 292a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathSin; 293a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicAcos: 294a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathAcos; 295a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicAsin: 296a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathAsin; 297a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicAtan: 298a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathAtan; 299a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicAtan2: 300a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathAtan2; 301a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicCbrt: 302a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathCbrt; 303a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicCosh: 304a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathCosh; 305a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicExp: 306a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathExp; 307a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicExpm1: 308a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathExpm1; 309a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicHypot: 310a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathHypot; 311a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicLog: 312a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathLog; 313a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicLog10: 314a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathLog10; 315a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicNextAfter: 316a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathNextAfter; 317a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicSinh: 318a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathSinh; 319a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicTan: 320a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathTan; 321a4f1220c1518074db18ca1044e9201492975750bMark Mendell case kIntrinsicTanh: 322a4f1220c1518074db18ca1044e9201492975750bMark Mendell return Intrinsics::kMathTanh; 323a4f1220c1518074db18ca1044e9201492975750bMark Mendell 32471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // Misc math. 32571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicSqrt: 32671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMathSqrt; 32771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicCeil: 32871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMathCeil; 32971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicFloor: 33071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMathFloor; 33171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicRint: 33271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMathRint; 33371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicRoundDouble: 33471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMathRoundDouble; 33571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicRoundFloat: 33671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMathRoundFloat; 33771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 33871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // System.arraycopy. 33971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicSystemArrayCopyCharArray: 34071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kSystemArrayCopyChar; 34171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 342ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray case kIntrinsicSystemArrayCopy: 343ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray return Intrinsics::kSystemArrayCopy; 344ee3cf0731d0ef0787bc2947c8e3ca432b513956bNicolas Geoffray 34571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // Thread.currentThread. 34671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicCurrentThread: 3475d75afe333f57546786686d9bee16b52f1bbe971Aart Bik return Intrinsics::kThreadCurrentThread; 34871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 34971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // Memory.peek. 35071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicPeek: 35171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (GetType(method.d.data, true)) { 352878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimByte: 35371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMemoryPeekByte; 354878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimShort: 35571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMemoryPeekShortNative; 356878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimInt: 35771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMemoryPeekIntNative; 358878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimLong: 35971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMemoryPeekLongNative; 36071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe default: 36171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 36271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe UNREACHABLE(); 36371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 36471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 36571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // Memory.poke. 36671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicPoke: 36771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (GetType(method.d.data, true)) { 368878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimByte: 36971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMemoryPokeByte; 370878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimShort: 37171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMemoryPokeShortNative; 372878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimInt: 37371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMemoryPokeIntNative; 374878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimLong: 37571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kMemoryPokeLongNative; 37671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe default: 37771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 37871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe UNREACHABLE(); 37971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 38071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 38171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // String. 38271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicCharAt: 38371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kStringCharAt; 38471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicCompareTo: 38571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kStringCompareTo; 3867da072feb160079734331e994ea52760cb2a3243agicsaki case kIntrinsicEquals: 3877da072feb160079734331e994ea52760cb2a3243agicsaki return Intrinsics::kStringEquals; 388848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao case kIntrinsicGetCharsNoCheck: 389848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return Intrinsics::kStringGetCharsNoCheck; 39071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicIsEmptyOrLength: 3913e90a96f403cbc353731e6687fe12a088f996ceeRazvan A Lupusoru // The inliner can handle these two cases - and this is the preferred approach 3923e90a96f403cbc353731e6687fe12a088f996ceeRazvan A Lupusoru // since after inlining the call is no longer visible (as opposed to waiting 3933e90a96f403cbc353731e6687fe12a088f996ceeRazvan A Lupusoru // until codegen to handle intrinsic). 3943e90a96f403cbc353731e6687fe12a088f996ceeRazvan A Lupusoru return Intrinsics::kNone; 39571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicIndexOf: 39671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return ((method.d.data & kIntrinsicFlagBase0) == 0) ? 39771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe Intrinsics::kStringIndexOfAfter : Intrinsics::kStringIndexOf; 398848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao case kIntrinsicNewStringFromBytes: 399848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return Intrinsics::kStringNewStringFromBytes; 400848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao case kIntrinsicNewStringFromChars: 401848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return Intrinsics::kStringNewStringFromChars; 402848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao case kIntrinsicNewStringFromString: 403848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return Intrinsics::kStringNewStringFromString; 40471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 40571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicCas: 40671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (GetType(method.d.data, false)) { 407878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimNot: 40871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kUnsafeCASObject; 409878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimInt: 41071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kUnsafeCASInt; 411878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimLong: 41271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kUnsafeCASLong; 41371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe default: 41471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 41571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe UNREACHABLE(); 41671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 41771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicUnsafeGet: { 41871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe const bool is_volatile = (method.d.data & kIntrinsicFlagIsVolatile); 41971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (GetType(method.d.data, false)) { 420878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimInt: 42171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return is_volatile ? Intrinsics::kUnsafeGetVolatile : Intrinsics::kUnsafeGet; 422878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimLong: 42371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return is_volatile ? Intrinsics::kUnsafeGetLongVolatile : Intrinsics::kUnsafeGetLong; 424878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimNot: 425878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe return is_volatile ? Intrinsics::kUnsafeGetObjectVolatile : Intrinsics::kUnsafeGetObject; 42671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe default: 42771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 42871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe UNREACHABLE(); 42971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 43071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 43171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicUnsafePut: { 43271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe enum Sync { kNoSync, kVolatile, kOrdered }; 43371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe const Sync sync = 43471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe ((method.d.data & kIntrinsicFlagIsVolatile) != 0) ? kVolatile : 43571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe ((method.d.data & kIntrinsicFlagIsOrdered) != 0) ? kOrdered : 43671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe kNoSync; 43771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (GetType(method.d.data, false)) { 438878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimInt: 43971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (sync) { 44071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kNoSync: 44171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kUnsafePut; 44271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kVolatile: 44371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kUnsafePutVolatile; 44471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kOrdered: 44571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kUnsafePutOrdered; 44671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 44771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe break; 448878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimLong: 44971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (sync) { 45071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kNoSync: 45171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kUnsafePutLong; 45271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kVolatile: 45371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kUnsafePutLongVolatile; 45471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kOrdered: 45571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kUnsafePutLongOrdered; 45671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 45771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe break; 458878d58cbaf6b17a9e3dcab790754527f3ebc69e5Andreas Gampe case Primitive::kPrimNot: 45971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (sync) { 46071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kNoSync: 46171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kUnsafePutObject; 46271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kVolatile: 46371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kUnsafePutObjectVolatile; 46471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kOrdered: 46571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kUnsafePutObjectOrdered; 46671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 46771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe break; 46871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe default: 46971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe LOG(FATAL) << "Unknown/unsupported op size " << method.d.data; 47071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe UNREACHABLE(); 47171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 47271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe break; 47371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 47471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 4750e54c0160c84894696c05af6cad9eae3690f9496Aart Bik // 1.8. 4760e54c0160c84894696c05af6cad9eae3690f9496Aart Bik case kIntrinsicUnsafeGetAndAddInt: 4770e54c0160c84894696c05af6cad9eae3690f9496Aart Bik return Intrinsics::kUnsafeGetAndAddInt; 4780e54c0160c84894696c05af6cad9eae3690f9496Aart Bik case kIntrinsicUnsafeGetAndAddLong: 4790e54c0160c84894696c05af6cad9eae3690f9496Aart Bik return Intrinsics::kUnsafeGetAndAddLong; 4800e54c0160c84894696c05af6cad9eae3690f9496Aart Bik case kIntrinsicUnsafeGetAndSetInt: 4810e54c0160c84894696c05af6cad9eae3690f9496Aart Bik return Intrinsics::kUnsafeGetAndSetInt; 4820e54c0160c84894696c05af6cad9eae3690f9496Aart Bik case kIntrinsicUnsafeGetAndSetLong: 4830e54c0160c84894696c05af6cad9eae3690f9496Aart Bik return Intrinsics::kUnsafeGetAndSetLong; 4840e54c0160c84894696c05af6cad9eae3690f9496Aart Bik case kIntrinsicUnsafeGetAndSetObject: 4850e54c0160c84894696c05af6cad9eae3690f9496Aart Bik return Intrinsics::kUnsafeGetAndSetObject; 4860e54c0160c84894696c05af6cad9eae3690f9496Aart Bik case kIntrinsicUnsafeLoadFence: 4870e54c0160c84894696c05af6cad9eae3690f9496Aart Bik return Intrinsics::kUnsafeLoadFence; 4880e54c0160c84894696c05af6cad9eae3690f9496Aart Bik case kIntrinsicUnsafeStoreFence: 4890e54c0160c84894696c05af6cad9eae3690f9496Aart Bik return Intrinsics::kUnsafeStoreFence; 4900e54c0160c84894696c05af6cad9eae3690f9496Aart Bik case kIntrinsicUnsafeFullFence: 4910e54c0160c84894696c05af6cad9eae3690f9496Aart Bik return Intrinsics::kUnsafeFullFence; 4920e54c0160c84894696c05af6cad9eae3690f9496Aart Bik 49371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // Virtual cases. 49471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 49571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kIntrinsicReferenceGetReferent: 49671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kReferenceGetReferent; 49771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 49871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // Quick inliner cases. Remove after refactoring. They are here so that we can use the 49971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // compiler to warn on missing cases. 50071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 50171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kInlineOpNop: 50271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kInlineOpReturnArg: 50371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kInlineOpNonWideConst: 50471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kInlineOpIGet: 50571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kInlineOpIPut: 506354efa6cdf558b2331e8fec539893fa51763806eVladimir Marko case kInlineOpConstructor: 50771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kNone; 50871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 509848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao // String init cases, not intrinsics. 510848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 511848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao case kInlineStringInit: 512848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao return Intrinsics::kNone; 513848f70a3d73833fc1bf3032a9ff6812e429661d9Jeff Hao 51471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // No default case to make the compiler warn on missing cases. 51571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 51671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return Intrinsics::kNone; 51771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe} 51871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 519bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampestatic bool CheckInvokeType(Intrinsics intrinsic, HInvoke* invoke, const DexFile& dex_file) { 52071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // The DexFileMethodInliner should have checked whether the methods are agreeing with 52171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // what we expect, i.e., static methods are called as such. Add another check here for 52271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // our expectations: 523bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe // 524bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe // Whenever the intrinsic is marked as static, report an error if we find an InvokeVirtual. 525bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe // 526bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe // Whenever the intrinsic is marked as direct and we find an InvokeVirtual, a devirtualization 527bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe // failure occured. We might be in a situation where we have inlined a method that calls an 528bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe // intrinsic, but that method is in a different dex file on which we do not have a 529bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe // verified_method that would have helped the compiler driver sharpen the call. In that case, 530bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe // make sure that the intrinsic is actually for some final method (or in a final class), as 531bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe // otherwise the intrinsics setup is broken. 532bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe // 533bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe // For the last direction, we have intrinsics for virtual functions that will perform a check 534bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe // inline. If the precise type is known, however, the instruction will be sharpened to an 535bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe // InvokeStaticOrDirect. 53671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe InvokeType intrinsic_type = GetIntrinsicInvokeType(intrinsic); 53771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe InvokeType invoke_type = invoke->IsInvokeStaticOrDirect() ? 538e523423a053af5cb55837f07ceae9ff2fd581712Nicolas Geoffray invoke->AsInvokeStaticOrDirect()->GetOptimizedInvokeType() : 53971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe invoke->IsInvokeVirtual() ? kVirtual : kSuper; 54071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (intrinsic_type) { 54171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kStatic: 54271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return (invoke_type == kStatic); 543bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe 54471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kDirect: 545bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe if (invoke_type == kDirect) { 546bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe return true; 547bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe } 548bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe if (invoke_type == kVirtual) { 549bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 550bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe ScopedObjectAccess soa(Thread::Current()); 551bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe ArtMethod* art_method = 552bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe class_linker->FindDexCache(soa.Self(), dex_file)->GetResolvedMethod( 553bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe invoke->GetDexMethodIndex(), class_linker->GetImagePointerSize()); 554bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe return art_method != nullptr && 555bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe (art_method->IsFinal() || art_method->GetDeclaringClass()->IsFinal()); 556bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe } 557bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe return false; 558bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe 55971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case kVirtual: 56071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe // Call might be devirtualized. 56171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return (invoke_type == kVirtual || invoke_type == kDirect); 56271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 56371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe default: 56471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return false; 56571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 56671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe} 56771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 56871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe// TODO: Refactor DexFileMethodInliner and have something nicer than InlineMethod. 56971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampevoid IntrinsicsRecognizer::Run() { 57071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe for (HReversePostOrderIterator it(*graph_); !it.Done(); it.Advance()) { 57171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe HBasicBlock* block = it.Current(); 57271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe for (HInstructionIterator inst_it(block->GetInstructions()); !inst_it.Done(); 57371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe inst_it.Advance()) { 57471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe HInstruction* inst = inst_it.Current(); 57571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe if (inst->IsInvoke()) { 57671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe HInvoke* invoke = inst->AsInvoke(); 57771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe InlineMethod method; 578bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe const DexFile& dex_file = invoke->GetDexFile(); 579bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe DexFileMethodInliner* inliner = driver_->GetMethodInlinerMap()->GetMethodInliner(&dex_file); 580d5111bf05fc0a9974280a80eeb43db6d5227a81eNicolas Geoffray DCHECK(inliner != nullptr); 58171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe if (inliner->IsIntrinsic(invoke->GetDexMethodIndex(), &method)) { 58216ba2b4726cafc2d83cae4a65132aac15f372689Chris Larsen Intrinsics intrinsic = GetIntrinsic(method); 58371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 58471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe if (intrinsic != Intrinsics::kNone) { 585bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe if (!CheckInvokeType(intrinsic, invoke, dex_file)) { 586a14b9fef395b94fa9a32147862c198fe7c22e3d7Andreas Gampe LOG(WARNING) << "Found an intrinsic with unexpected invoke type: " 587bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe << intrinsic << " for " 588bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe << PrettyMethod(invoke->GetDexMethodIndex(), invoke->GetDexFile()) 589bfb5ba90cd6425ce49c2125a87e3b12222cc2601Andreas Gampe << invoke->DebugName(); 59071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } else { 5915d75afe333f57546786686d9bee16b52f1bbe971Aart Bik invoke->SetIntrinsic(intrinsic, 5925d75afe333f57546786686d9bee16b52f1bbe971Aart Bik NeedsEnvironmentOrCache(intrinsic), 5935d75afe333f57546786686d9bee16b52f1bbe971Aart Bik GetSideEffects(intrinsic), 5945d75afe333f57546786686d9bee16b52f1bbe971Aart Bik GetExceptions(intrinsic)); 59538e9e8046ea2196284bdb4638771c31108a30a4aJean-Philippe Halimi MaybeRecordStat(MethodCompilationStat::kIntrinsicRecognized); 59671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 59771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 59871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 59971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 60071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 60171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 60271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe} 60371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 60471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampestd::ostream& operator<<(std::ostream& os, const Intrinsics& intrinsic) { 60571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe switch (intrinsic) { 60671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case Intrinsics::kNone: 607109c89a8e3b5023d123f8c1313f5843a0ba2e15eDavid Brazdil os << "None"; 60871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe break; 6095d75afe333f57546786686d9bee16b52f1bbe971Aart Bik#define OPTIMIZING_INTRINSICS(Name, IsStatic, NeedsEnvironmentOrCache, SideEffects, Exceptions) \ 61071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe case Intrinsics::k ## Name: \ 61171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe os << # Name; \ 61271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe break; 61371fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#include "intrinsics_list.h" 61471fb52fee246b7d511f520febbd73dc7a9bbca79Andreas GampeINTRINSICS_LIST(OPTIMIZING_INTRINSICS) 61571fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#undef STATIC_INTRINSICS_LIST 61671fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#undef VIRTUAL_INTRINSICS_LIST 61771fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe#undef OPTIMIZING_INTRINSICS 61871fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe } 61971fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe return os; 62071fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe} 62171fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe 62271fb52fee246b7d511f520febbd73dc7a9bbca79Andreas Gampe} // namespace art 623