• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
MterpStringCharAt(ShadowFrame * shadow_frame,const Instruction * inst,uint16_t inst_data,JValue * result_register)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
MterpStringCompareTo(ShadowFrame * shadow_frame,const Instruction * inst,uint16_t inst_data,JValue * result_register)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
MterpStringGetCharsNoCheck(ShadowFrame * shadow_frame,const Instruction * inst,uint16_t inst_data,JValue * result_register ATTRIBUTE_UNUSED)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
MterpStringEquals(ShadowFrame * shadow_frame,const Instruction * inst,uint16_t inst_data,JValue * result_register)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 
MterpHandleIntrinsic(ShadowFrame * shadow_frame,ArtMethod * const called_method,const Instruction * inst,uint16_t inst_data,JValue * result_register)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     case Intrinsics::kNone:
473       res = false;
474       break;
475     // Note: no default case to ensure we catch any newly added intrinsics.
476   }
477   return res;
478 }
479 
480 }  // namespace interpreter
481 }  // namespace art
482