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