interpreter_intrinsics.cc revision 4a4610a438ff2b836f6fe07839a0689ce618863a
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "interpreter/interpreter_intrinsics.h" 18 19#include "compiler/intrinsics_enum.h" 20#include "dex_instruction.h" 21#include "interpreter/interpreter_common.h" 22 23namespace art { 24namespace interpreter { 25 26 27#define BINARY_INTRINSIC(name, op, get1, get2, set) \ 28static ALWAYS_INLINE bool name(ShadowFrame* shadow_frame, \ 29 const Instruction* inst, \ 30 uint16_t inst_data, \ 31 JValue* result_register) \ 32 REQUIRES_SHARED(Locks::mutator_lock_) { \ 33 uint32_t arg[Instruction::kMaxVarArgRegs] = {}; \ 34 inst->GetVarArgs(arg, inst_data); \ 35 result_register->set(op(shadow_frame->get1, shadow_frame->get2)); \ 36 return true; \ 37} 38 39#define BINARY_II_INTRINSIC(name, op, set) \ 40 BINARY_INTRINSIC(name, op, GetVReg(arg[0]), GetVReg(arg[1]), set) 41 42#define BINARY_JJ_INTRINSIC(name, op, set) \ 43 BINARY_INTRINSIC(name, op, GetVRegLong(arg[0]), GetVRegLong(arg[2]), set) 44 45#define BINARY_JI_INTRINSIC(name, op, set) \ 46 BINARY_INTRINSIC(name, op, GetVRegLong(arg[0]), GetVReg(arg[2]), set) 47 48#define UNARY_INTRINSIC(name, op, get, set) \ 49static ALWAYS_INLINE bool name(ShadowFrame* shadow_frame, \ 50 const Instruction* inst, \ 51 uint16_t inst_data, \ 52 JValue* result_register) \ 53 REQUIRES_SHARED(Locks::mutator_lock_) { \ 54 uint32_t arg[Instruction::kMaxVarArgRegs] = {}; \ 55 inst->GetVarArgs(arg, inst_data); \ 56 result_register->set(op(shadow_frame->get(arg[0]))); \ 57 return true; \ 58} 59 60 61// java.lang.Integer.reverse(I)I 62UNARY_INTRINSIC(MterpIntegerReverse, ReverseBits32, GetVReg, SetI); 63 64// java.lang.Integer.reverseBytes(I)I 65UNARY_INTRINSIC(MterpIntegerReverseBytes, BSWAP, GetVReg, SetI); 66 67// java.lang.Integer.bitCount(I)I 68UNARY_INTRINSIC(MterpIntegerBitCount, POPCOUNT, GetVReg, SetI); 69 70// java.lang.Integer.compare(II)I 71BINARY_II_INTRINSIC(MterpIntegerCompare, Compare, SetI); 72 73// java.lang.Integer.highestOneBit(I)I 74UNARY_INTRINSIC(MterpIntegerHighestOneBit, HighestOneBitValue, GetVReg, SetI); 75 76// java.lang.Integer.LowestOneBit(I)I 77UNARY_INTRINSIC(MterpIntegerLowestOneBit, LowestOneBitValue, GetVReg, SetI); 78 79// java.lang.Integer.numberOfLeadingZeros(I)I 80UNARY_INTRINSIC(MterpIntegerNumberOfLeadingZeros, JAVASTYLE_CLZ, GetVReg, SetI); 81 82// java.lang.Integer.numberOfTrailingZeros(I)I 83UNARY_INTRINSIC(MterpIntegerNumberOfTrailingZeros, JAVASTYLE_CTZ, GetVReg, SetI); 84 85// java.lang.Integer.rotateRight(II)I 86BINARY_II_INTRINSIC(MterpIntegerRotateRight, (Rot<int32_t, false>), SetI); 87 88// java.lang.Integer.rotateLeft(II)I 89BINARY_II_INTRINSIC(MterpIntegerRotateLeft, (Rot<int32_t, true>), SetI); 90 91// java.lang.Integer.signum(I)I 92UNARY_INTRINSIC(MterpIntegerSignum, Signum, GetVReg, SetI); 93 94// java.lang.Long.reverse(I)I 95UNARY_INTRINSIC(MterpLongReverse, ReverseBits64, GetVRegLong, SetJ); 96 97// java.lang.Long.reverseBytes(J)J 98UNARY_INTRINSIC(MterpLongReverseBytes, BSWAP, GetVRegLong, SetJ); 99 100// java.lang.Long.bitCount(J)I 101UNARY_INTRINSIC(MterpLongBitCount, POPCOUNT, GetVRegLong, SetI); 102 103// java.lang.Long.compare(JJ)I 104BINARY_JJ_INTRINSIC(MterpLongCompare, Compare, SetI); 105 106// java.lang.Long.highestOneBit(J)J 107UNARY_INTRINSIC(MterpLongHighestOneBit, HighestOneBitValue, GetVRegLong, SetJ); 108 109// java.lang.Long.lowestOneBit(J)J 110UNARY_INTRINSIC(MterpLongLowestOneBit, LowestOneBitValue, GetVRegLong, SetJ); 111 112// java.lang.Long.numberOfLeadingZeros(J)I 113UNARY_INTRINSIC(MterpLongNumberOfLeadingZeros, JAVASTYLE_CLZ, GetVRegLong, SetJ); 114 115// java.lang.Long.numberOfTrailingZeros(J)I 116UNARY_INTRINSIC(MterpLongNumberOfTrailingZeros, JAVASTYLE_CTZ, GetVRegLong, SetJ); 117 118// java.lang.Long.rotateRight(JI)J 119BINARY_JJ_INTRINSIC(MterpLongRotateRight, (Rot<int64_t, false>), SetJ); 120 121// java.lang.Long.rotateLeft(JI)J 122BINARY_JJ_INTRINSIC(MterpLongRotateLeft, (Rot<int64_t, true>), SetJ); 123 124// java.lang.Long.signum(J)I 125UNARY_INTRINSIC(MterpLongSignum, Signum, GetVRegLong, SetI); 126 127// java.lang.Short.reverseBytes(S)S 128UNARY_INTRINSIC(MterpShortReverseBytes, BSWAP, GetVRegShort, SetS); 129 130// java.lang.Math.min(II)I 131BINARY_II_INTRINSIC(MterpMathMinIntInt, std::min, SetI); 132 133// java.lang.Math.min(JJ)J 134BINARY_JJ_INTRINSIC(MterpMathMinLongLong, std::min, SetJ); 135 136// java.lang.Math.max(II)I 137BINARY_II_INTRINSIC(MterpMathMaxIntInt, std::max, SetI); 138 139// java.lang.Math.max(JJ)J 140BINARY_JJ_INTRINSIC(MterpMathMaxLongLong, std::max, SetJ); 141 142// java.lang.Math.abs(I)I 143UNARY_INTRINSIC(MterpMathAbsInt, std::abs, GetVReg, SetI); 144 145// java.lang.Math.abs(J)J 146UNARY_INTRINSIC(MterpMathAbsLong, std::abs, GetVRegLong, SetJ); 147 148// java.lang.Math.abs(F)F 149UNARY_INTRINSIC(MterpMathAbsFloat, 0x7fffffff&, GetVReg, SetI); 150 151// java.lang.Math.abs(D)D 152UNARY_INTRINSIC(MterpMathAbsDouble, INT64_C(0x7fffffffffffffff)&, GetVRegLong, SetJ); 153 154// java.lang.Math.sqrt(D)D 155UNARY_INTRINSIC(MterpMathSqrt, std::sqrt, GetVRegDouble, SetD); 156 157// java.lang.Math.ceil(D)D 158UNARY_INTRINSIC(MterpMathCeil, std::ceil, GetVRegDouble, SetD); 159 160// java.lang.Math.floor(D)D 161UNARY_INTRINSIC(MterpMathFloor, std::floor, GetVRegDouble, SetD); 162 163// java.lang.Math.sin(D)D 164UNARY_INTRINSIC(MterpMathSin, std::sin, GetVRegDouble, SetD); 165 166// java.lang.Math.cos(D)D 167UNARY_INTRINSIC(MterpMathCos, std::cos, GetVRegDouble, SetD); 168 169// java.lang.Math.tan(D)D 170UNARY_INTRINSIC(MterpMathTan, std::tan, GetVRegDouble, SetD); 171 172// java.lang.Math.asin(D)D 173UNARY_INTRINSIC(MterpMathAsin, std::asin, GetVRegDouble, SetD); 174 175// java.lang.Math.acos(D)D 176UNARY_INTRINSIC(MterpMathAcos, std::acos, GetVRegDouble, SetD); 177 178// java.lang.Math.atan(D)D 179UNARY_INTRINSIC(MterpMathAtan, std::atan, GetVRegDouble, SetD); 180 181// java.lang.String.charAt(I)C 182static ALWAYS_INLINE bool MterpStringCharAt(ShadowFrame* shadow_frame, 183 const Instruction* inst, 184 uint16_t inst_data, 185 JValue* result_register) 186 REQUIRES_SHARED(Locks::mutator_lock_) { 187 uint32_t arg[Instruction::kMaxVarArgRegs] = {}; 188 inst->GetVarArgs(arg, inst_data); 189 mirror::String* str = shadow_frame->GetVRegReference(arg[0])->AsString(); 190 int length = str->GetLength(); 191 int index = shadow_frame->GetVReg(arg[1]); 192 uint16_t res; 193 if (UNLIKELY(index < 0) || (index >= length)) { 194 return false; // Punt and let non-intrinsic version deal with the throw. 195 } 196 if (str->IsCompressed()) { 197 res = str->GetValueCompressed()[index]; 198 } else { 199 res = str->GetValue()[index]; 200 } 201 result_register->SetC(res); 202 return true; 203} 204 205// java.lang.String.compareTo(Ljava/lang/string)I 206static ALWAYS_INLINE bool MterpStringCompareTo(ShadowFrame* shadow_frame, 207 const Instruction* inst, 208 uint16_t inst_data, 209 JValue* result_register) 210 REQUIRES_SHARED(Locks::mutator_lock_) { 211 uint32_t arg[Instruction::kMaxVarArgRegs] = {}; 212 inst->GetVarArgs(arg, inst_data); 213 mirror::String* str = shadow_frame->GetVRegReference(arg[0])->AsString(); 214 mirror::Object* arg1 = shadow_frame->GetVRegReference(arg[1]); 215 if (arg1 == nullptr) { 216 return false; 217 } 218 result_register->SetI(str->CompareTo(arg1->AsString())); 219 return true; 220} 221 222#define STRING_INDEXOF_INTRINSIC(name, starting_pos) \ 223static ALWAYS_INLINE bool Mterp##name(ShadowFrame* shadow_frame, \ 224 const Instruction* inst, \ 225 uint16_t inst_data, \ 226 JValue* result_register) \ 227 REQUIRES_SHARED(Locks::mutator_lock_) { \ 228 uint32_t arg[Instruction::kMaxVarArgRegs] = {}; \ 229 inst->GetVarArgs(arg, inst_data); \ 230 mirror::String* str = shadow_frame->GetVRegReference(arg[0])->AsString(); \ 231 int ch = shadow_frame->GetVReg(arg[1]); \ 232 if (ch >= 0x10000) { \ 233 /* Punt if supplementary char. */ \ 234 return false; \ 235 } \ 236 result_register->SetI(str->FastIndexOf(ch, starting_pos)); \ 237 return true; \ 238} 239 240// java.lang.String.indexOf(I)I 241STRING_INDEXOF_INTRINSIC(StringIndexOf, 0); 242 243// java.lang.String.indexOf(II)I 244STRING_INDEXOF_INTRINSIC(StringIndexOfAfter, shadow_frame->GetVReg(arg[2])); 245 246#define SIMPLE_STRING_INTRINSIC(name, operation) \ 247static ALWAYS_INLINE bool Mterp##name(ShadowFrame* shadow_frame, \ 248 const Instruction* inst, \ 249 uint16_t inst_data, \ 250 JValue* result_register) \ 251 REQUIRES_SHARED(Locks::mutator_lock_) { \ 252 uint32_t arg[Instruction::kMaxVarArgRegs] = {}; \ 253 inst->GetVarArgs(arg, inst_data); \ 254 mirror::String* str = shadow_frame->GetVRegReference(arg[0])->AsString(); \ 255 result_register->operation; \ 256 return true; \ 257} 258 259// java.lang.String.isEmpty()Z 260SIMPLE_STRING_INTRINSIC(StringIsEmpty, SetZ(str->GetLength() == 0)) 261 262// java.lang.String.length()I 263SIMPLE_STRING_INTRINSIC(StringLength, SetI(str->GetLength())) 264 265// java.lang.String.getCharsNoCheck(II[CI)V 266static ALWAYS_INLINE bool MterpStringGetCharsNoCheck(ShadowFrame* shadow_frame, 267 const Instruction* inst, 268 uint16_t inst_data, 269 JValue* result_register ATTRIBUTE_UNUSED) 270 REQUIRES_SHARED(Locks::mutator_lock_) { 271 // Start, end & index already checked by caller - won't throw. Destination is uncompressed. 272 uint32_t arg[Instruction::kMaxVarArgRegs] = {}; 273 inst->GetVarArgs(arg, inst_data); 274 mirror::String* str = shadow_frame->GetVRegReference(arg[0])->AsString(); 275 int32_t start = shadow_frame->GetVReg(arg[1]); 276 int32_t end = shadow_frame->GetVReg(arg[2]); 277 int32_t index = shadow_frame->GetVReg(arg[4]); 278 mirror::CharArray* array = shadow_frame->GetVRegReference(arg[3])->AsCharArray(); 279 uint16_t* dst = array->GetData() + index; 280 int32_t len = (end - start); 281 if (str->IsCompressed()) { 282 const uint8_t* src_8 = str->GetValueCompressed() + start; 283 for (int i = 0; i < len; i++) { 284 dst[i] = src_8[i]; 285 } 286 } else { 287 uint16_t* src_16 = str->GetValue() + start; 288 memcpy(dst, src_16, len * sizeof(uint16_t)); 289 } 290 return true; 291} 292 293// java.lang.String.equalsLjava/lang/Object;)Z 294static ALWAYS_INLINE bool MterpStringEquals(ShadowFrame* shadow_frame, 295 const Instruction* inst, 296 uint16_t inst_data, 297 JValue* result_register) 298 REQUIRES_SHARED(Locks::mutator_lock_) { 299 uint32_t arg[Instruction::kMaxVarArgRegs] = {}; 300 inst->GetVarArgs(arg, inst_data); 301 mirror::String* str = shadow_frame->GetVRegReference(arg[0])->AsString(); 302 mirror::Object* obj = shadow_frame->GetVRegReference(arg[1]); 303 bool res = false; // Assume not equal. 304 if ((obj != nullptr) && obj->IsString()) { 305 mirror::String* str2 = obj->AsString(); 306 if (str->GetCount() == str2->GetCount()) { 307 // Length & compression status are same. Can use block compare. 308 void* bytes1; 309 void* bytes2; 310 int len = str->GetLength(); 311 if (str->IsCompressed()) { 312 bytes1 = str->GetValueCompressed(); 313 bytes2 = str2->GetValueCompressed(); 314 } else { 315 len *= sizeof(uint16_t); 316 bytes1 = str->GetValue(); 317 bytes2 = str2->GetValue(); 318 } 319 res = (memcmp(bytes1, bytes2, len) == 0); 320 } 321 } 322 result_register->SetZ(res); 323 return true; 324} 325 326#define VARHANDLE_FENCE_INTRINSIC(name, std_memory_operation) \ 327static ALWAYS_INLINE bool name(ShadowFrame* /* shadow_frame */, \ 328 const Instruction* /* inst */, \ 329 uint16_t /* inst_data */, \ 330 JValue* /* result_register */) \ 331 REQUIRES_SHARED(Locks::mutator_lock_) { \ 332 std::atomic_thread_fence(std_memory_operation); \ 333 return true; \ 334} 335 336// The VarHandle fence methods are static (unlike sun.misc.Unsafe versions). 337// The fences for the LoadLoadFence and StoreStoreFence are stronger 338// than strictly required, but the impact should be marginal. 339VARHANDLE_FENCE_INTRINSIC(MterpVarHandleFullFence, std::memory_order_seq_cst) 340VARHANDLE_FENCE_INTRINSIC(MterpVarHandleAcquireFence, std::memory_order_acquire) 341VARHANDLE_FENCE_INTRINSIC(MterpVarHandleReleaseFence, std::memory_order_release) 342VARHANDLE_FENCE_INTRINSIC(MterpVarHandleLoadLoadFence, std::memory_order_acquire) 343VARHANDLE_FENCE_INTRINSIC(MterpVarHandleStoreStoreFence, std::memory_order_release) 344 345// Macro to help keep track of what's left to implement. 346#define UNIMPLEMENTED_CASE(name) \ 347 case Intrinsics::k##name: \ 348 res = false; \ 349 break; 350 351#define INTRINSIC_CASE(name) \ 352 case Intrinsics::k##name: \ 353 res = Mterp##name(shadow_frame, inst, inst_data, result_register); \ 354 break; 355 356bool MterpHandleIntrinsic(ShadowFrame* shadow_frame, 357 ArtMethod* const called_method, 358 const Instruction* inst, 359 uint16_t inst_data, 360 JValue* result_register) 361 REQUIRES_SHARED(Locks::mutator_lock_) { 362 Intrinsics intrinsic = static_cast<Intrinsics>(called_method->GetIntrinsic()); 363 bool res = false; // Assume failure 364 switch (intrinsic) { 365 UNIMPLEMENTED_CASE(DoubleDoubleToRawLongBits /* (D)J */) 366 UNIMPLEMENTED_CASE(DoubleDoubleToLongBits /* (D)J */) 367 UNIMPLEMENTED_CASE(DoubleIsInfinite /* (D)Z */) 368 UNIMPLEMENTED_CASE(DoubleIsNaN /* (D)Z */) 369 UNIMPLEMENTED_CASE(DoubleLongBitsToDouble /* (J)D */) 370 UNIMPLEMENTED_CASE(FloatFloatToRawIntBits /* (F)I */) 371 UNIMPLEMENTED_CASE(FloatFloatToIntBits /* (F)I */) 372 UNIMPLEMENTED_CASE(FloatIsInfinite /* (F)Z */) 373 UNIMPLEMENTED_CASE(FloatIsNaN /* (F)Z */) 374 UNIMPLEMENTED_CASE(FloatIntBitsToFloat /* (I)F */) 375 INTRINSIC_CASE(IntegerReverse) 376 INTRINSIC_CASE(IntegerReverseBytes) 377 INTRINSIC_CASE(IntegerBitCount) 378 INTRINSIC_CASE(IntegerCompare) 379 INTRINSIC_CASE(IntegerHighestOneBit) 380 INTRINSIC_CASE(IntegerLowestOneBit) 381 INTRINSIC_CASE(IntegerNumberOfLeadingZeros) 382 INTRINSIC_CASE(IntegerNumberOfTrailingZeros) 383 INTRINSIC_CASE(IntegerRotateRight) 384 INTRINSIC_CASE(IntegerRotateLeft) 385 INTRINSIC_CASE(IntegerSignum) 386 INTRINSIC_CASE(LongReverse) 387 INTRINSIC_CASE(LongReverseBytes) 388 INTRINSIC_CASE(LongBitCount) 389 INTRINSIC_CASE(LongCompare) 390 INTRINSIC_CASE(LongHighestOneBit) 391 INTRINSIC_CASE(LongLowestOneBit) 392 INTRINSIC_CASE(LongNumberOfLeadingZeros) 393 INTRINSIC_CASE(LongNumberOfTrailingZeros) 394 INTRINSIC_CASE(LongRotateRight) 395 INTRINSIC_CASE(LongRotateLeft) 396 INTRINSIC_CASE(LongSignum) 397 INTRINSIC_CASE(ShortReverseBytes) 398 INTRINSIC_CASE(MathAbsDouble) 399 INTRINSIC_CASE(MathAbsFloat) 400 INTRINSIC_CASE(MathAbsLong) 401 INTRINSIC_CASE(MathAbsInt) 402 UNIMPLEMENTED_CASE(MathMinDoubleDouble /* (DD)D */) 403 UNIMPLEMENTED_CASE(MathMinFloatFloat /* (FF)F */) 404 INTRINSIC_CASE(MathMinLongLong) 405 INTRINSIC_CASE(MathMinIntInt) 406 UNIMPLEMENTED_CASE(MathMaxDoubleDouble /* (DD)D */) 407 UNIMPLEMENTED_CASE(MathMaxFloatFloat /* (FF)F */) 408 INTRINSIC_CASE(MathMaxLongLong) 409 INTRINSIC_CASE(MathMaxIntInt) 410 INTRINSIC_CASE(MathCos) 411 INTRINSIC_CASE(MathSin) 412 INTRINSIC_CASE(MathAcos) 413 INTRINSIC_CASE(MathAsin) 414 INTRINSIC_CASE(MathAtan) 415 UNIMPLEMENTED_CASE(MathAtan2 /* (DD)D */) 416 UNIMPLEMENTED_CASE(MathCbrt /* (D)D */) 417 UNIMPLEMENTED_CASE(MathCosh /* (D)D */) 418 UNIMPLEMENTED_CASE(MathExp /* (D)D */) 419 UNIMPLEMENTED_CASE(MathExpm1 /* (D)D */) 420 UNIMPLEMENTED_CASE(MathHypot /* (DD)D */) 421 UNIMPLEMENTED_CASE(MathLog /* (D)D */) 422 UNIMPLEMENTED_CASE(MathLog10 /* (D)D */) 423 UNIMPLEMENTED_CASE(MathNextAfter /* (DD)D */) 424 UNIMPLEMENTED_CASE(MathSinh /* (D)D */) 425 INTRINSIC_CASE(MathTan) 426 UNIMPLEMENTED_CASE(MathTanh /* (D)D */) 427 INTRINSIC_CASE(MathSqrt) 428 INTRINSIC_CASE(MathCeil) 429 INTRINSIC_CASE(MathFloor) 430 UNIMPLEMENTED_CASE(MathRint /* (D)D */) 431 UNIMPLEMENTED_CASE(MathRoundDouble /* (D)J */) 432 UNIMPLEMENTED_CASE(MathRoundFloat /* (F)I */) 433 UNIMPLEMENTED_CASE(SystemArrayCopyChar /* ([CI[CII)V */) 434 UNIMPLEMENTED_CASE(SystemArrayCopy /* (Ljava/lang/Object;ILjava/lang/Object;II)V */) 435 UNIMPLEMENTED_CASE(ThreadCurrentThread /* ()Ljava/lang/Thread; */) 436 UNIMPLEMENTED_CASE(MemoryPeekByte /* (J)B */) 437 UNIMPLEMENTED_CASE(MemoryPeekIntNative /* (J)I */) 438 UNIMPLEMENTED_CASE(MemoryPeekLongNative /* (J)J */) 439 UNIMPLEMENTED_CASE(MemoryPeekShortNative /* (J)S */) 440 UNIMPLEMENTED_CASE(MemoryPokeByte /* (JB)V */) 441 UNIMPLEMENTED_CASE(MemoryPokeIntNative /* (JI)V */) 442 UNIMPLEMENTED_CASE(MemoryPokeLongNative /* (JJ)V */) 443 UNIMPLEMENTED_CASE(MemoryPokeShortNative /* (JS)V */) 444 INTRINSIC_CASE(StringCharAt) 445 INTRINSIC_CASE(StringCompareTo) 446 INTRINSIC_CASE(StringEquals) 447 INTRINSIC_CASE(StringGetCharsNoCheck) 448 INTRINSIC_CASE(StringIndexOf) 449 INTRINSIC_CASE(StringIndexOfAfter) 450 UNIMPLEMENTED_CASE(StringStringIndexOf /* (Ljava/lang/String;)I */) 451 UNIMPLEMENTED_CASE(StringStringIndexOfAfter /* (Ljava/lang/String;I)I */) 452 INTRINSIC_CASE(StringIsEmpty) 453 INTRINSIC_CASE(StringLength) 454 UNIMPLEMENTED_CASE(StringNewStringFromBytes /* ([BIII)Ljava/lang/String; */) 455 UNIMPLEMENTED_CASE(StringNewStringFromChars /* (II[C)Ljava/lang/String; */) 456 UNIMPLEMENTED_CASE(StringNewStringFromString /* (Ljava/lang/String;)Ljava/lang/String; */) 457 UNIMPLEMENTED_CASE(StringBufferAppend /* (Ljava/lang/String;)Ljava/lang/StringBuffer; */) 458 UNIMPLEMENTED_CASE(StringBufferLength /* ()I */) 459 UNIMPLEMENTED_CASE(StringBufferToString /* ()Ljava/lang/String; */) 460 UNIMPLEMENTED_CASE(StringBuilderAppend /* (Ljava/lang/String;)Ljava/lang/StringBuilder; */) 461 UNIMPLEMENTED_CASE(StringBuilderLength /* ()I */) 462 UNIMPLEMENTED_CASE(StringBuilderToString /* ()Ljava/lang/String; */) 463 UNIMPLEMENTED_CASE(UnsafeCASInt /* (Ljava/lang/Object;JII)Z */) 464 UNIMPLEMENTED_CASE(UnsafeCASLong /* (Ljava/lang/Object;JJJ)Z */) 465 UNIMPLEMENTED_CASE(UnsafeCASObject /* (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z */) 466 UNIMPLEMENTED_CASE(UnsafeGet /* (Ljava/lang/Object;J)I */) 467 UNIMPLEMENTED_CASE(UnsafeGetVolatile /* (Ljava/lang/Object;J)I */) 468 UNIMPLEMENTED_CASE(UnsafeGetObject /* (Ljava/lang/Object;J)Ljava/lang/Object; */) 469 UNIMPLEMENTED_CASE(UnsafeGetObjectVolatile /* (Ljava/lang/Object;J)Ljava/lang/Object; */) 470 UNIMPLEMENTED_CASE(UnsafeGetLong /* (Ljava/lang/Object;J)J */) 471 UNIMPLEMENTED_CASE(UnsafeGetLongVolatile /* (Ljava/lang/Object;J)J */) 472 UNIMPLEMENTED_CASE(UnsafePut /* (Ljava/lang/Object;JI)V */) 473 UNIMPLEMENTED_CASE(UnsafePutOrdered /* (Ljava/lang/Object;JI)V */) 474 UNIMPLEMENTED_CASE(UnsafePutVolatile /* (Ljava/lang/Object;JI)V */) 475 UNIMPLEMENTED_CASE(UnsafePutObject /* (Ljava/lang/Object;JLjava/lang/Object;)V */) 476 UNIMPLEMENTED_CASE(UnsafePutObjectOrdered /* (Ljava/lang/Object;JLjava/lang/Object;)V */) 477 UNIMPLEMENTED_CASE(UnsafePutObjectVolatile /* (Ljava/lang/Object;JLjava/lang/Object;)V */) 478 UNIMPLEMENTED_CASE(UnsafePutLong /* (Ljava/lang/Object;JJ)V */) 479 UNIMPLEMENTED_CASE(UnsafePutLongOrdered /* (Ljava/lang/Object;JJ)V */) 480 UNIMPLEMENTED_CASE(UnsafePutLongVolatile /* (Ljava/lang/Object;JJ)V */) 481 UNIMPLEMENTED_CASE(UnsafeGetAndAddInt /* (Ljava/lang/Object;JI)I */) 482 UNIMPLEMENTED_CASE(UnsafeGetAndAddLong /* (Ljava/lang/Object;JJ)J */) 483 UNIMPLEMENTED_CASE(UnsafeGetAndSetInt /* (Ljava/lang/Object;JI)I */) 484 UNIMPLEMENTED_CASE(UnsafeGetAndSetLong /* (Ljava/lang/Object;JJ)J */) 485 UNIMPLEMENTED_CASE(UnsafeGetAndSetObject /* (Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object; */) 486 UNIMPLEMENTED_CASE(UnsafeLoadFence /* ()V */) 487 UNIMPLEMENTED_CASE(UnsafeStoreFence /* ()V */) 488 UNIMPLEMENTED_CASE(UnsafeFullFence /* ()V */) 489 UNIMPLEMENTED_CASE(ReferenceGetReferent /* ()Ljava/lang/Object; */) 490 UNIMPLEMENTED_CASE(IntegerValueOf /* (I)Ljava/lang/Integer; */) 491 UNIMPLEMENTED_CASE(ThreadInterrupted /* ()Z */) 492 INTRINSIC_CASE(VarHandleFullFence) 493 INTRINSIC_CASE(VarHandleAcquireFence) 494 INTRINSIC_CASE(VarHandleReleaseFence) 495 INTRINSIC_CASE(VarHandleLoadLoadFence) 496 INTRINSIC_CASE(VarHandleStoreStoreFence) 497 case Intrinsics::kNone: 498 res = false; 499 break; 500 // Note: no default case to ensure we catch any newly added intrinsics. 501 } 502 return res; 503} 504 505} // namespace interpreter 506} // namespace art 507