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