blob: f6069785a21d8af40388ff63140340437a6c4ae5 [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 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
Igor Murashkin6918bf12015-09-27 19:19:06 -070017#include "base/stl_util.h" // MakeUnique
Alex Lighteb7c1442015-08-31 13:17:42 -070018#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020019#include "interpreter_common.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070020#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020021
Igor Murashkin6918bf12015-09-27 19:19:06 -070022#include <memory> // std::unique_ptr
23
Sebastien Hertz8ece0502013-08-07 11:26:41 +020024namespace art {
25namespace interpreter {
26
27#define HANDLE_PENDING_EXCEPTION() \
28 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020029 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070030 self->AllowThreadSuspension(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020031 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, \
32 inst->GetDexPc(insns), \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020033 instrumentation); \
34 if (found_dex_pc == DexFile::kDexNoIndex) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070035 /* Structured locking is to be enforced for abnormal termination, too. */ \
36 shadow_frame.GetLockCountData(). \
37 CheckAllMonitorsReleasedOrThrow<do_assignability_check>(self); \
buzbee1452bee2015-03-06 14:43:04 -080038 if (interpret_one_instruction) { \
39 shadow_frame.SetDexPC(DexFile::kDexNoIndex); \
40 } \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020041 return JValue(); /* Handled in caller. */ \
42 } else { \
43 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); \
44 inst = inst->RelativeAt(displacement); \
45 } \
46 } while (false)
47
48#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
49 do { \
50 if (UNLIKELY(_is_exception_pending)) { \
51 HANDLE_PENDING_EXCEPTION(); \
52 } else { \
53 inst = inst->_next_function(); \
54 } \
55 } while (false)
56
Andreas Gampe03ec9302015-08-27 17:41:47 -070057#define HANDLE_MONITOR_CHECKS() \
58 if (!shadow_frame.GetLockCountData(). \
59 CheckAllMonitorsReleasedOrThrow<do_assignability_check>(self)) { \
60 HANDLE_PENDING_EXCEPTION(); \
61 }
62
Sebastien Hertz8ece0502013-08-07 11:26:41 +020063// Code to run before each dex instruction.
Sebastien Hertz8379b222014-02-24 17:38:15 +010064#define PREAMBLE() \
65 do { \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +020066 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
Sebastien Hertz8379b222014-02-24 17:38:15 +010067 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), \
68 shadow_frame.GetMethod(), dex_pc); \
69 } \
70 } while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020071
Nicolas Geoffray81f0f952016-01-20 16:25:19 +000072#define BRANCH_INSTRUMENTATION(offset) \
Nicolas Geoffray3108daf2015-11-24 16:32:33 +000073 do { \
Nicolas Geoffray81f0f952016-01-20 16:25:19 +000074 instrumentation->Branch(self, shadow_frame.GetMethod(), dex_pc, offset); \
Nicolas Geoffray3108daf2015-11-24 16:32:33 +000075 } while (false)
76
Igor Murashkin158f35c2015-06-10 15:55:30 -070077static bool IsExperimentalInstructionEnabled(const Instruction *inst) {
78 DCHECK(inst->IsExperimental());
Alex Lighteb7c1442015-08-31 13:17:42 -070079 return Runtime::Current()->AreExperimentalFlagsEnabled(ExperimentalFlags::kLambdas);
Igor Murashkin158f35c2015-06-10 15:55:30 -070080}
81
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010082template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -080083JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -080084 ShadowFrame& shadow_frame, JValue result_register,
85 bool interpret_one_instruction) {
Igor Murashkinc449e8b2015-06-10 15:56:42 -070086 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020087 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
88 LOG(FATAL) << "Invalid shadow frame for interpreter use";
89 return JValue();
90 }
91 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020092
93 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -070094 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020095 const uint16_t* const insns = code_item->insns_;
96 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020097 uint16_t inst_data;
Igor Murashkin6918bf12015-09-27 19:19:06 -070098
99 // TODO: collapse capture-variable+create-lambda into one opcode, then we won't need
100 // to keep this live for the scope of the entire function call.
101 std::unique_ptr<lambda::ClosureBuilder> lambda_closure_builder;
102 size_t lambda_captured_variable_index = 0;
buzbee1452bee2015-03-06 14:43:04 -0800103 do {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200104 dex_pc = inst->GetDexPc(insns);
105 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800106 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200107 inst_data = inst->Fetch16(0);
108 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200109 case Instruction::NOP:
110 PREAMBLE();
111 inst = inst->Next_1xx();
112 break;
113 case Instruction::MOVE:
114 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200115 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
116 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200117 inst = inst->Next_1xx();
118 break;
119 case Instruction::MOVE_FROM16:
120 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200121 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200122 shadow_frame.GetVReg(inst->VRegB_22x()));
123 inst = inst->Next_2xx();
124 break;
125 case Instruction::MOVE_16:
126 PREAMBLE();
127 shadow_frame.SetVReg(inst->VRegA_32x(),
128 shadow_frame.GetVReg(inst->VRegB_32x()));
129 inst = inst->Next_3xx();
130 break;
131 case Instruction::MOVE_WIDE:
132 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200133 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
134 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200135 inst = inst->Next_1xx();
136 break;
137 case Instruction::MOVE_WIDE_FROM16:
138 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200139 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200140 shadow_frame.GetVRegLong(inst->VRegB_22x()));
141 inst = inst->Next_2xx();
142 break;
143 case Instruction::MOVE_WIDE_16:
144 PREAMBLE();
145 shadow_frame.SetVRegLong(inst->VRegA_32x(),
146 shadow_frame.GetVRegLong(inst->VRegB_32x()));
147 inst = inst->Next_3xx();
148 break;
149 case Instruction::MOVE_OBJECT:
150 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200151 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
152 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200153 inst = inst->Next_1xx();
154 break;
155 case Instruction::MOVE_OBJECT_FROM16:
156 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200157 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200158 shadow_frame.GetVRegReference(inst->VRegB_22x()));
159 inst = inst->Next_2xx();
160 break;
161 case Instruction::MOVE_OBJECT_16:
162 PREAMBLE();
163 shadow_frame.SetVRegReference(inst->VRegA_32x(),
164 shadow_frame.GetVRegReference(inst->VRegB_32x()));
165 inst = inst->Next_3xx();
166 break;
167 case Instruction::MOVE_RESULT:
168 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200169 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200170 inst = inst->Next_1xx();
171 break;
172 case Instruction::MOVE_RESULT_WIDE:
173 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200174 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200175 inst = inst->Next_1xx();
176 break;
177 case Instruction::MOVE_RESULT_OBJECT:
178 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200179 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200180 inst = inst->Next_1xx();
181 break;
182 case Instruction::MOVE_EXCEPTION: {
183 PREAMBLE();
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000184 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100185 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200186 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200187 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200188 inst = inst->Next_1xx();
189 break;
190 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700191 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200192 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200193 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700194 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700195 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200196 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200197 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200198 shadow_frame.GetMethod(), inst->GetDexPc(insns),
199 result);
200 }
buzbee1452bee2015-03-06 14:43:04 -0800201 if (interpret_one_instruction) {
202 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
203 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200204 return result;
205 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700206 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200207 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700208 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200209 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700210 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700211 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200212 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200213 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200214 shadow_frame.GetMethod(), inst->GetDexPc(insns),
215 result);
216 }
buzbee1452bee2015-03-06 14:43:04 -0800217 if (interpret_one_instruction) {
218 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
219 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200220 return result;
221 }
222 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200223 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200224 JValue result;
225 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200226 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700227 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700228 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200229 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200230 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200231 shadow_frame.GetMethod(), inst->GetDexPc(insns),
232 result);
233 }
buzbee1452bee2015-03-06 14:43:04 -0800234 if (interpret_one_instruction) {
235 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
236 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200237 return result;
238 }
239 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200240 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200241 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200242 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700243 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700244 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200245 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200246 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200247 shadow_frame.GetMethod(), inst->GetDexPc(insns),
248 result);
249 }
buzbee1452bee2015-03-06 14:43:04 -0800250 if (interpret_one_instruction) {
251 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
252 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200253 return result;
254 }
255 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200256 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200257 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700258 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700259 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700260 const size_t ref_idx = inst->VRegA_11x(inst_data);
261 Object* obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700262 if (do_assignability_check && obj_result != nullptr) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100263 size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
264 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
265 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700266 // Re-load since it might have moved.
267 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700268 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700269 // Return the pending exception.
270 HANDLE_PENDING_EXCEPTION();
271 }
272 if (!obj_result->VerifierInstanceOf(return_type)) {
273 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700274 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000275 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700276 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700277 obj_result->GetClass()->GetDescriptor(&temp1),
278 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700279 HANDLE_PENDING_EXCEPTION();
280 }
281 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700282 result.SetL(obj_result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200283 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200284 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200285 shadow_frame.GetMethod(), inst->GetDexPc(insns),
286 result);
287 }
buzbee1452bee2015-03-06 14:43:04 -0800288 if (interpret_one_instruction) {
289 shadow_frame.SetDexPC(DexFile::kDexNoIndex);
290 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200291 return result;
292 }
293 case Instruction::CONST_4: {
294 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200295 uint4_t dst = inst->VRegA_11n(inst_data);
296 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200297 shadow_frame.SetVReg(dst, val);
298 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700299 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200300 }
301 inst = inst->Next_1xx();
302 break;
303 }
304 case Instruction::CONST_16: {
305 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200306 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200307 int16_t val = inst->VRegB_21s();
308 shadow_frame.SetVReg(dst, val);
309 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700310 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200311 }
312 inst = inst->Next_2xx();
313 break;
314 }
315 case Instruction::CONST: {
316 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200317 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200318 int32_t val = inst->VRegB_31i();
319 shadow_frame.SetVReg(dst, val);
320 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700321 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200322 }
323 inst = inst->Next_3xx();
324 break;
325 }
326 case Instruction::CONST_HIGH16: {
327 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200328 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200329 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
330 shadow_frame.SetVReg(dst, val);
331 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700332 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200333 }
334 inst = inst->Next_2xx();
335 break;
336 }
337 case Instruction::CONST_WIDE_16:
338 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200339 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200340 inst = inst->Next_2xx();
341 break;
342 case Instruction::CONST_WIDE_32:
343 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200344 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200345 inst = inst->Next_3xx();
346 break;
347 case Instruction::CONST_WIDE:
348 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200349 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200350 inst = inst->Next_51l();
351 break;
352 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200353 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200354 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200355 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
356 inst = inst->Next_2xx();
357 break;
358 case Instruction::CONST_STRING: {
359 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700360 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700361 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200362 HANDLE_PENDING_EXCEPTION();
363 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200364 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200365 inst = inst->Next_2xx();
366 }
367 break;
368 }
369 case Instruction::CONST_STRING_JUMBO: {
370 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700371 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700372 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200373 HANDLE_PENDING_EXCEPTION();
374 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200375 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200376 inst = inst->Next_3xx();
377 }
378 break;
379 }
380 case Instruction::CONST_CLASS: {
381 PREAMBLE();
382 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
383 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700384 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200385 HANDLE_PENDING_EXCEPTION();
386 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200387 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200388 inst = inst->Next_2xx();
389 }
390 break;
391 }
392 case Instruction::MONITOR_ENTER: {
393 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200394 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700395 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000396 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200397 HANDLE_PENDING_EXCEPTION();
398 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700399 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200400 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
401 }
402 break;
403 }
404 case Instruction::MONITOR_EXIT: {
405 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200406 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700407 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000408 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200409 HANDLE_PENDING_EXCEPTION();
410 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700411 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200412 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
413 }
414 break;
415 }
416 case Instruction::CHECK_CAST: {
417 PREAMBLE();
418 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
419 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700420 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200421 HANDLE_PENDING_EXCEPTION();
422 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200423 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700424 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200425 ThrowClassCastException(c, obj->GetClass());
426 HANDLE_PENDING_EXCEPTION();
427 } else {
428 inst = inst->Next_2xx();
429 }
430 }
431 break;
432 }
433 case Instruction::INSTANCE_OF: {
434 PREAMBLE();
435 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
436 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700437 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200438 HANDLE_PENDING_EXCEPTION();
439 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200440 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700441 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
442 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200443 inst = inst->Next_2xx();
444 }
445 break;
446 }
447 case Instruction::ARRAY_LENGTH: {
448 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200449 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700450 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000451 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200452 HANDLE_PENDING_EXCEPTION();
453 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200454 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200455 inst = inst->Next_1xx();
456 }
457 break;
458 }
459 case Instruction::NEW_INSTANCE: {
460 PREAMBLE();
Jeff Hao848f70a2014-01-15 13:49:50 -0800461 Object* obj = nullptr;
462 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
463 self, false, do_access_check);
464 if (LIKELY(c != nullptr)) {
465 if (UNLIKELY(c->IsStringClass())) {
466 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
467 mirror::SetStringCountVisitor visitor(0);
468 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
469 } else {
470 obj = AllocObjectFromCode<do_access_check, true>(
471 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
472 Runtime::Current()->GetHeap()->GetCurrentAllocator());
473 }
474 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700475 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200476 HANDLE_PENDING_EXCEPTION();
477 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200478 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700479 // Don't allow finalizable objects to be allocated during a transaction since these can't
480 // be finalized without a started runtime.
481 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200482 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
483 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700484 HANDLE_PENDING_EXCEPTION();
485 break;
486 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200487 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200488 inst = inst->Next_2xx();
489 }
490 break;
491 }
492 case Instruction::NEW_ARRAY: {
493 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200494 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800495 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800496 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800497 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700498 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200499 HANDLE_PENDING_EXCEPTION();
500 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200501 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200502 inst = inst->Next_2xx();
503 }
504 break;
505 }
506 case Instruction::FILLED_NEW_ARRAY: {
507 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100508 bool success =
509 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
510 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200511 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
512 break;
513 }
514 case Instruction::FILLED_NEW_ARRAY_RANGE: {
515 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100516 bool success =
517 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
518 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200519 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
520 break;
521 }
522 case Instruction::FILL_ARRAY_DATA: {
523 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200524 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
525 const Instruction::ArrayDataPayload* payload =
526 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Ian Rogers832336b2014-10-08 15:35:22 -0700527 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
528 bool success = FillArrayData(obj, payload);
529 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200530 HANDLE_PENDING_EXCEPTION();
531 break;
532 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100533 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700534 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100535 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200536 inst = inst->Next_3xx();
537 break;
538 }
539 case Instruction::THROW: {
540 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200541 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700542 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000543 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700544 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
545 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700546 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000547 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700548 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700549 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200550 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000551 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200552 }
553 HANDLE_PENDING_EXCEPTION();
554 break;
555 }
556 case Instruction::GOTO: {
557 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200558 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000559 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200560 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700561 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200562 }
563 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200564 break;
565 }
566 case Instruction::GOTO_16: {
567 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200568 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000569 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200570 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700571 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200572 }
573 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200574 break;
575 }
576 case Instruction::GOTO_32: {
577 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200578 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000579 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200580 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700581 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200582 }
583 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200584 break;
585 }
586 case Instruction::PACKED_SWITCH: {
587 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200588 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000589 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200590 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700591 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200592 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200593 inst = inst->RelativeAt(offset);
594 break;
595 }
596 case Instruction::SPARSE_SWITCH: {
597 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200598 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000599 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200600 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700601 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200602 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200603 inst = inst->RelativeAt(offset);
604 break;
605 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700606
607#if defined(__clang__)
608#pragma clang diagnostic push
609#pragma clang diagnostic ignored "-Wfloat-equal"
610#endif
611
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200612 case Instruction::CMPL_FLOAT: {
613 PREAMBLE();
614 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
615 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
616 int32_t result;
617 if (val1 > val2) {
618 result = 1;
619 } else if (val1 == val2) {
620 result = 0;
621 } else {
622 result = -1;
623 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200624 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200625 inst = inst->Next_2xx();
626 break;
627 }
628 case Instruction::CMPG_FLOAT: {
629 PREAMBLE();
630 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
631 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
632 int32_t result;
633 if (val1 < val2) {
634 result = -1;
635 } else if (val1 == val2) {
636 result = 0;
637 } else {
638 result = 1;
639 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200640 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200641 inst = inst->Next_2xx();
642 break;
643 }
644 case Instruction::CMPL_DOUBLE: {
645 PREAMBLE();
646 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
647 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
648 int32_t result;
649 if (val1 > val2) {
650 result = 1;
651 } else if (val1 == val2) {
652 result = 0;
653 } else {
654 result = -1;
655 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200656 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200657 inst = inst->Next_2xx();
658 break;
659 }
660
661 case Instruction::CMPG_DOUBLE: {
662 PREAMBLE();
663 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
664 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
665 int32_t result;
666 if (val1 < val2) {
667 result = -1;
668 } else if (val1 == val2) {
669 result = 0;
670 } else {
671 result = 1;
672 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200673 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200674 inst = inst->Next_2xx();
675 break;
676 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700677
678#if defined(__clang__)
679#pragma clang diagnostic pop
680#endif
681
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200682 case Instruction::CMP_LONG: {
683 PREAMBLE();
684 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
685 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
686 int32_t result;
687 if (val1 > val2) {
688 result = 1;
689 } else if (val1 == val2) {
690 result = 0;
691 } else {
692 result = -1;
693 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200694 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200695 inst = inst->Next_2xx();
696 break;
697 }
698 case Instruction::IF_EQ: {
699 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700700 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
701 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200702 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000703 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200704 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700705 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200706 }
707 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200708 } else {
709 inst = inst->Next_2xx();
710 }
711 break;
712 }
713 case Instruction::IF_NE: {
714 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700715 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
716 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200717 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000718 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200719 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700720 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200721 }
722 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200723 } else {
724 inst = inst->Next_2xx();
725 }
726 break;
727 }
728 case Instruction::IF_LT: {
729 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700730 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
731 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200732 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000733 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200734 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700735 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200736 }
737 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200738 } else {
739 inst = inst->Next_2xx();
740 }
741 break;
742 }
743 case Instruction::IF_GE: {
744 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700745 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
746 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200747 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000748 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200749 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700750 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200751 }
752 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200753 } else {
754 inst = inst->Next_2xx();
755 }
756 break;
757 }
758 case Instruction::IF_GT: {
759 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700760 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
761 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200762 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000763 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200764 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700765 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200766 }
767 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200768 } else {
769 inst = inst->Next_2xx();
770 }
771 break;
772 }
773 case Instruction::IF_LE: {
774 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700775 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
776 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200777 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000778 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200779 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700780 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200781 }
782 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200783 } else {
784 inst = inst->Next_2xx();
785 }
786 break;
787 }
788 case Instruction::IF_EQZ: {
789 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200790 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200791 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000792 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200793 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700794 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200795 }
796 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200797 } else {
798 inst = inst->Next_2xx();
799 }
800 break;
801 }
802 case Instruction::IF_NEZ: {
803 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200804 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200805 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000806 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200807 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700808 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200809 }
810 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200811 } else {
812 inst = inst->Next_2xx();
813 }
814 break;
815 }
816 case Instruction::IF_LTZ: {
817 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200818 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200819 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000820 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200821 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700822 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200823 }
824 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200825 } else {
826 inst = inst->Next_2xx();
827 }
828 break;
829 }
830 case Instruction::IF_GEZ: {
831 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200832 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200833 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000834 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200835 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700836 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200837 }
838 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200839 } else {
840 inst = inst->Next_2xx();
841 }
842 break;
843 }
844 case Instruction::IF_GTZ: {
845 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200846 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200847 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000848 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200849 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700850 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200851 }
852 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200853 } else {
854 inst = inst->Next_2xx();
855 }
856 break;
857 }
858 case Instruction::IF_LEZ: {
859 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200860 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200861 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000862 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200863 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700864 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200865 }
866 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200867 } else {
868 inst = inst->Next_2xx();
869 }
870 break;
871 }
872 case Instruction::AGET_BOOLEAN: {
873 PREAMBLE();
874 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700875 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000876 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200877 HANDLE_PENDING_EXCEPTION();
878 break;
879 }
880 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
881 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700882 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100883 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200884 inst = inst->Next_2xx();
885 } else {
886 HANDLE_PENDING_EXCEPTION();
887 }
888 break;
889 }
890 case Instruction::AGET_BYTE: {
891 PREAMBLE();
892 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700893 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000894 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200895 HANDLE_PENDING_EXCEPTION();
896 break;
897 }
898 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
899 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700900 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100901 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200902 inst = inst->Next_2xx();
903 } else {
904 HANDLE_PENDING_EXCEPTION();
905 }
906 break;
907 }
908 case Instruction::AGET_CHAR: {
909 PREAMBLE();
910 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700911 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000912 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200913 HANDLE_PENDING_EXCEPTION();
914 break;
915 }
916 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
917 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700918 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100919 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200920 inst = inst->Next_2xx();
921 } else {
922 HANDLE_PENDING_EXCEPTION();
923 }
924 break;
925 }
926 case Instruction::AGET_SHORT: {
927 PREAMBLE();
928 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700929 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000930 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200931 HANDLE_PENDING_EXCEPTION();
932 break;
933 }
934 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
935 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700936 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100937 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200938 inst = inst->Next_2xx();
939 } else {
940 HANDLE_PENDING_EXCEPTION();
941 }
942 break;
943 }
944 case Instruction::AGET: {
945 PREAMBLE();
946 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700947 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000948 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200949 HANDLE_PENDING_EXCEPTION();
950 break;
951 }
952 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700953 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
954 auto* array = down_cast<IntArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700955 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100956 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200957 inst = inst->Next_2xx();
958 } else {
959 HANDLE_PENDING_EXCEPTION();
960 }
961 break;
962 }
963 case Instruction::AGET_WIDE: {
964 PREAMBLE();
965 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700966 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000967 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200968 HANDLE_PENDING_EXCEPTION();
969 break;
970 }
971 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700972 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
973 auto* array = down_cast<LongArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700974 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100975 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200976 inst = inst->Next_2xx();
977 } else {
978 HANDLE_PENDING_EXCEPTION();
979 }
980 break;
981 }
982 case Instruction::AGET_OBJECT: {
983 PREAMBLE();
984 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700985 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000986 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200987 HANDLE_PENDING_EXCEPTION();
988 break;
989 }
990 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
991 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700992 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200993 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200994 inst = inst->Next_2xx();
995 } else {
996 HANDLE_PENDING_EXCEPTION();
997 }
998 break;
999 }
1000 case Instruction::APUT_BOOLEAN: {
1001 PREAMBLE();
1002 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001003 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001004 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001005 HANDLE_PENDING_EXCEPTION();
1006 break;
1007 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001008 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001009 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1010 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001011 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001012 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001013 inst = inst->Next_2xx();
1014 } else {
1015 HANDLE_PENDING_EXCEPTION();
1016 }
1017 break;
1018 }
1019 case Instruction::APUT_BYTE: {
1020 PREAMBLE();
1021 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001022 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001023 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001024 HANDLE_PENDING_EXCEPTION();
1025 break;
1026 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001027 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001028 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1029 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001030 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001031 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001032 inst = inst->Next_2xx();
1033 } else {
1034 HANDLE_PENDING_EXCEPTION();
1035 }
1036 break;
1037 }
1038 case Instruction::APUT_CHAR: {
1039 PREAMBLE();
1040 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001041 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001042 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001043 HANDLE_PENDING_EXCEPTION();
1044 break;
1045 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001046 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001047 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1048 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001049 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001050 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001051 inst = inst->Next_2xx();
1052 } else {
1053 HANDLE_PENDING_EXCEPTION();
1054 }
1055 break;
1056 }
1057 case Instruction::APUT_SHORT: {
1058 PREAMBLE();
1059 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001060 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001061 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001062 HANDLE_PENDING_EXCEPTION();
1063 break;
1064 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001065 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001066 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1067 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001068 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001069 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001070 inst = inst->Next_2xx();
1071 } else {
1072 HANDLE_PENDING_EXCEPTION();
1073 }
1074 break;
1075 }
1076 case Instruction::APUT: {
1077 PREAMBLE();
1078 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001079 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001080 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001081 HANDLE_PENDING_EXCEPTION();
1082 break;
1083 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001084 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001085 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001086 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1087 auto* array = down_cast<IntArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001088 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001089 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001090 inst = inst->Next_2xx();
1091 } else {
1092 HANDLE_PENDING_EXCEPTION();
1093 }
1094 break;
1095 }
1096 case Instruction::APUT_WIDE: {
1097 PREAMBLE();
1098 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001099 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001100 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001101 HANDLE_PENDING_EXCEPTION();
1102 break;
1103 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001104 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001105 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001106 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1107 LongArray* array = down_cast<LongArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001108 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001109 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001110 inst = inst->Next_2xx();
1111 } else {
1112 HANDLE_PENDING_EXCEPTION();
1113 }
1114 break;
1115 }
1116 case Instruction::APUT_OBJECT: {
1117 PREAMBLE();
1118 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001119 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001120 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001121 HANDLE_PENDING_EXCEPTION();
1122 break;
1123 }
1124 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001125 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001126 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001127 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001128 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001129 inst = inst->Next_2xx();
1130 } else {
1131 HANDLE_PENDING_EXCEPTION();
1132 }
1133 break;
1134 }
1135 case Instruction::IGET_BOOLEAN: {
1136 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001137 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1138 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001139 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1140 break;
1141 }
1142 case Instruction::IGET_BYTE: {
1143 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001144 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1145 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001146 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1147 break;
1148 }
1149 case Instruction::IGET_CHAR: {
1150 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001151 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1152 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001153 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1154 break;
1155 }
1156 case Instruction::IGET_SHORT: {
1157 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001158 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1159 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001160 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1161 break;
1162 }
1163 case Instruction::IGET: {
1164 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001165 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1166 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001167 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1168 break;
1169 }
1170 case Instruction::IGET_WIDE: {
1171 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001172 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1173 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001174 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1175 break;
1176 }
1177 case Instruction::IGET_OBJECT: {
1178 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001179 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1180 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001181 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1182 break;
1183 }
1184 case Instruction::IGET_QUICK: {
1185 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001186 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001187 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1188 break;
1189 }
1190 case Instruction::IGET_WIDE_QUICK: {
1191 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001192 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001193 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1194 break;
1195 }
1196 case Instruction::IGET_OBJECT_QUICK: {
1197 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001198 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001199 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1200 break;
1201 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001202 case Instruction::IGET_BOOLEAN_QUICK: {
1203 PREAMBLE();
1204 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1205 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1206 break;
1207 }
1208 case Instruction::IGET_BYTE_QUICK: {
1209 PREAMBLE();
1210 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1211 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1212 break;
1213 }
1214 case Instruction::IGET_CHAR_QUICK: {
1215 PREAMBLE();
1216 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1217 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1218 break;
1219 }
1220 case Instruction::IGET_SHORT_QUICK: {
1221 PREAMBLE();
1222 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1223 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1224 break;
1225 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001226 case Instruction::SGET_BOOLEAN: {
1227 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001228 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1229 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001230 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1231 break;
1232 }
1233 case Instruction::SGET_BYTE: {
1234 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001235 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1236 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001237 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1238 break;
1239 }
1240 case Instruction::SGET_CHAR: {
1241 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001242 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1243 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001244 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1245 break;
1246 }
1247 case Instruction::SGET_SHORT: {
1248 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001249 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1250 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001251 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1252 break;
1253 }
1254 case Instruction::SGET: {
1255 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001256 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1257 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001258 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1259 break;
1260 }
1261 case Instruction::SGET_WIDE: {
1262 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001263 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1264 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001265 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1266 break;
1267 }
1268 case Instruction::SGET_OBJECT: {
1269 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001270 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1271 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001272 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1273 break;
1274 }
1275 case Instruction::IPUT_BOOLEAN: {
1276 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001277 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1278 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001279 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1280 break;
1281 }
1282 case Instruction::IPUT_BYTE: {
1283 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001284 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1285 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001286 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1287 break;
1288 }
1289 case Instruction::IPUT_CHAR: {
1290 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001291 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1292 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001293 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1294 break;
1295 }
1296 case Instruction::IPUT_SHORT: {
1297 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001298 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1299 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001300 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1301 break;
1302 }
1303 case Instruction::IPUT: {
1304 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001305 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1306 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001307 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1308 break;
1309 }
1310 case Instruction::IPUT_WIDE: {
1311 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001312 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1313 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001314 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1315 break;
1316 }
1317 case Instruction::IPUT_OBJECT: {
1318 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001319 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1320 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001321 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1322 break;
1323 }
1324 case Instruction::IPUT_QUICK: {
1325 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001326 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1327 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001328 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1329 break;
1330 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001331 case Instruction::IPUT_BOOLEAN_QUICK: {
1332 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001333 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1334 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001335 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1336 break;
1337 }
1338 case Instruction::IPUT_BYTE_QUICK: {
1339 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001340 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1341 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001342 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1343 break;
1344 }
1345 case Instruction::IPUT_CHAR_QUICK: {
1346 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001347 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1348 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001349 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1350 break;
1351 }
1352 case Instruction::IPUT_SHORT_QUICK: {
1353 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001354 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1355 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001356 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1357 break;
1358 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001359 case Instruction::IPUT_WIDE_QUICK: {
1360 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001361 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1362 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001363 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1364 break;
1365 }
1366 case Instruction::IPUT_OBJECT_QUICK: {
1367 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001368 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1369 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001370 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1371 break;
1372 }
1373 case Instruction::SPUT_BOOLEAN: {
1374 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001375 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1376 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001377 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1378 break;
1379 }
1380 case Instruction::SPUT_BYTE: {
1381 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001382 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1383 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001384 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1385 break;
1386 }
1387 case Instruction::SPUT_CHAR: {
1388 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001389 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1390 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001391 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1392 break;
1393 }
1394 case Instruction::SPUT_SHORT: {
1395 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001396 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1397 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001398 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1399 break;
1400 }
1401 case Instruction::SPUT: {
1402 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001403 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1404 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001405 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1406 break;
1407 }
1408 case Instruction::SPUT_WIDE: {
1409 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001410 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1411 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001412 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1413 break;
1414 }
1415 case Instruction::SPUT_OBJECT: {
1416 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001417 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1418 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001419 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1420 break;
1421 }
1422 case Instruction::INVOKE_VIRTUAL: {
1423 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001424 bool success = DoInvoke<kVirtual, false, do_access_check>(
1425 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001426 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1427 break;
1428 }
1429 case Instruction::INVOKE_VIRTUAL_RANGE: {
1430 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001431 bool success = DoInvoke<kVirtual, true, do_access_check>(
1432 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001433 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1434 break;
1435 }
1436 case Instruction::INVOKE_SUPER: {
1437 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001438 bool success = DoInvoke<kSuper, false, do_access_check>(
1439 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001440 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1441 break;
1442 }
1443 case Instruction::INVOKE_SUPER_RANGE: {
1444 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001445 bool success = DoInvoke<kSuper, true, do_access_check>(
1446 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001447 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1448 break;
1449 }
1450 case Instruction::INVOKE_DIRECT: {
1451 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001452 bool success = DoInvoke<kDirect, false, do_access_check>(
1453 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001454 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1455 break;
1456 }
1457 case Instruction::INVOKE_DIRECT_RANGE: {
1458 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001459 bool success = DoInvoke<kDirect, true, do_access_check>(
1460 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001461 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1462 break;
1463 }
1464 case Instruction::INVOKE_INTERFACE: {
1465 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001466 bool success = DoInvoke<kInterface, false, do_access_check>(
1467 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001468 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1469 break;
1470 }
1471 case Instruction::INVOKE_INTERFACE_RANGE: {
1472 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001473 bool success = DoInvoke<kInterface, true, do_access_check>(
1474 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001475 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1476 break;
1477 }
1478 case Instruction::INVOKE_STATIC: {
1479 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001480 bool success = DoInvoke<kStatic, false, do_access_check>(
1481 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001482 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1483 break;
1484 }
1485 case Instruction::INVOKE_STATIC_RANGE: {
1486 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001487 bool success = DoInvoke<kStatic, true, do_access_check>(
1488 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001489 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1490 break;
1491 }
1492 case Instruction::INVOKE_VIRTUAL_QUICK: {
1493 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001494 bool success = DoInvokeVirtualQuick<false>(
1495 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001496 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1497 break;
1498 }
1499 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1500 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001501 bool success = DoInvokeVirtualQuick<true>(
1502 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001503 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1504 break;
1505 }
1506 case Instruction::NEG_INT:
1507 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001508 shadow_frame.SetVReg(
1509 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001510 inst = inst->Next_1xx();
1511 break;
1512 case Instruction::NOT_INT:
1513 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001514 shadow_frame.SetVReg(
1515 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001516 inst = inst->Next_1xx();
1517 break;
1518 case Instruction::NEG_LONG:
1519 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001520 shadow_frame.SetVRegLong(
1521 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001522 inst = inst->Next_1xx();
1523 break;
1524 case Instruction::NOT_LONG:
1525 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001526 shadow_frame.SetVRegLong(
1527 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001528 inst = inst->Next_1xx();
1529 break;
1530 case Instruction::NEG_FLOAT:
1531 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001532 shadow_frame.SetVRegFloat(
1533 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001534 inst = inst->Next_1xx();
1535 break;
1536 case Instruction::NEG_DOUBLE:
1537 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001538 shadow_frame.SetVRegDouble(
1539 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001540 inst = inst->Next_1xx();
1541 break;
1542 case Instruction::INT_TO_LONG:
1543 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001544 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1545 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001546 inst = inst->Next_1xx();
1547 break;
1548 case Instruction::INT_TO_FLOAT:
1549 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001550 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1551 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001552 inst = inst->Next_1xx();
1553 break;
1554 case Instruction::INT_TO_DOUBLE:
1555 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001556 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1557 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001558 inst = inst->Next_1xx();
1559 break;
1560 case Instruction::LONG_TO_INT:
1561 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001562 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1563 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001564 inst = inst->Next_1xx();
1565 break;
1566 case Instruction::LONG_TO_FLOAT:
1567 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001568 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1569 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001570 inst = inst->Next_1xx();
1571 break;
1572 case Instruction::LONG_TO_DOUBLE:
1573 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001574 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1575 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001576 inst = inst->Next_1xx();
1577 break;
1578 case Instruction::FLOAT_TO_INT: {
1579 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001580 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001581 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001582 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001583 inst = inst->Next_1xx();
1584 break;
1585 }
1586 case Instruction::FLOAT_TO_LONG: {
1587 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001588 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001589 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001590 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001591 inst = inst->Next_1xx();
1592 break;
1593 }
1594 case Instruction::FLOAT_TO_DOUBLE:
1595 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001596 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1597 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001598 inst = inst->Next_1xx();
1599 break;
1600 case Instruction::DOUBLE_TO_INT: {
1601 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001602 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001603 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001604 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001605 inst = inst->Next_1xx();
1606 break;
1607 }
1608 case Instruction::DOUBLE_TO_LONG: {
1609 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001610 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001611 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001612 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001613 inst = inst->Next_1xx();
1614 break;
1615 }
1616 case Instruction::DOUBLE_TO_FLOAT:
1617 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001618 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1619 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001620 inst = inst->Next_1xx();
1621 break;
1622 case Instruction::INT_TO_BYTE:
1623 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001624 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1625 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001626 inst = inst->Next_1xx();
1627 break;
1628 case Instruction::INT_TO_CHAR:
1629 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001630 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1631 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001632 inst = inst->Next_1xx();
1633 break;
1634 case Instruction::INT_TO_SHORT:
1635 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001636 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1637 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001638 inst = inst->Next_1xx();
1639 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001640 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001641 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001642 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001643 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1644 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001645 inst = inst->Next_2xx();
1646 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001647 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001648 case Instruction::SUB_INT:
1649 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001650 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001651 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1652 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001653 inst = inst->Next_2xx();
1654 break;
1655 case Instruction::MUL_INT:
1656 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001657 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001658 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1659 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001660 inst = inst->Next_2xx();
1661 break;
1662 case Instruction::DIV_INT: {
1663 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001664 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001665 shadow_frame.GetVReg(inst->VRegB_23x()),
1666 shadow_frame.GetVReg(inst->VRegC_23x()));
1667 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1668 break;
1669 }
1670 case Instruction::REM_INT: {
1671 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001672 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001673 shadow_frame.GetVReg(inst->VRegB_23x()),
1674 shadow_frame.GetVReg(inst->VRegC_23x()));
1675 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1676 break;
1677 }
1678 case Instruction::SHL_INT:
1679 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001680 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001681 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1682 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1683 inst = inst->Next_2xx();
1684 break;
1685 case Instruction::SHR_INT:
1686 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001687 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001688 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1689 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1690 inst = inst->Next_2xx();
1691 break;
1692 case Instruction::USHR_INT:
1693 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001694 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001695 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1696 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1697 inst = inst->Next_2xx();
1698 break;
1699 case Instruction::AND_INT:
1700 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001701 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001702 shadow_frame.GetVReg(inst->VRegB_23x()) &
1703 shadow_frame.GetVReg(inst->VRegC_23x()));
1704 inst = inst->Next_2xx();
1705 break;
1706 case Instruction::OR_INT:
1707 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001708 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001709 shadow_frame.GetVReg(inst->VRegB_23x()) |
1710 shadow_frame.GetVReg(inst->VRegC_23x()));
1711 inst = inst->Next_2xx();
1712 break;
1713 case Instruction::XOR_INT:
1714 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001715 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001716 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1717 shadow_frame.GetVReg(inst->VRegC_23x()));
1718 inst = inst->Next_2xx();
1719 break;
1720 case Instruction::ADD_LONG:
1721 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001722 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001723 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1724 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001725 inst = inst->Next_2xx();
1726 break;
1727 case Instruction::SUB_LONG:
1728 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001729 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001730 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1731 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001732 inst = inst->Next_2xx();
1733 break;
1734 case Instruction::MUL_LONG:
1735 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001736 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001737 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1738 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001739 inst = inst->Next_2xx();
1740 break;
1741 case Instruction::DIV_LONG:
1742 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001743 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001744 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001745 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001746 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1747 break;
1748 case Instruction::REM_LONG:
1749 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001750 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001751 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1752 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1753 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1754 break;
1755 case Instruction::AND_LONG:
1756 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001757 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001758 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1759 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1760 inst = inst->Next_2xx();
1761 break;
1762 case Instruction::OR_LONG:
1763 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001764 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001765 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1766 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1767 inst = inst->Next_2xx();
1768 break;
1769 case Instruction::XOR_LONG:
1770 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001771 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001772 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1773 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1774 inst = inst->Next_2xx();
1775 break;
1776 case Instruction::SHL_LONG:
1777 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001778 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001779 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1780 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1781 inst = inst->Next_2xx();
1782 break;
1783 case Instruction::SHR_LONG:
1784 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001785 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001786 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1787 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1788 inst = inst->Next_2xx();
1789 break;
1790 case Instruction::USHR_LONG:
1791 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001792 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001793 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1794 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1795 inst = inst->Next_2xx();
1796 break;
1797 case Instruction::ADD_FLOAT:
1798 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001799 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001800 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1801 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1802 inst = inst->Next_2xx();
1803 break;
1804 case Instruction::SUB_FLOAT:
1805 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001806 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001807 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1808 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1809 inst = inst->Next_2xx();
1810 break;
1811 case Instruction::MUL_FLOAT:
1812 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001813 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001814 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1815 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1816 inst = inst->Next_2xx();
1817 break;
1818 case Instruction::DIV_FLOAT:
1819 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001820 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001821 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1822 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1823 inst = inst->Next_2xx();
1824 break;
1825 case Instruction::REM_FLOAT:
1826 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001827 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001828 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1829 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1830 inst = inst->Next_2xx();
1831 break;
1832 case Instruction::ADD_DOUBLE:
1833 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001834 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001835 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1836 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1837 inst = inst->Next_2xx();
1838 break;
1839 case Instruction::SUB_DOUBLE:
1840 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001841 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001842 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1843 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1844 inst = inst->Next_2xx();
1845 break;
1846 case Instruction::MUL_DOUBLE:
1847 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001848 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001849 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1850 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1851 inst = inst->Next_2xx();
1852 break;
1853 case Instruction::DIV_DOUBLE:
1854 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001855 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001856 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1857 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1858 inst = inst->Next_2xx();
1859 break;
1860 case Instruction::REM_DOUBLE:
1861 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001862 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001863 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1864 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1865 inst = inst->Next_2xx();
1866 break;
1867 case Instruction::ADD_INT_2ADDR: {
1868 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001869 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07001870 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
1871 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001872 inst = inst->Next_1xx();
1873 break;
1874 }
1875 case Instruction::SUB_INT_2ADDR: {
1876 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001877 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001878 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001879 SafeSub(shadow_frame.GetVReg(vregA),
1880 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001881 inst = inst->Next_1xx();
1882 break;
1883 }
1884 case Instruction::MUL_INT_2ADDR: {
1885 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001886 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001887 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001888 SafeMul(shadow_frame.GetVReg(vregA),
1889 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001890 inst = inst->Next_1xx();
1891 break;
1892 }
1893 case Instruction::DIV_INT_2ADDR: {
1894 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001895 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001896 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001897 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001898 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1899 break;
1900 }
1901 case Instruction::REM_INT_2ADDR: {
1902 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001903 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001904 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001905 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001906 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1907 break;
1908 }
1909 case Instruction::SHL_INT_2ADDR: {
1910 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001911 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001912 shadow_frame.SetVReg(vregA,
1913 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001914 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001915 inst = inst->Next_1xx();
1916 break;
1917 }
1918 case Instruction::SHR_INT_2ADDR: {
1919 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001920 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001921 shadow_frame.SetVReg(vregA,
1922 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001923 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001924 inst = inst->Next_1xx();
1925 break;
1926 }
1927 case Instruction::USHR_INT_2ADDR: {
1928 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001929 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001930 shadow_frame.SetVReg(vregA,
1931 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001932 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001933 inst = inst->Next_1xx();
1934 break;
1935 }
1936 case Instruction::AND_INT_2ADDR: {
1937 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001938 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001939 shadow_frame.SetVReg(vregA,
1940 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001941 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001942 inst = inst->Next_1xx();
1943 break;
1944 }
1945 case Instruction::OR_INT_2ADDR: {
1946 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001947 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001948 shadow_frame.SetVReg(vregA,
1949 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001950 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001951 inst = inst->Next_1xx();
1952 break;
1953 }
1954 case Instruction::XOR_INT_2ADDR: {
1955 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001956 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001957 shadow_frame.SetVReg(vregA,
1958 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001959 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001960 inst = inst->Next_1xx();
1961 break;
1962 }
1963 case Instruction::ADD_LONG_2ADDR: {
1964 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001965 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001966 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001967 SafeAdd(shadow_frame.GetVRegLong(vregA),
1968 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001969 inst = inst->Next_1xx();
1970 break;
1971 }
1972 case Instruction::SUB_LONG_2ADDR: {
1973 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001974 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001975 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001976 SafeSub(shadow_frame.GetVRegLong(vregA),
1977 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001978 inst = inst->Next_1xx();
1979 break;
1980 }
1981 case Instruction::MUL_LONG_2ADDR: {
1982 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001983 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001984 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001985 SafeMul(shadow_frame.GetVRegLong(vregA),
1986 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001987 inst = inst->Next_1xx();
1988 break;
1989 }
1990 case Instruction::DIV_LONG_2ADDR: {
1991 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001992 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001993 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001994 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001995 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1996 break;
1997 }
1998 case Instruction::REM_LONG_2ADDR: {
1999 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002000 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002001 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002002 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002003 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2004 break;
2005 }
2006 case Instruction::AND_LONG_2ADDR: {
2007 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002008 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002009 shadow_frame.SetVRegLong(vregA,
2010 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002011 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002012 inst = inst->Next_1xx();
2013 break;
2014 }
2015 case Instruction::OR_LONG_2ADDR: {
2016 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002017 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002018 shadow_frame.SetVRegLong(vregA,
2019 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002020 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002021 inst = inst->Next_1xx();
2022 break;
2023 }
2024 case Instruction::XOR_LONG_2ADDR: {
2025 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002026 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002027 shadow_frame.SetVRegLong(vregA,
2028 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002029 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002030 inst = inst->Next_1xx();
2031 break;
2032 }
2033 case Instruction::SHL_LONG_2ADDR: {
2034 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002035 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002036 shadow_frame.SetVRegLong(vregA,
2037 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002038 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002039 inst = inst->Next_1xx();
2040 break;
2041 }
2042 case Instruction::SHR_LONG_2ADDR: {
2043 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002044 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002045 shadow_frame.SetVRegLong(vregA,
2046 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002047 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002048 inst = inst->Next_1xx();
2049 break;
2050 }
2051 case Instruction::USHR_LONG_2ADDR: {
2052 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002053 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002054 shadow_frame.SetVRegLong(vregA,
2055 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002056 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002057 inst = inst->Next_1xx();
2058 break;
2059 }
2060 case Instruction::ADD_FLOAT_2ADDR: {
2061 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002062 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002063 shadow_frame.SetVRegFloat(vregA,
2064 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002065 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002066 inst = inst->Next_1xx();
2067 break;
2068 }
2069 case Instruction::SUB_FLOAT_2ADDR: {
2070 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002071 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002072 shadow_frame.SetVRegFloat(vregA,
2073 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002074 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002075 inst = inst->Next_1xx();
2076 break;
2077 }
2078 case Instruction::MUL_FLOAT_2ADDR: {
2079 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002080 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002081 shadow_frame.SetVRegFloat(vregA,
2082 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002083 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002084 inst = inst->Next_1xx();
2085 break;
2086 }
2087 case Instruction::DIV_FLOAT_2ADDR: {
2088 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002089 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002090 shadow_frame.SetVRegFloat(vregA,
2091 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002092 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002093 inst = inst->Next_1xx();
2094 break;
2095 }
2096 case Instruction::REM_FLOAT_2ADDR: {
2097 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002098 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002099 shadow_frame.SetVRegFloat(vregA,
2100 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002101 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002102 inst = inst->Next_1xx();
2103 break;
2104 }
2105 case Instruction::ADD_DOUBLE_2ADDR: {
2106 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002107 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002108 shadow_frame.SetVRegDouble(vregA,
2109 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002110 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002111 inst = inst->Next_1xx();
2112 break;
2113 }
2114 case Instruction::SUB_DOUBLE_2ADDR: {
2115 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002116 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002117 shadow_frame.SetVRegDouble(vregA,
2118 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002119 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002120 inst = inst->Next_1xx();
2121 break;
2122 }
2123 case Instruction::MUL_DOUBLE_2ADDR: {
2124 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002125 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002126 shadow_frame.SetVRegDouble(vregA,
2127 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002128 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002129 inst = inst->Next_1xx();
2130 break;
2131 }
2132 case Instruction::DIV_DOUBLE_2ADDR: {
2133 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002134 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002135 shadow_frame.SetVRegDouble(vregA,
2136 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002137 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002138 inst = inst->Next_1xx();
2139 break;
2140 }
2141 case Instruction::REM_DOUBLE_2ADDR: {
2142 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002143 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002144 shadow_frame.SetVRegDouble(vregA,
2145 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002146 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002147 inst = inst->Next_1xx();
2148 break;
2149 }
2150 case Instruction::ADD_INT_LIT16:
2151 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002152 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002153 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2154 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002155 inst = inst->Next_2xx();
2156 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002157 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002158 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002159 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002160 SafeSub(inst->VRegC_22s(),
2161 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002162 inst = inst->Next_2xx();
2163 break;
2164 case Instruction::MUL_INT_LIT16:
2165 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002166 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002167 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2168 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002169 inst = inst->Next_2xx();
2170 break;
2171 case Instruction::DIV_INT_LIT16: {
2172 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002173 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002174 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2175 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002176 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2177 break;
2178 }
2179 case Instruction::REM_INT_LIT16: {
2180 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002181 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002182 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2183 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002184 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2185 break;
2186 }
2187 case Instruction::AND_INT_LIT16:
2188 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002189 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2190 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002191 inst->VRegC_22s());
2192 inst = inst->Next_2xx();
2193 break;
2194 case Instruction::OR_INT_LIT16:
2195 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002196 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2197 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002198 inst->VRegC_22s());
2199 inst = inst->Next_2xx();
2200 break;
2201 case Instruction::XOR_INT_LIT16:
2202 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002203 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2204 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002205 inst->VRegC_22s());
2206 inst = inst->Next_2xx();
2207 break;
2208 case Instruction::ADD_INT_LIT8:
2209 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002210 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002211 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002212 inst = inst->Next_2xx();
2213 break;
2214 case Instruction::RSUB_INT_LIT8:
2215 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002216 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002217 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002218 inst = inst->Next_2xx();
2219 break;
2220 case Instruction::MUL_INT_LIT8:
2221 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002222 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002223 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002224 inst = inst->Next_2xx();
2225 break;
2226 case Instruction::DIV_INT_LIT8: {
2227 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002228 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002229 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2230 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2231 break;
2232 }
2233 case Instruction::REM_INT_LIT8: {
2234 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002235 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002236 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2237 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2238 break;
2239 }
2240 case Instruction::AND_INT_LIT8:
2241 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002242 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002243 shadow_frame.GetVReg(inst->VRegB_22b()) &
2244 inst->VRegC_22b());
2245 inst = inst->Next_2xx();
2246 break;
2247 case Instruction::OR_INT_LIT8:
2248 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002249 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002250 shadow_frame.GetVReg(inst->VRegB_22b()) |
2251 inst->VRegC_22b());
2252 inst = inst->Next_2xx();
2253 break;
2254 case Instruction::XOR_INT_LIT8:
2255 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002256 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002257 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2258 inst->VRegC_22b());
2259 inst = inst->Next_2xx();
2260 break;
2261 case Instruction::SHL_INT_LIT8:
2262 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002263 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002264 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2265 (inst->VRegC_22b() & 0x1f));
2266 inst = inst->Next_2xx();
2267 break;
2268 case Instruction::SHR_INT_LIT8:
2269 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002270 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002271 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2272 (inst->VRegC_22b() & 0x1f));
2273 inst = inst->Next_2xx();
2274 break;
2275 case Instruction::USHR_INT_LIT8:
2276 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002277 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002278 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2279 (inst->VRegC_22b() & 0x1f));
2280 inst = inst->Next_2xx();
2281 break;
Igor Murashkin158f35c2015-06-10 15:55:30 -07002282 case Instruction::INVOKE_LAMBDA: {
2283 if (!IsExperimentalInstructionEnabled(inst)) {
2284 UnexpectedOpcode(inst, shadow_frame);
2285 }
2286
2287 PREAMBLE();
2288 bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
2289 &result_register);
2290 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2291 break;
2292 }
Igor Murashkin6918bf12015-09-27 19:19:06 -07002293 case Instruction::CAPTURE_VARIABLE: {
2294 if (!IsExperimentalInstructionEnabled(inst)) {
2295 UnexpectedOpcode(inst, shadow_frame);
2296 }
2297
2298 if (lambda_closure_builder == nullptr) {
2299 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2300 }
2301
2302 PREAMBLE();
2303 bool success = DoCaptureVariable<do_access_check>(self,
2304 inst,
2305 /*inout*/shadow_frame,
2306 /*inout*/lambda_closure_builder.get());
2307 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2308 break;
2309 }
Igor Murashkin158f35c2015-06-10 15:55:30 -07002310 case Instruction::CREATE_LAMBDA: {
2311 if (!IsExperimentalInstructionEnabled(inst)) {
2312 UnexpectedOpcode(inst, shadow_frame);
2313 }
2314
2315 PREAMBLE();
Igor Murashkin6918bf12015-09-27 19:19:06 -07002316
2317 if (lambda_closure_builder == nullptr) {
2318 // DoCreateLambda always needs a ClosureBuilder, even if it has 0 captured variables.
2319 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2320 }
2321
2322 // TODO: these allocations should not leak, and the lambda method should not be local.
2323 lambda::Closure* lambda_closure =
2324 reinterpret_cast<lambda::Closure*>(alloca(lambda_closure_builder->GetSize()));
2325 bool success = DoCreateLambda<do_access_check>(self,
2326 inst,
2327 /*inout*/shadow_frame,
2328 /*inout*/lambda_closure_builder.get(),
2329 /*inout*/lambda_closure);
2330 lambda_closure_builder.reset(nullptr); // reset state of variables captured
Igor Murashkin158f35c2015-06-10 15:55:30 -07002331 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2332 break;
2333 }
Igor Murashkin6918bf12015-09-27 19:19:06 -07002334 case Instruction::LIBERATE_VARIABLE: {
2335 if (!IsExperimentalInstructionEnabled(inst)) {
2336 UnexpectedOpcode(inst, shadow_frame);
2337 }
2338
2339 PREAMBLE();
2340 bool success = DoLiberateVariable<do_access_check>(self,
2341 inst,
2342 lambda_captured_variable_index,
2343 /*inout*/shadow_frame);
2344 // Temporarily only allow sequences of 'liberate-variable, liberate-variable, ...'
2345 lambda_captured_variable_index++;
2346 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2347 break;
2348 }
2349 case Instruction::UNUSED_F4: {
Igor Murashkin158f35c2015-06-10 15:55:30 -07002350 if (!IsExperimentalInstructionEnabled(inst)) {
2351 UnexpectedOpcode(inst, shadow_frame);
2352 }
2353
2354 CHECK(false); // TODO(iam): Implement opcodes for lambdas
2355 break;
2356 }
Igor Murashkin2ee54e22015-06-18 10:05:11 -07002357 case Instruction::BOX_LAMBDA: {
2358 if (!IsExperimentalInstructionEnabled(inst)) {
2359 UnexpectedOpcode(inst, shadow_frame);
2360 }
2361
2362 PREAMBLE();
2363 bool success = DoBoxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2364 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2365 break;
2366 }
2367 case Instruction::UNBOX_LAMBDA: {
2368 if (!IsExperimentalInstructionEnabled(inst)) {
2369 UnexpectedOpcode(inst, shadow_frame);
2370 }
2371
2372 PREAMBLE();
2373 bool success = DoUnboxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2374 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2375 break;
2376 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002377 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Igor Murashkin158f35c2015-06-10 15:55:30 -07002378 case Instruction::UNUSED_FA ... Instruction::UNUSED_FF:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002379 case Instruction::UNUSED_79:
2380 case Instruction::UNUSED_7A:
Ian Rogerse94652f2014-12-02 11:13:19 -08002381 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002382 }
buzbee1452bee2015-03-06 14:43:04 -08002383 } while (!interpret_one_instruction);
2384 // Record where we stopped.
2385 shadow_frame.SetDexPC(inst->GetDexPc(insns));
buzbeed6b48db2016-01-28 15:48:55 -08002386 return result_register;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002387} // NOLINT(readability/fn_size)
2388
2389// Explicit definitions of ExecuteSwitchImpl.
Mathieu Chartier90443472015-07-16 20:32:27 -07002390template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002391JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002392 ShadowFrame& shadow_frame, JValue result_register,
2393 bool interpret_one_instruction);
Mathieu Chartier90443472015-07-16 20:32:27 -07002394template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002395JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002396 ShadowFrame& shadow_frame, JValue result_register,
2397 bool interpret_one_instruction);
Mathieu Chartier90443472015-07-16 20:32:27 -07002398template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002399JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002400 ShadowFrame& shadow_frame, JValue result_register,
2401 bool interpret_one_instruction);
Mathieu Chartier90443472015-07-16 20:32:27 -07002402template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002403JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
buzbee1452bee2015-03-06 14:43:04 -08002404 ShadowFrame& shadow_frame, JValue result_register,
2405 bool interpret_one_instruction);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002406
2407} // namespace interpreter
2408} // namespace art