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 23 namespace art { 24 namespace interpreter { 25 26 27 #define BINARY_INTRINSIC(name, op, get1, get2, set) \ 28 static 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) \ 49 static 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 62 UNARY_INTRINSIC(MterpIntegerReverse, ReverseBits32, GetVReg, SetI); 63 64 // java.lang.Integer.reverseBytes(I)I 65 UNARY_INTRINSIC(MterpIntegerReverseBytes, BSWAP, GetVReg, SetI); 66 67 // java.lang.Integer.bitCount(I)I 68 UNARY_INTRINSIC(MterpIntegerBitCount, POPCOUNT, GetVReg, SetI); 69 70 // java.lang.Integer.compare(II)I 71 BINARY_II_INTRINSIC(MterpIntegerCompare, Compare, SetI); 72 73 // java.lang.Integer.highestOneBit(I)I 74 UNARY_INTRINSIC(MterpIntegerHighestOneBit, HighestOneBitValue, GetVReg, SetI); 75 76 // java.lang.Integer.LowestOneBit(I)I 77 UNARY_INTRINSIC(MterpIntegerLowestOneBit, LowestOneBitValue, GetVReg, SetI); 78 79 // java.lang.Integer.numberOfLeadingZeros(I)I 80 UNARY_INTRINSIC(MterpIntegerNumberOfLeadingZeros, JAVASTYLE_CLZ, GetVReg, SetI); 81 82 // java.lang.Integer.numberOfTrailingZeros(I)I 83 UNARY_INTRINSIC(MterpIntegerNumberOfTrailingZeros, JAVASTYLE_CTZ, GetVReg, SetI); 84 85 // java.lang.Integer.rotateRight(II)I 86 BINARY_II_INTRINSIC(MterpIntegerRotateRight, (Rot<int32_t, false>), SetI); 87 88 // java.lang.Integer.rotateLeft(II)I 89 BINARY_II_INTRINSIC(MterpIntegerRotateLeft, (Rot<int32_t, true>), SetI); 90 91 // java.lang.Integer.signum(I)I 92 UNARY_INTRINSIC(MterpIntegerSignum, Signum, GetVReg, SetI); 93 94 // java.lang.Long.reverse(I)I 95 UNARY_INTRINSIC(MterpLongReverse, ReverseBits64, GetVRegLong, SetJ); 96 97 // java.lang.Long.reverseBytes(J)J 98 UNARY_INTRINSIC(MterpLongReverseBytes, BSWAP, GetVRegLong, SetJ); 99 100 // java.lang.Long.bitCount(J)I 101 UNARY_INTRINSIC(MterpLongBitCount, POPCOUNT, GetVRegLong, SetI); 102 103 // java.lang.Long.compare(JJ)I 104 BINARY_JJ_INTRINSIC(MterpLongCompare, Compare, SetI); 105 106 // java.lang.Long.highestOneBit(J)J 107 UNARY_INTRINSIC(MterpLongHighestOneBit, HighestOneBitValue, GetVRegLong, SetJ); 108 109 // java.lang.Long.lowestOneBit(J)J 110 UNARY_INTRINSIC(MterpLongLowestOneBit, LowestOneBitValue, GetVRegLong, SetJ); 111 112 // java.lang.Long.numberOfLeadingZeros(J)I 113 UNARY_INTRINSIC(MterpLongNumberOfLeadingZeros, JAVASTYLE_CLZ, GetVRegLong, SetJ); 114 115 // java.lang.Long.numberOfTrailingZeros(J)I 116 UNARY_INTRINSIC(MterpLongNumberOfTrailingZeros, JAVASTYLE_CTZ, GetVRegLong, SetJ); 117 118 // java.lang.Long.rotateRight(JI)J 119 BINARY_JJ_INTRINSIC(MterpLongRotateRight, (Rot<int64_t, false>), SetJ); 120 121 // java.lang.Long.rotateLeft(JI)J 122 BINARY_JJ_INTRINSIC(MterpLongRotateLeft, (Rot<int64_t, true>), SetJ); 123 124 // java.lang.Long.signum(J)I 125 UNARY_INTRINSIC(MterpLongSignum, Signum, GetVRegLong, SetI); 126 127 // java.lang.Short.reverseBytes(S)S 128 UNARY_INTRINSIC(MterpShortReverseBytes, BSWAP, GetVRegShort, SetS); 129 130 // java.lang.Math.min(II)I 131 BINARY_II_INTRINSIC(MterpMathMinIntInt, std::min, SetI); 132 133 // java.lang.Math.min(JJ)J 134 BINARY_JJ_INTRINSIC(MterpMathMinLongLong, std::min, SetJ); 135 136 // java.lang.Math.max(II)I 137 BINARY_II_INTRINSIC(MterpMathMaxIntInt, std::max, SetI); 138 139 // java.lang.Math.max(JJ)J 140 BINARY_JJ_INTRINSIC(MterpMathMaxLongLong, std::max, SetJ); 141 142 // java.lang.Math.abs(I)I 143 UNARY_INTRINSIC(MterpMathAbsInt, std::abs, GetVReg, SetI); 144 145 // java.lang.Math.abs(J)J 146 UNARY_INTRINSIC(MterpMathAbsLong, std::abs, GetVRegLong, SetJ); 147 148 // java.lang.Math.abs(F)F 149 UNARY_INTRINSIC(MterpMathAbsFloat, 0x7fffffff&, GetVReg, SetI); 150 151 // java.lang.Math.abs(D)D 152 UNARY_INTRINSIC(MterpMathAbsDouble, INT64_C(0x7fffffffffffffff)&, GetVRegLong, SetJ); 153 154 // java.lang.Math.sqrt(D)D 155 UNARY_INTRINSIC(MterpMathSqrt, std::sqrt, GetVRegDouble, SetD); 156 157 // java.lang.Math.ceil(D)D 158 UNARY_INTRINSIC(MterpMathCeil, std::ceil, GetVRegDouble, SetD); 159 160 // java.lang.Math.floor(D)D 161 UNARY_INTRINSIC(MterpMathFloor, std::floor, GetVRegDouble, SetD); 162 163 // java.lang.Math.sin(D)D 164 UNARY_INTRINSIC(MterpMathSin, std::sin, GetVRegDouble, SetD); 165 166 // java.lang.Math.cos(D)D 167 UNARY_INTRINSIC(MterpMathCos, std::cos, GetVRegDouble, SetD); 168 169 // java.lang.Math.tan(D)D 170 UNARY_INTRINSIC(MterpMathTan, std::tan, GetVRegDouble, SetD); 171 172 // java.lang.Math.asin(D)D 173 UNARY_INTRINSIC(MterpMathAsin, std::asin, GetVRegDouble, SetD); 174 175 // java.lang.Math.acos(D)D 176 UNARY_INTRINSIC(MterpMathAcos, std::acos, GetVRegDouble, SetD); 177 178 // java.lang.Math.atan(D)D 179 UNARY_INTRINSIC(MterpMathAtan, std::atan, GetVRegDouble, SetD); 180 181 // java.lang.String.charAt(I)C 182 static 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 206 static 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) \ 223 static 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 241 STRING_INDEXOF_INTRINSIC(StringIndexOf, 0); 242 243 // java.lang.String.indexOf(II)I 244 STRING_INDEXOF_INTRINSIC(StringIndexOfAfter, shadow_frame->GetVReg(arg[2])); 245 246 #define SIMPLE_STRING_INTRINSIC(name, operation) \ 247 static 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 260 SIMPLE_STRING_INTRINSIC(StringIsEmpty, SetZ(str->GetLength() == 0)) 261 262 // java.lang.String.length()I 263 SIMPLE_STRING_INTRINSIC(StringLength, SetI(str->GetLength())) 264 265 // java.lang.String.getCharsNoCheck(II[CI)V 266 static 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 294 static 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 // Macro to help keep track of what's left to implement. 327 #define UNIMPLEMENTED_CASE(name) \ 328 case Intrinsics::k##name: \ 329 res = false; \ 330 break; 331 332 #define INTRINSIC_CASE(name) \ 333 case Intrinsics::k##name: \ 334 res = Mterp##name(shadow_frame, inst, inst_data, result_register); \ 335 break; 336 337 bool MterpHandleIntrinsic(ShadowFrame* shadow_frame, 338 ArtMethod* const called_method, 339 const Instruction* inst, 340 uint16_t inst_data, 341 JValue* result_register) 342 REQUIRES_SHARED(Locks::mutator_lock_) { 343 Intrinsics intrinsic = static_cast<Intrinsics>(called_method->GetIntrinsic()); 344 bool res = false; // Assume failure 345 switch (intrinsic) { 346 UNIMPLEMENTED_CASE(DoubleDoubleToRawLongBits /* (D)J */) 347 UNIMPLEMENTED_CASE(DoubleDoubleToLongBits /* (D)J */) 348 UNIMPLEMENTED_CASE(DoubleIsInfinite /* (D)Z */) 349 UNIMPLEMENTED_CASE(DoubleIsNaN /* (D)Z */) 350 UNIMPLEMENTED_CASE(DoubleLongBitsToDouble /* (J)D */) 351 UNIMPLEMENTED_CASE(FloatFloatToRawIntBits /* (F)I */) 352 UNIMPLEMENTED_CASE(FloatFloatToIntBits /* (F)I */) 353 UNIMPLEMENTED_CASE(FloatIsInfinite /* (F)Z */) 354 UNIMPLEMENTED_CASE(FloatIsNaN /* (F)Z */) 355 UNIMPLEMENTED_CASE(FloatIntBitsToFloat /* (I)F */) 356 INTRINSIC_CASE(IntegerReverse) 357 INTRINSIC_CASE(IntegerReverseBytes) 358 INTRINSIC_CASE(IntegerBitCount) 359 INTRINSIC_CASE(IntegerCompare) 360 INTRINSIC_CASE(IntegerHighestOneBit) 361 INTRINSIC_CASE(IntegerLowestOneBit) 362 INTRINSIC_CASE(IntegerNumberOfLeadingZeros) 363 INTRINSIC_CASE(IntegerNumberOfTrailingZeros) 364 INTRINSIC_CASE(IntegerRotateRight) 365 INTRINSIC_CASE(IntegerRotateLeft) 366 INTRINSIC_CASE(IntegerSignum) 367 INTRINSIC_CASE(LongReverse) 368 INTRINSIC_CASE(LongReverseBytes) 369 INTRINSIC_CASE(LongBitCount) 370 INTRINSIC_CASE(LongCompare) 371 INTRINSIC_CASE(LongHighestOneBit) 372 INTRINSIC_CASE(LongLowestOneBit) 373 INTRINSIC_CASE(LongNumberOfLeadingZeros) 374 INTRINSIC_CASE(LongNumberOfTrailingZeros) 375 INTRINSIC_CASE(LongRotateRight) 376 INTRINSIC_CASE(LongRotateLeft) 377 INTRINSIC_CASE(LongSignum) 378 INTRINSIC_CASE(ShortReverseBytes) 379 INTRINSIC_CASE(MathAbsDouble) 380 INTRINSIC_CASE(MathAbsFloat) 381 INTRINSIC_CASE(MathAbsLong) 382 INTRINSIC_CASE(MathAbsInt) 383 UNIMPLEMENTED_CASE(MathMinDoubleDouble /* (DD)D */) 384 UNIMPLEMENTED_CASE(MathMinFloatFloat /* (FF)F */) 385 INTRINSIC_CASE(MathMinLongLong) 386 INTRINSIC_CASE(MathMinIntInt) 387 UNIMPLEMENTED_CASE(MathMaxDoubleDouble /* (DD)D */) 388 UNIMPLEMENTED_CASE(MathMaxFloatFloat /* (FF)F */) 389 INTRINSIC_CASE(MathMaxLongLong) 390 INTRINSIC_CASE(MathMaxIntInt) 391 INTRINSIC_CASE(MathCos) 392 INTRINSIC_CASE(MathSin) 393 INTRINSIC_CASE(MathAcos) 394 INTRINSIC_CASE(MathAsin) 395 INTRINSIC_CASE(MathAtan) 396 UNIMPLEMENTED_CASE(MathAtan2 /* (DD)D */) 397 UNIMPLEMENTED_CASE(MathCbrt /* (D)D */) 398 UNIMPLEMENTED_CASE(MathCosh /* (D)D */) 399 UNIMPLEMENTED_CASE(MathExp /* (D)D */) 400 UNIMPLEMENTED_CASE(MathExpm1 /* (D)D */) 401 UNIMPLEMENTED_CASE(MathHypot /* (DD)D */) 402 UNIMPLEMENTED_CASE(MathLog /* (D)D */) 403 UNIMPLEMENTED_CASE(MathLog10 /* (D)D */) 404 UNIMPLEMENTED_CASE(MathNextAfter /* (DD)D */) 405 UNIMPLEMENTED_CASE(MathSinh /* (D)D */) 406 INTRINSIC_CASE(MathTan) 407 UNIMPLEMENTED_CASE(MathTanh /* (D)D */) 408 INTRINSIC_CASE(MathSqrt) 409 INTRINSIC_CASE(MathCeil) 410 INTRINSIC_CASE(MathFloor) 411 UNIMPLEMENTED_CASE(MathRint /* (D)D */) 412 UNIMPLEMENTED_CASE(MathRoundDouble /* (D)J */) 413 UNIMPLEMENTED_CASE(MathRoundFloat /* (F)I */) 414 UNIMPLEMENTED_CASE(SystemArrayCopyChar /* ([CI[CII)V */) 415 UNIMPLEMENTED_CASE(SystemArrayCopy /* (Ljava/lang/Object;ILjava/lang/Object;II)V */) 416 UNIMPLEMENTED_CASE(ThreadCurrentThread /* ()Ljava/lang/Thread; */) 417 UNIMPLEMENTED_CASE(MemoryPeekByte /* (J)B */) 418 UNIMPLEMENTED_CASE(MemoryPeekIntNative /* (J)I */) 419 UNIMPLEMENTED_CASE(MemoryPeekLongNative /* (J)J */) 420 UNIMPLEMENTED_CASE(MemoryPeekShortNative /* (J)S */) 421 UNIMPLEMENTED_CASE(MemoryPokeByte /* (JB)V */) 422 UNIMPLEMENTED_CASE(MemoryPokeIntNative /* (JI)V */) 423 UNIMPLEMENTED_CASE(MemoryPokeLongNative /* (JJ)V */) 424 UNIMPLEMENTED_CASE(MemoryPokeShortNative /* (JS)V */) 425 INTRINSIC_CASE(StringCharAt) 426 INTRINSIC_CASE(StringCompareTo) 427 INTRINSIC_CASE(StringEquals) 428 INTRINSIC_CASE(StringGetCharsNoCheck) 429 INTRINSIC_CASE(StringIndexOf) 430 INTRINSIC_CASE(StringIndexOfAfter) 431 UNIMPLEMENTED_CASE(StringStringIndexOf /* (Ljava/lang/String;)I */) 432 UNIMPLEMENTED_CASE(StringStringIndexOfAfter /* (Ljava/lang/String;I)I */) 433 INTRINSIC_CASE(StringIsEmpty) 434 INTRINSIC_CASE(StringLength) 435 UNIMPLEMENTED_CASE(StringNewStringFromBytes /* ([BIII)Ljava/lang/String; */) 436 UNIMPLEMENTED_CASE(StringNewStringFromChars /* (II[C)Ljava/lang/String; */) 437 UNIMPLEMENTED_CASE(StringNewStringFromString /* (Ljava/lang/String;)Ljava/lang/String; */) 438 UNIMPLEMENTED_CASE(StringBufferAppend /* (Ljava/lang/String;)Ljava/lang/StringBuffer; */) 439 UNIMPLEMENTED_CASE(StringBufferLength /* ()I */) 440 UNIMPLEMENTED_CASE(StringBufferToString /* ()Ljava/lang/String; */) 441 UNIMPLEMENTED_CASE(StringBuilderAppend /* (Ljava/lang/String;)Ljava/lang/StringBuilder; */) 442 UNIMPLEMENTED_CASE(StringBuilderLength /* ()I */) 443 UNIMPLEMENTED_CASE(StringBuilderToString /* ()Ljava/lang/String; */) 444 UNIMPLEMENTED_CASE(UnsafeCASInt /* (Ljava/lang/Object;JII)Z */) 445 UNIMPLEMENTED_CASE(UnsafeCASLong /* (Ljava/lang/Object;JJJ)Z */) 446 UNIMPLEMENTED_CASE(UnsafeCASObject /* (Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z */) 447 UNIMPLEMENTED_CASE(UnsafeGet /* (Ljava/lang/Object;J)I */) 448 UNIMPLEMENTED_CASE(UnsafeGetVolatile /* (Ljava/lang/Object;J)I */) 449 UNIMPLEMENTED_CASE(UnsafeGetObject /* (Ljava/lang/Object;J)Ljava/lang/Object; */) 450 UNIMPLEMENTED_CASE(UnsafeGetObjectVolatile /* (Ljava/lang/Object;J)Ljava/lang/Object; */) 451 UNIMPLEMENTED_CASE(UnsafeGetLong /* (Ljava/lang/Object;J)J */) 452 UNIMPLEMENTED_CASE(UnsafeGetLongVolatile /* (Ljava/lang/Object;J)J */) 453 UNIMPLEMENTED_CASE(UnsafePut /* (Ljava/lang/Object;JI)V */) 454 UNIMPLEMENTED_CASE(UnsafePutOrdered /* (Ljava/lang/Object;JI)V */) 455 UNIMPLEMENTED_CASE(UnsafePutVolatile /* (Ljava/lang/Object;JI)V */) 456 UNIMPLEMENTED_CASE(UnsafePutObject /* (Ljava/lang/Object;JLjava/lang/Object;)V */) 457 UNIMPLEMENTED_CASE(UnsafePutObjectOrdered /* (Ljava/lang/Object;JLjava/lang/Object;)V */) 458 UNIMPLEMENTED_CASE(UnsafePutObjectVolatile /* (Ljava/lang/Object;JLjava/lang/Object;)V */) 459 UNIMPLEMENTED_CASE(UnsafePutLong /* (Ljava/lang/Object;JJ)V */) 460 UNIMPLEMENTED_CASE(UnsafePutLongOrdered /* (Ljava/lang/Object;JJ)V */) 461 UNIMPLEMENTED_CASE(UnsafePutLongVolatile /* (Ljava/lang/Object;JJ)V */) 462 UNIMPLEMENTED_CASE(UnsafeGetAndAddInt /* (Ljava/lang/Object;JI)I */) 463 UNIMPLEMENTED_CASE(UnsafeGetAndAddLong /* (Ljava/lang/Object;JJ)J */) 464 UNIMPLEMENTED_CASE(UnsafeGetAndSetInt /* (Ljava/lang/Object;JI)I */) 465 UNIMPLEMENTED_CASE(UnsafeGetAndSetLong /* (Ljava/lang/Object;JJ)J */) 466 UNIMPLEMENTED_CASE(UnsafeGetAndSetObject /* (Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object; */) 467 UNIMPLEMENTED_CASE(UnsafeLoadFence /* ()V */) 468 UNIMPLEMENTED_CASE(UnsafeStoreFence /* ()V */) 469 UNIMPLEMENTED_CASE(UnsafeFullFence /* ()V */) 470 UNIMPLEMENTED_CASE(ReferenceGetReferent /* ()Ljava/lang/Object; */) 471 UNIMPLEMENTED_CASE(IntegerValueOf /* (I)Ljava/lang/Integer; */) 472 UNIMPLEMENTED_CASE(ThreadInterrupted /* ()Z */) 473 case Intrinsics::kNone: 474 res = false; 475 break; 476 // Note: no default case to ensure we catch any newly added intrinsics. 477 } 478 return res; 479 } 480 481 } // namespace interpreter 482 } // namespace art 483