blob: 083dfb526777eda8c8117f6470496818fad52ec4 [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
Sebastien Hertz8ece0502013-08-07 11:26:41 +020018#include "interpreter_common.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070019#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020020
Igor Murashkin6918bf12015-09-27 19:19:06 -070021#include <memory> // std::unique_ptr
22
Sebastien Hertz8ece0502013-08-07 11:26:41 +020023namespace art {
24namespace interpreter {
25
26#define HANDLE_PENDING_EXCEPTION() \
27 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020028 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070029 self->AllowThreadSuspension(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020030 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, \
31 inst->GetDexPc(insns), \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020032 instrumentation); \
33 if (found_dex_pc == DexFile::kDexNoIndex) { \
34 return JValue(); /* Handled in caller. */ \
35 } else { \
36 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); \
37 inst = inst->RelativeAt(displacement); \
38 } \
39 } while (false)
40
41#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
42 do { \
43 if (UNLIKELY(_is_exception_pending)) { \
44 HANDLE_PENDING_EXCEPTION(); \
45 } else { \
46 inst = inst->_next_function(); \
47 } \
48 } while (false)
49
50// Code to run before each dex instruction.
Sebastien Hertz8379b222014-02-24 17:38:15 +010051#define PREAMBLE() \
52 do { \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +020053 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
Sebastien Hertz8379b222014-02-24 17:38:15 +010054 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), \
55 shadow_frame.GetMethod(), dex_pc); \
56 } \
57 } while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020058
Igor Murashkin158f35c2015-06-10 15:55:30 -070059static bool IsExperimentalInstructionEnabled(const Instruction *inst) {
60 DCHECK(inst->IsExperimental());
61 return Runtime::Current()->AreExperimentalLambdasEnabled();
62}
63
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010064template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -080065JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertz8379b222014-02-24 17:38:15 +010066 ShadowFrame& shadow_frame, JValue result_register) {
Igor Murashkinc449e8b2015-06-10 15:56:42 -070067 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020068 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
69 LOG(FATAL) << "Invalid shadow frame for interpreter use";
70 return JValue();
71 }
72 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020073
74 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -070075 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz270a0e12015-01-16 19:49:09 +010076 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.
77 if (kIsDebugBuild) {
78 self->AssertNoPendingException();
79 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +020080 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +020081 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +020082 shadow_frame.GetMethod(), 0);
83 }
84 }
85 const uint16_t* const insns = code_item->insns_;
86 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020087 uint16_t inst_data;
Igor Murashkin6918bf12015-09-27 19:19:06 -070088
89 // TODO: collapse capture-variable+create-lambda into one opcode, then we won't need
90 // to keep this live for the scope of the entire function call.
91 std::unique_ptr<lambda::ClosureBuilder> lambda_closure_builder;
92 size_t lambda_captured_variable_index = 0;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020093 while (true) {
94 dex_pc = inst->GetDexPc(insns);
95 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -080096 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020097 inst_data = inst->Fetch16(0);
98 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +020099 case Instruction::NOP:
100 PREAMBLE();
101 inst = inst->Next_1xx();
102 break;
103 case Instruction::MOVE:
104 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200105 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
106 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200107 inst = inst->Next_1xx();
108 break;
109 case Instruction::MOVE_FROM16:
110 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200111 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200112 shadow_frame.GetVReg(inst->VRegB_22x()));
113 inst = inst->Next_2xx();
114 break;
115 case Instruction::MOVE_16:
116 PREAMBLE();
117 shadow_frame.SetVReg(inst->VRegA_32x(),
118 shadow_frame.GetVReg(inst->VRegB_32x()));
119 inst = inst->Next_3xx();
120 break;
121 case Instruction::MOVE_WIDE:
122 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200123 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
124 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200125 inst = inst->Next_1xx();
126 break;
127 case Instruction::MOVE_WIDE_FROM16:
128 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200129 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200130 shadow_frame.GetVRegLong(inst->VRegB_22x()));
131 inst = inst->Next_2xx();
132 break;
133 case Instruction::MOVE_WIDE_16:
134 PREAMBLE();
135 shadow_frame.SetVRegLong(inst->VRegA_32x(),
136 shadow_frame.GetVRegLong(inst->VRegB_32x()));
137 inst = inst->Next_3xx();
138 break;
139 case Instruction::MOVE_OBJECT:
140 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200141 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
142 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200143 inst = inst->Next_1xx();
144 break;
145 case Instruction::MOVE_OBJECT_FROM16:
146 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200147 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200148 shadow_frame.GetVRegReference(inst->VRegB_22x()));
149 inst = inst->Next_2xx();
150 break;
151 case Instruction::MOVE_OBJECT_16:
152 PREAMBLE();
153 shadow_frame.SetVRegReference(inst->VRegA_32x(),
154 shadow_frame.GetVRegReference(inst->VRegB_32x()));
155 inst = inst->Next_3xx();
156 break;
157 case Instruction::MOVE_RESULT:
158 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200159 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200160 inst = inst->Next_1xx();
161 break;
162 case Instruction::MOVE_RESULT_WIDE:
163 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200164 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200165 inst = inst->Next_1xx();
166 break;
167 case Instruction::MOVE_RESULT_OBJECT:
168 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200169 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200170 inst = inst->Next_1xx();
171 break;
172 case Instruction::MOVE_EXCEPTION: {
173 PREAMBLE();
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000174 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100175 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200176 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200177 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200178 inst = inst->Next_1xx();
179 break;
180 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700181 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200182 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200183 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700184 self->AllowThreadSuspension();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200185 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200186 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200187 shadow_frame.GetMethod(), inst->GetDexPc(insns),
188 result);
189 }
190 return result;
191 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700192 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200193 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700194 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200195 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700196 self->AllowThreadSuspension();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200197 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200198 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200199 shadow_frame.GetMethod(), inst->GetDexPc(insns),
200 result);
201 }
202 return result;
203 }
204 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200205 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200206 JValue result;
207 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200208 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700209 self->AllowThreadSuspension();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200210 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200211 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200212 shadow_frame.GetMethod(), inst->GetDexPc(insns),
213 result);
214 }
215 return result;
216 }
217 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200218 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200219 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200220 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700221 self->AllowThreadSuspension();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200222 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200223 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200224 shadow_frame.GetMethod(), inst->GetDexPc(insns),
225 result);
226 }
227 return result;
228 }
229 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200230 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200231 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700232 self->AllowThreadSuspension();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700233 const size_t ref_idx = inst->VRegA_11x(inst_data);
234 Object* obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700235 if (do_assignability_check && obj_result != nullptr) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100236 size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
237 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
238 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700239 // Re-load since it might have moved.
240 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700241 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700242 // Return the pending exception.
243 HANDLE_PENDING_EXCEPTION();
244 }
245 if (!obj_result->VerifierInstanceOf(return_type)) {
246 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700247 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000248 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700249 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700250 obj_result->GetClass()->GetDescriptor(&temp1),
251 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700252 HANDLE_PENDING_EXCEPTION();
253 }
254 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700255 result.SetL(obj_result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200256 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200257 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200258 shadow_frame.GetMethod(), inst->GetDexPc(insns),
259 result);
260 }
261 return result;
262 }
263 case Instruction::CONST_4: {
264 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200265 uint4_t dst = inst->VRegA_11n(inst_data);
266 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200267 shadow_frame.SetVReg(dst, val);
268 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700269 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200270 }
271 inst = inst->Next_1xx();
272 break;
273 }
274 case Instruction::CONST_16: {
275 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200276 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200277 int16_t val = inst->VRegB_21s();
278 shadow_frame.SetVReg(dst, val);
279 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700280 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200281 }
282 inst = inst->Next_2xx();
283 break;
284 }
285 case Instruction::CONST: {
286 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200287 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200288 int32_t val = inst->VRegB_31i();
289 shadow_frame.SetVReg(dst, val);
290 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700291 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200292 }
293 inst = inst->Next_3xx();
294 break;
295 }
296 case Instruction::CONST_HIGH16: {
297 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200298 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200299 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
300 shadow_frame.SetVReg(dst, val);
301 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700302 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200303 }
304 inst = inst->Next_2xx();
305 break;
306 }
307 case Instruction::CONST_WIDE_16:
308 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200309 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200310 inst = inst->Next_2xx();
311 break;
312 case Instruction::CONST_WIDE_32:
313 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200314 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200315 inst = inst->Next_3xx();
316 break;
317 case Instruction::CONST_WIDE:
318 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200319 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200320 inst = inst->Next_51l();
321 break;
322 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200323 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200324 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200325 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
326 inst = inst->Next_2xx();
327 break;
328 case Instruction::CONST_STRING: {
329 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700330 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700331 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200332 HANDLE_PENDING_EXCEPTION();
333 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200334 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200335 inst = inst->Next_2xx();
336 }
337 break;
338 }
339 case Instruction::CONST_STRING_JUMBO: {
340 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700341 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700342 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200343 HANDLE_PENDING_EXCEPTION();
344 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200345 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200346 inst = inst->Next_3xx();
347 }
348 break;
349 }
350 case Instruction::CONST_CLASS: {
351 PREAMBLE();
352 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
353 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700354 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200355 HANDLE_PENDING_EXCEPTION();
356 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200357 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200358 inst = inst->Next_2xx();
359 }
360 break;
361 }
362 case Instruction::MONITOR_ENTER: {
363 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200364 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700365 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000366 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200367 HANDLE_PENDING_EXCEPTION();
368 } else {
369 DoMonitorEnter(self, obj);
370 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
371 }
372 break;
373 }
374 case Instruction::MONITOR_EXIT: {
375 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200376 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700377 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000378 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200379 HANDLE_PENDING_EXCEPTION();
380 } else {
381 DoMonitorExit(self, obj);
382 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
383 }
384 break;
385 }
386 case Instruction::CHECK_CAST: {
387 PREAMBLE();
388 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
389 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700390 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200391 HANDLE_PENDING_EXCEPTION();
392 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200393 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700394 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200395 ThrowClassCastException(c, obj->GetClass());
396 HANDLE_PENDING_EXCEPTION();
397 } else {
398 inst = inst->Next_2xx();
399 }
400 }
401 break;
402 }
403 case Instruction::INSTANCE_OF: {
404 PREAMBLE();
405 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
406 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700407 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200408 HANDLE_PENDING_EXCEPTION();
409 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200410 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700411 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
412 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200413 inst = inst->Next_2xx();
414 }
415 break;
416 }
417 case Instruction::ARRAY_LENGTH: {
418 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200419 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700420 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000421 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200422 HANDLE_PENDING_EXCEPTION();
423 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200424 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200425 inst = inst->Next_1xx();
426 }
427 break;
428 }
429 case Instruction::NEW_INSTANCE: {
430 PREAMBLE();
Jeff Hao848f70a2014-01-15 13:49:50 -0800431 Object* obj = nullptr;
432 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
433 self, false, do_access_check);
434 if (LIKELY(c != nullptr)) {
435 if (UNLIKELY(c->IsStringClass())) {
436 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
437 mirror::SetStringCountVisitor visitor(0);
438 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
439 } else {
440 obj = AllocObjectFromCode<do_access_check, true>(
441 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
442 Runtime::Current()->GetHeap()->GetCurrentAllocator());
443 }
444 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700445 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200446 HANDLE_PENDING_EXCEPTION();
447 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200448 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700449 // Don't allow finalizable objects to be allocated during a transaction since these can't
450 // be finalized without a started runtime.
451 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200452 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
453 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700454 HANDLE_PENDING_EXCEPTION();
455 break;
456 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200457 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200458 inst = inst->Next_2xx();
459 }
460 break;
461 }
462 case Instruction::NEW_ARRAY: {
463 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200464 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800465 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800466 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800467 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700468 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200469 HANDLE_PENDING_EXCEPTION();
470 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200471 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200472 inst = inst->Next_2xx();
473 }
474 break;
475 }
476 case Instruction::FILLED_NEW_ARRAY: {
477 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100478 bool success =
479 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
480 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200481 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
482 break;
483 }
484 case Instruction::FILLED_NEW_ARRAY_RANGE: {
485 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100486 bool success =
487 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
488 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200489 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
490 break;
491 }
492 case Instruction::FILL_ARRAY_DATA: {
493 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200494 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
495 const Instruction::ArrayDataPayload* payload =
496 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Ian Rogers832336b2014-10-08 15:35:22 -0700497 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
498 bool success = FillArrayData(obj, payload);
499 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200500 HANDLE_PENDING_EXCEPTION();
501 break;
502 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100503 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700504 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100505 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200506 inst = inst->Next_3xx();
507 break;
508 }
509 case Instruction::THROW: {
510 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200511 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700512 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000513 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700514 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
515 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700516 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000517 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700518 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700519 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200520 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000521 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200522 }
523 HANDLE_PENDING_EXCEPTION();
524 break;
525 }
526 case Instruction::GOTO: {
527 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200528 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200529 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700530 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200531 }
532 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200533 break;
534 }
535 case Instruction::GOTO_16: {
536 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200537 int16_t offset = inst->VRegA_20t();
538 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700539 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200540 }
541 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200542 break;
543 }
544 case Instruction::GOTO_32: {
545 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200546 int32_t offset = inst->VRegA_30t();
547 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700548 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200549 }
550 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200551 break;
552 }
553 case Instruction::PACKED_SWITCH: {
554 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200555 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200556 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700557 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200558 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200559 inst = inst->RelativeAt(offset);
560 break;
561 }
562 case Instruction::SPARSE_SWITCH: {
563 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200564 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200565 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700566 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200567 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200568 inst = inst->RelativeAt(offset);
569 break;
570 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700571
572#if defined(__clang__)
573#pragma clang diagnostic push
574#pragma clang diagnostic ignored "-Wfloat-equal"
575#endif
576
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200577 case Instruction::CMPL_FLOAT: {
578 PREAMBLE();
579 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
580 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
581 int32_t result;
582 if (val1 > val2) {
583 result = 1;
584 } else if (val1 == val2) {
585 result = 0;
586 } else {
587 result = -1;
588 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200589 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200590 inst = inst->Next_2xx();
591 break;
592 }
593 case Instruction::CMPG_FLOAT: {
594 PREAMBLE();
595 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
596 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
597 int32_t result;
598 if (val1 < val2) {
599 result = -1;
600 } else if (val1 == val2) {
601 result = 0;
602 } else {
603 result = 1;
604 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200605 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200606 inst = inst->Next_2xx();
607 break;
608 }
609 case Instruction::CMPL_DOUBLE: {
610 PREAMBLE();
611 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
612 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
613 int32_t result;
614 if (val1 > val2) {
615 result = 1;
616 } else if (val1 == val2) {
617 result = 0;
618 } else {
619 result = -1;
620 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200621 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200622 inst = inst->Next_2xx();
623 break;
624 }
625
626 case Instruction::CMPG_DOUBLE: {
627 PREAMBLE();
628 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
629 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
630 int32_t result;
631 if (val1 < val2) {
632 result = -1;
633 } else if (val1 == val2) {
634 result = 0;
635 } else {
636 result = 1;
637 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200638 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200639 inst = inst->Next_2xx();
640 break;
641 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700642
643#if defined(__clang__)
644#pragma clang diagnostic pop
645#endif
646
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200647 case Instruction::CMP_LONG: {
648 PREAMBLE();
649 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
650 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
651 int32_t result;
652 if (val1 > val2) {
653 result = 1;
654 } else if (val1 == val2) {
655 result = 0;
656 } else {
657 result = -1;
658 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200659 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200660 inst = inst->Next_2xx();
661 break;
662 }
663 case Instruction::IF_EQ: {
664 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700665 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
666 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200667 int16_t offset = inst->VRegC_22t();
668 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700669 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200670 }
671 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200672 } else {
673 inst = inst->Next_2xx();
674 }
675 break;
676 }
677 case Instruction::IF_NE: {
678 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700679 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
680 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200681 int16_t offset = inst->VRegC_22t();
682 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700683 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200684 }
685 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200686 } else {
687 inst = inst->Next_2xx();
688 }
689 break;
690 }
691 case Instruction::IF_LT: {
692 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700693 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
694 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200695 int16_t offset = inst->VRegC_22t();
696 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700697 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200698 }
699 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200700 } else {
701 inst = inst->Next_2xx();
702 }
703 break;
704 }
705 case Instruction::IF_GE: {
706 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700707 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
708 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200709 int16_t offset = inst->VRegC_22t();
710 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700711 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200712 }
713 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200714 } else {
715 inst = inst->Next_2xx();
716 }
717 break;
718 }
719 case Instruction::IF_GT: {
720 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700721 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
722 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200723 int16_t offset = inst->VRegC_22t();
724 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700725 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200726 }
727 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200728 } else {
729 inst = inst->Next_2xx();
730 }
731 break;
732 }
733 case Instruction::IF_LE: {
734 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700735 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
736 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200737 int16_t offset = inst->VRegC_22t();
738 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700739 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200740 }
741 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200742 } else {
743 inst = inst->Next_2xx();
744 }
745 break;
746 }
747 case Instruction::IF_EQZ: {
748 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200749 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200750 int16_t offset = inst->VRegB_21t();
751 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700752 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200753 }
754 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200755 } else {
756 inst = inst->Next_2xx();
757 }
758 break;
759 }
760 case Instruction::IF_NEZ: {
761 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200762 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200763 int16_t offset = inst->VRegB_21t();
764 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_LTZ: {
774 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200775 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200776 int16_t offset = inst->VRegB_21t();
777 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700778 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200779 }
780 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200781 } else {
782 inst = inst->Next_2xx();
783 }
784 break;
785 }
786 case Instruction::IF_GEZ: {
787 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200788 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200789 int16_t offset = inst->VRegB_21t();
790 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700791 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200792 }
793 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200794 } else {
795 inst = inst->Next_2xx();
796 }
797 break;
798 }
799 case Instruction::IF_GTZ: {
800 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200801 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200802 int16_t offset = inst->VRegB_21t();
803 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700804 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200805 }
806 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200807 } else {
808 inst = inst->Next_2xx();
809 }
810 break;
811 }
812 case Instruction::IF_LEZ: {
813 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200814 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200815 int16_t offset = inst->VRegB_21t();
816 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700817 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200818 }
819 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200820 } else {
821 inst = inst->Next_2xx();
822 }
823 break;
824 }
825 case Instruction::AGET_BOOLEAN: {
826 PREAMBLE();
827 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700828 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000829 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200830 HANDLE_PENDING_EXCEPTION();
831 break;
832 }
833 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
834 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700835 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100836 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200837 inst = inst->Next_2xx();
838 } else {
839 HANDLE_PENDING_EXCEPTION();
840 }
841 break;
842 }
843 case Instruction::AGET_BYTE: {
844 PREAMBLE();
845 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700846 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000847 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200848 HANDLE_PENDING_EXCEPTION();
849 break;
850 }
851 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
852 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700853 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100854 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200855 inst = inst->Next_2xx();
856 } else {
857 HANDLE_PENDING_EXCEPTION();
858 }
859 break;
860 }
861 case Instruction::AGET_CHAR: {
862 PREAMBLE();
863 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700864 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000865 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200866 HANDLE_PENDING_EXCEPTION();
867 break;
868 }
869 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
870 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700871 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100872 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200873 inst = inst->Next_2xx();
874 } else {
875 HANDLE_PENDING_EXCEPTION();
876 }
877 break;
878 }
879 case Instruction::AGET_SHORT: {
880 PREAMBLE();
881 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700882 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000883 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200884 HANDLE_PENDING_EXCEPTION();
885 break;
886 }
887 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
888 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700889 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100890 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200891 inst = inst->Next_2xx();
892 } else {
893 HANDLE_PENDING_EXCEPTION();
894 }
895 break;
896 }
897 case Instruction::AGET: {
898 PREAMBLE();
899 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700900 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000901 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200902 HANDLE_PENDING_EXCEPTION();
903 break;
904 }
905 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700906 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
907 auto* array = down_cast<IntArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700908 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100909 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200910 inst = inst->Next_2xx();
911 } else {
912 HANDLE_PENDING_EXCEPTION();
913 }
914 break;
915 }
916 case Instruction::AGET_WIDE: {
917 PREAMBLE();
918 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700919 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000920 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200921 HANDLE_PENDING_EXCEPTION();
922 break;
923 }
924 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700925 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
926 auto* array = down_cast<LongArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700927 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100928 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200929 inst = inst->Next_2xx();
930 } else {
931 HANDLE_PENDING_EXCEPTION();
932 }
933 break;
934 }
935 case Instruction::AGET_OBJECT: {
936 PREAMBLE();
937 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700938 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000939 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200940 HANDLE_PENDING_EXCEPTION();
941 break;
942 }
943 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
944 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700945 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200946 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200947 inst = inst->Next_2xx();
948 } else {
949 HANDLE_PENDING_EXCEPTION();
950 }
951 break;
952 }
953 case Instruction::APUT_BOOLEAN: {
954 PREAMBLE();
955 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700956 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000957 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200958 HANDLE_PENDING_EXCEPTION();
959 break;
960 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200961 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200962 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
963 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700964 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100965 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200966 inst = inst->Next_2xx();
967 } else {
968 HANDLE_PENDING_EXCEPTION();
969 }
970 break;
971 }
972 case Instruction::APUT_BYTE: {
973 PREAMBLE();
974 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700975 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000976 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200977 HANDLE_PENDING_EXCEPTION();
978 break;
979 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200980 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200981 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
982 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700983 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100984 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200985 inst = inst->Next_2xx();
986 } else {
987 HANDLE_PENDING_EXCEPTION();
988 }
989 break;
990 }
991 case Instruction::APUT_CHAR: {
992 PREAMBLE();
993 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700994 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000995 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200996 HANDLE_PENDING_EXCEPTION();
997 break;
998 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200999 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001000 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1001 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001002 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001003 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001004 inst = inst->Next_2xx();
1005 } else {
1006 HANDLE_PENDING_EXCEPTION();
1007 }
1008 break;
1009 }
1010 case Instruction::APUT_SHORT: {
1011 PREAMBLE();
1012 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001013 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001014 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001015 HANDLE_PENDING_EXCEPTION();
1016 break;
1017 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001018 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001019 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1020 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001021 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001022 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001023 inst = inst->Next_2xx();
1024 } else {
1025 HANDLE_PENDING_EXCEPTION();
1026 }
1027 break;
1028 }
1029 case Instruction::APUT: {
1030 PREAMBLE();
1031 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001032 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001033 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001034 HANDLE_PENDING_EXCEPTION();
1035 break;
1036 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001037 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001038 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001039 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1040 auto* array = down_cast<IntArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001041 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001042 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001043 inst = inst->Next_2xx();
1044 } else {
1045 HANDLE_PENDING_EXCEPTION();
1046 }
1047 break;
1048 }
1049 case Instruction::APUT_WIDE: {
1050 PREAMBLE();
1051 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001052 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001053 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001054 HANDLE_PENDING_EXCEPTION();
1055 break;
1056 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001057 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001058 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001059 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1060 LongArray* array = down_cast<LongArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001061 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001062 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001063 inst = inst->Next_2xx();
1064 } else {
1065 HANDLE_PENDING_EXCEPTION();
1066 }
1067 break;
1068 }
1069 case Instruction::APUT_OBJECT: {
1070 PREAMBLE();
1071 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001072 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001073 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001074 HANDLE_PENDING_EXCEPTION();
1075 break;
1076 }
1077 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001078 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001079 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001080 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001081 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001082 inst = inst->Next_2xx();
1083 } else {
1084 HANDLE_PENDING_EXCEPTION();
1085 }
1086 break;
1087 }
1088 case Instruction::IGET_BOOLEAN: {
1089 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001090 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1091 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001092 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1093 break;
1094 }
1095 case Instruction::IGET_BYTE: {
1096 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001097 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1098 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001099 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1100 break;
1101 }
1102 case Instruction::IGET_CHAR: {
1103 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001104 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1105 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001106 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1107 break;
1108 }
1109 case Instruction::IGET_SHORT: {
1110 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001111 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1112 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001113 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1114 break;
1115 }
1116 case Instruction::IGET: {
1117 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001118 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1119 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001120 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1121 break;
1122 }
1123 case Instruction::IGET_WIDE: {
1124 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001125 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1126 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001127 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1128 break;
1129 }
1130 case Instruction::IGET_OBJECT: {
1131 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001132 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1133 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001134 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1135 break;
1136 }
1137 case Instruction::IGET_QUICK: {
1138 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001139 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001140 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1141 break;
1142 }
1143 case Instruction::IGET_WIDE_QUICK: {
1144 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001145 bool success = DoIGetQuick<Primitive::kPrimLong>(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_OBJECT_QUICK: {
1150 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001151 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001152 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1153 break;
1154 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001155 case Instruction::IGET_BOOLEAN_QUICK: {
1156 PREAMBLE();
1157 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1158 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1159 break;
1160 }
1161 case Instruction::IGET_BYTE_QUICK: {
1162 PREAMBLE();
1163 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1164 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1165 break;
1166 }
1167 case Instruction::IGET_CHAR_QUICK: {
1168 PREAMBLE();
1169 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1170 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1171 break;
1172 }
1173 case Instruction::IGET_SHORT_QUICK: {
1174 PREAMBLE();
1175 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1176 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1177 break;
1178 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001179 case Instruction::SGET_BOOLEAN: {
1180 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001181 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1182 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001183 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1184 break;
1185 }
1186 case Instruction::SGET_BYTE: {
1187 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001188 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1189 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001190 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1191 break;
1192 }
1193 case Instruction::SGET_CHAR: {
1194 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001195 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1196 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001197 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1198 break;
1199 }
1200 case Instruction::SGET_SHORT: {
1201 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001202 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1203 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001204 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1205 break;
1206 }
1207 case Instruction::SGET: {
1208 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001209 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1210 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001211 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1212 break;
1213 }
1214 case Instruction::SGET_WIDE: {
1215 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001216 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1217 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001218 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1219 break;
1220 }
1221 case Instruction::SGET_OBJECT: {
1222 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001223 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1224 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001225 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1226 break;
1227 }
1228 case Instruction::IPUT_BOOLEAN: {
1229 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001230 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1231 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001232 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1233 break;
1234 }
1235 case Instruction::IPUT_BYTE: {
1236 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001237 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1238 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001239 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1240 break;
1241 }
1242 case Instruction::IPUT_CHAR: {
1243 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001244 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1245 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001246 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1247 break;
1248 }
1249 case Instruction::IPUT_SHORT: {
1250 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001251 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1252 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001253 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1254 break;
1255 }
1256 case Instruction::IPUT: {
1257 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001258 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1259 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001260 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1261 break;
1262 }
1263 case Instruction::IPUT_WIDE: {
1264 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001265 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1266 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001267 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1268 break;
1269 }
1270 case Instruction::IPUT_OBJECT: {
1271 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001272 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1273 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001274 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1275 break;
1276 }
1277 case Instruction::IPUT_QUICK: {
1278 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001279 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1280 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001281 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1282 break;
1283 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001284 case Instruction::IPUT_BOOLEAN_QUICK: {
1285 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001286 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1287 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001288 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1289 break;
1290 }
1291 case Instruction::IPUT_BYTE_QUICK: {
1292 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001293 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1294 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001295 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1296 break;
1297 }
1298 case Instruction::IPUT_CHAR_QUICK: {
1299 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001300 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1301 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001302 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1303 break;
1304 }
1305 case Instruction::IPUT_SHORT_QUICK: {
1306 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001307 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1308 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001309 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1310 break;
1311 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001312 case Instruction::IPUT_WIDE_QUICK: {
1313 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001314 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1315 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001316 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1317 break;
1318 }
1319 case Instruction::IPUT_OBJECT_QUICK: {
1320 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001321 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1322 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001323 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1324 break;
1325 }
1326 case Instruction::SPUT_BOOLEAN: {
1327 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001328 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1329 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001330 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1331 break;
1332 }
1333 case Instruction::SPUT_BYTE: {
1334 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001335 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1336 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001337 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1338 break;
1339 }
1340 case Instruction::SPUT_CHAR: {
1341 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001342 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1343 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001344 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1345 break;
1346 }
1347 case Instruction::SPUT_SHORT: {
1348 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001349 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1350 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001351 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1352 break;
1353 }
1354 case Instruction::SPUT: {
1355 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001356 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1357 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001358 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1359 break;
1360 }
1361 case Instruction::SPUT_WIDE: {
1362 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001363 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1364 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001365 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1366 break;
1367 }
1368 case Instruction::SPUT_OBJECT: {
1369 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001370 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1371 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001372 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1373 break;
1374 }
1375 case Instruction::INVOKE_VIRTUAL: {
1376 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001377 bool success = DoInvoke<kVirtual, false, do_access_check>(
1378 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001379 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1380 break;
1381 }
1382 case Instruction::INVOKE_VIRTUAL_RANGE: {
1383 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001384 bool success = DoInvoke<kVirtual, true, do_access_check>(
1385 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001386 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1387 break;
1388 }
1389 case Instruction::INVOKE_SUPER: {
1390 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001391 bool success = DoInvoke<kSuper, false, do_access_check>(
1392 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001393 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1394 break;
1395 }
1396 case Instruction::INVOKE_SUPER_RANGE: {
1397 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001398 bool success = DoInvoke<kSuper, true, do_access_check>(
1399 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001400 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1401 break;
1402 }
1403 case Instruction::INVOKE_DIRECT: {
1404 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001405 bool success = DoInvoke<kDirect, false, do_access_check>(
1406 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001407 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1408 break;
1409 }
1410 case Instruction::INVOKE_DIRECT_RANGE: {
1411 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001412 bool success = DoInvoke<kDirect, true, do_access_check>(
1413 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001414 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1415 break;
1416 }
1417 case Instruction::INVOKE_INTERFACE: {
1418 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001419 bool success = DoInvoke<kInterface, false, do_access_check>(
1420 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001421 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1422 break;
1423 }
1424 case Instruction::INVOKE_INTERFACE_RANGE: {
1425 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001426 bool success = DoInvoke<kInterface, true, do_access_check>(
1427 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001428 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1429 break;
1430 }
1431 case Instruction::INVOKE_STATIC: {
1432 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001433 bool success = DoInvoke<kStatic, false, do_access_check>(
1434 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001435 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1436 break;
1437 }
1438 case Instruction::INVOKE_STATIC_RANGE: {
1439 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001440 bool success = DoInvoke<kStatic, true, do_access_check>(
1441 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001442 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1443 break;
1444 }
1445 case Instruction::INVOKE_VIRTUAL_QUICK: {
1446 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001447 bool success = DoInvokeVirtualQuick<false>(
1448 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001449 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1450 break;
1451 }
1452 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1453 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001454 bool success = DoInvokeVirtualQuick<true>(
1455 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001456 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1457 break;
1458 }
1459 case Instruction::NEG_INT:
1460 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001461 shadow_frame.SetVReg(
1462 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001463 inst = inst->Next_1xx();
1464 break;
1465 case Instruction::NOT_INT:
1466 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001467 shadow_frame.SetVReg(
1468 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001469 inst = inst->Next_1xx();
1470 break;
1471 case Instruction::NEG_LONG:
1472 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001473 shadow_frame.SetVRegLong(
1474 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001475 inst = inst->Next_1xx();
1476 break;
1477 case Instruction::NOT_LONG:
1478 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001479 shadow_frame.SetVRegLong(
1480 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001481 inst = inst->Next_1xx();
1482 break;
1483 case Instruction::NEG_FLOAT:
1484 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001485 shadow_frame.SetVRegFloat(
1486 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001487 inst = inst->Next_1xx();
1488 break;
1489 case Instruction::NEG_DOUBLE:
1490 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001491 shadow_frame.SetVRegDouble(
1492 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001493 inst = inst->Next_1xx();
1494 break;
1495 case Instruction::INT_TO_LONG:
1496 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001497 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1498 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001499 inst = inst->Next_1xx();
1500 break;
1501 case Instruction::INT_TO_FLOAT:
1502 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001503 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1504 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001505 inst = inst->Next_1xx();
1506 break;
1507 case Instruction::INT_TO_DOUBLE:
1508 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001509 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1510 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001511 inst = inst->Next_1xx();
1512 break;
1513 case Instruction::LONG_TO_INT:
1514 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001515 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1516 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001517 inst = inst->Next_1xx();
1518 break;
1519 case Instruction::LONG_TO_FLOAT:
1520 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001521 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1522 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001523 inst = inst->Next_1xx();
1524 break;
1525 case Instruction::LONG_TO_DOUBLE:
1526 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001527 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1528 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001529 inst = inst->Next_1xx();
1530 break;
1531 case Instruction::FLOAT_TO_INT: {
1532 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001533 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001534 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001535 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001536 inst = inst->Next_1xx();
1537 break;
1538 }
1539 case Instruction::FLOAT_TO_LONG: {
1540 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001541 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001542 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001543 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001544 inst = inst->Next_1xx();
1545 break;
1546 }
1547 case Instruction::FLOAT_TO_DOUBLE:
1548 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001549 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1550 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001551 inst = inst->Next_1xx();
1552 break;
1553 case Instruction::DOUBLE_TO_INT: {
1554 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001555 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001556 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001557 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001558 inst = inst->Next_1xx();
1559 break;
1560 }
1561 case Instruction::DOUBLE_TO_LONG: {
1562 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001563 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001564 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001565 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001566 inst = inst->Next_1xx();
1567 break;
1568 }
1569 case Instruction::DOUBLE_TO_FLOAT:
1570 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001571 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1572 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001573 inst = inst->Next_1xx();
1574 break;
1575 case Instruction::INT_TO_BYTE:
1576 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001577 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1578 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001579 inst = inst->Next_1xx();
1580 break;
1581 case Instruction::INT_TO_CHAR:
1582 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001583 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1584 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001585 inst = inst->Next_1xx();
1586 break;
1587 case Instruction::INT_TO_SHORT:
1588 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001589 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1590 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001591 inst = inst->Next_1xx();
1592 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001593 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001594 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001595 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001596 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1597 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001598 inst = inst->Next_2xx();
1599 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001600 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001601 case Instruction::SUB_INT:
1602 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001603 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001604 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1605 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001606 inst = inst->Next_2xx();
1607 break;
1608 case Instruction::MUL_INT:
1609 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001610 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001611 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1612 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001613 inst = inst->Next_2xx();
1614 break;
1615 case Instruction::DIV_INT: {
1616 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001617 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001618 shadow_frame.GetVReg(inst->VRegB_23x()),
1619 shadow_frame.GetVReg(inst->VRegC_23x()));
1620 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1621 break;
1622 }
1623 case Instruction::REM_INT: {
1624 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001625 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001626 shadow_frame.GetVReg(inst->VRegB_23x()),
1627 shadow_frame.GetVReg(inst->VRegC_23x()));
1628 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1629 break;
1630 }
1631 case Instruction::SHL_INT:
1632 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001633 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001634 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1635 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1636 inst = inst->Next_2xx();
1637 break;
1638 case Instruction::SHR_INT:
1639 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001640 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001641 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1642 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1643 inst = inst->Next_2xx();
1644 break;
1645 case Instruction::USHR_INT:
1646 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001647 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001648 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1649 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1650 inst = inst->Next_2xx();
1651 break;
1652 case Instruction::AND_INT:
1653 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001654 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001655 shadow_frame.GetVReg(inst->VRegB_23x()) &
1656 shadow_frame.GetVReg(inst->VRegC_23x()));
1657 inst = inst->Next_2xx();
1658 break;
1659 case Instruction::OR_INT:
1660 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001661 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001662 shadow_frame.GetVReg(inst->VRegB_23x()) |
1663 shadow_frame.GetVReg(inst->VRegC_23x()));
1664 inst = inst->Next_2xx();
1665 break;
1666 case Instruction::XOR_INT:
1667 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001668 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001669 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1670 shadow_frame.GetVReg(inst->VRegC_23x()));
1671 inst = inst->Next_2xx();
1672 break;
1673 case Instruction::ADD_LONG:
1674 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001675 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001676 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1677 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001678 inst = inst->Next_2xx();
1679 break;
1680 case Instruction::SUB_LONG:
1681 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001682 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001683 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1684 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001685 inst = inst->Next_2xx();
1686 break;
1687 case Instruction::MUL_LONG:
1688 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001689 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001690 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1691 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001692 inst = inst->Next_2xx();
1693 break;
1694 case Instruction::DIV_LONG:
1695 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001696 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001697 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001698 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001699 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1700 break;
1701 case Instruction::REM_LONG:
1702 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001703 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001704 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1705 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1706 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1707 break;
1708 case Instruction::AND_LONG:
1709 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001710 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001711 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1712 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1713 inst = inst->Next_2xx();
1714 break;
1715 case Instruction::OR_LONG:
1716 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001717 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001718 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1719 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1720 inst = inst->Next_2xx();
1721 break;
1722 case Instruction::XOR_LONG:
1723 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001724 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001725 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1726 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1727 inst = inst->Next_2xx();
1728 break;
1729 case Instruction::SHL_LONG:
1730 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001731 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001732 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1733 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1734 inst = inst->Next_2xx();
1735 break;
1736 case Instruction::SHR_LONG:
1737 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001738 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001739 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1740 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1741 inst = inst->Next_2xx();
1742 break;
1743 case Instruction::USHR_LONG:
1744 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001745 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001746 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1747 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1748 inst = inst->Next_2xx();
1749 break;
1750 case Instruction::ADD_FLOAT:
1751 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001752 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001753 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1754 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1755 inst = inst->Next_2xx();
1756 break;
1757 case Instruction::SUB_FLOAT:
1758 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001759 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001760 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1761 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1762 inst = inst->Next_2xx();
1763 break;
1764 case Instruction::MUL_FLOAT:
1765 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001766 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001767 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1768 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1769 inst = inst->Next_2xx();
1770 break;
1771 case Instruction::DIV_FLOAT:
1772 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001773 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001774 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1775 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1776 inst = inst->Next_2xx();
1777 break;
1778 case Instruction::REM_FLOAT:
1779 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001780 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001781 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1782 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1783 inst = inst->Next_2xx();
1784 break;
1785 case Instruction::ADD_DOUBLE:
1786 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001787 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001788 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1789 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1790 inst = inst->Next_2xx();
1791 break;
1792 case Instruction::SUB_DOUBLE:
1793 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001794 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001795 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1796 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1797 inst = inst->Next_2xx();
1798 break;
1799 case Instruction::MUL_DOUBLE:
1800 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001801 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001802 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1803 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1804 inst = inst->Next_2xx();
1805 break;
1806 case Instruction::DIV_DOUBLE:
1807 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001808 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001809 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1810 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1811 inst = inst->Next_2xx();
1812 break;
1813 case Instruction::REM_DOUBLE:
1814 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001815 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001816 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1817 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1818 inst = inst->Next_2xx();
1819 break;
1820 case Instruction::ADD_INT_2ADDR: {
1821 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001822 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07001823 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
1824 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001825 inst = inst->Next_1xx();
1826 break;
1827 }
1828 case Instruction::SUB_INT_2ADDR: {
1829 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001830 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001831 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001832 SafeSub(shadow_frame.GetVReg(vregA),
1833 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001834 inst = inst->Next_1xx();
1835 break;
1836 }
1837 case Instruction::MUL_INT_2ADDR: {
1838 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001839 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001840 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001841 SafeMul(shadow_frame.GetVReg(vregA),
1842 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001843 inst = inst->Next_1xx();
1844 break;
1845 }
1846 case Instruction::DIV_INT_2ADDR: {
1847 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001848 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001849 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001850 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001851 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1852 break;
1853 }
1854 case Instruction::REM_INT_2ADDR: {
1855 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001856 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001857 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001858 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001859 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1860 break;
1861 }
1862 case Instruction::SHL_INT_2ADDR: {
1863 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001864 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001865 shadow_frame.SetVReg(vregA,
1866 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001867 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001868 inst = inst->Next_1xx();
1869 break;
1870 }
1871 case Instruction::SHR_INT_2ADDR: {
1872 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001873 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001874 shadow_frame.SetVReg(vregA,
1875 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001876 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001877 inst = inst->Next_1xx();
1878 break;
1879 }
1880 case Instruction::USHR_INT_2ADDR: {
1881 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001882 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001883 shadow_frame.SetVReg(vregA,
1884 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001885 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001886 inst = inst->Next_1xx();
1887 break;
1888 }
1889 case Instruction::AND_INT_2ADDR: {
1890 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001891 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001892 shadow_frame.SetVReg(vregA,
1893 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001894 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001895 inst = inst->Next_1xx();
1896 break;
1897 }
1898 case Instruction::OR_INT_2ADDR: {
1899 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001900 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001901 shadow_frame.SetVReg(vregA,
1902 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001903 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001904 inst = inst->Next_1xx();
1905 break;
1906 }
1907 case Instruction::XOR_INT_2ADDR: {
1908 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001909 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001910 shadow_frame.SetVReg(vregA,
1911 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001912 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001913 inst = inst->Next_1xx();
1914 break;
1915 }
1916 case Instruction::ADD_LONG_2ADDR: {
1917 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001918 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001919 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001920 SafeAdd(shadow_frame.GetVRegLong(vregA),
1921 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001922 inst = inst->Next_1xx();
1923 break;
1924 }
1925 case Instruction::SUB_LONG_2ADDR: {
1926 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001927 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001928 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001929 SafeSub(shadow_frame.GetVRegLong(vregA),
1930 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001931 inst = inst->Next_1xx();
1932 break;
1933 }
1934 case Instruction::MUL_LONG_2ADDR: {
1935 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001936 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001937 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001938 SafeMul(shadow_frame.GetVRegLong(vregA),
1939 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001940 inst = inst->Next_1xx();
1941 break;
1942 }
1943 case Instruction::DIV_LONG_2ADDR: {
1944 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001945 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001946 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001947 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001948 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1949 break;
1950 }
1951 case Instruction::REM_LONG_2ADDR: {
1952 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001953 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001954 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001955 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001956 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1957 break;
1958 }
1959 case Instruction::AND_LONG_2ADDR: {
1960 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001961 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001962 shadow_frame.SetVRegLong(vregA,
1963 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001964 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001965 inst = inst->Next_1xx();
1966 break;
1967 }
1968 case Instruction::OR_LONG_2ADDR: {
1969 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001970 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001971 shadow_frame.SetVRegLong(vregA,
1972 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001973 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001974 inst = inst->Next_1xx();
1975 break;
1976 }
1977 case Instruction::XOR_LONG_2ADDR: {
1978 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001979 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001980 shadow_frame.SetVRegLong(vregA,
1981 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001982 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001983 inst = inst->Next_1xx();
1984 break;
1985 }
1986 case Instruction::SHL_LONG_2ADDR: {
1987 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001988 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001989 shadow_frame.SetVRegLong(vregA,
1990 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001991 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001992 inst = inst->Next_1xx();
1993 break;
1994 }
1995 case Instruction::SHR_LONG_2ADDR: {
1996 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001997 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001998 shadow_frame.SetVRegLong(vregA,
1999 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002000 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002001 inst = inst->Next_1xx();
2002 break;
2003 }
2004 case Instruction::USHR_LONG_2ADDR: {
2005 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002006 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002007 shadow_frame.SetVRegLong(vregA,
2008 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002009 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002010 inst = inst->Next_1xx();
2011 break;
2012 }
2013 case Instruction::ADD_FLOAT_2ADDR: {
2014 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002015 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002016 shadow_frame.SetVRegFloat(vregA,
2017 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002018 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002019 inst = inst->Next_1xx();
2020 break;
2021 }
2022 case Instruction::SUB_FLOAT_2ADDR: {
2023 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002024 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002025 shadow_frame.SetVRegFloat(vregA,
2026 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002027 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002028 inst = inst->Next_1xx();
2029 break;
2030 }
2031 case Instruction::MUL_FLOAT_2ADDR: {
2032 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002033 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002034 shadow_frame.SetVRegFloat(vregA,
2035 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002036 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002037 inst = inst->Next_1xx();
2038 break;
2039 }
2040 case Instruction::DIV_FLOAT_2ADDR: {
2041 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002042 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002043 shadow_frame.SetVRegFloat(vregA,
2044 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002045 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002046 inst = inst->Next_1xx();
2047 break;
2048 }
2049 case Instruction::REM_FLOAT_2ADDR: {
2050 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002051 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002052 shadow_frame.SetVRegFloat(vregA,
2053 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002054 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002055 inst = inst->Next_1xx();
2056 break;
2057 }
2058 case Instruction::ADD_DOUBLE_2ADDR: {
2059 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002060 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002061 shadow_frame.SetVRegDouble(vregA,
2062 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002063 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002064 inst = inst->Next_1xx();
2065 break;
2066 }
2067 case Instruction::SUB_DOUBLE_2ADDR: {
2068 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002069 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002070 shadow_frame.SetVRegDouble(vregA,
2071 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002072 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002073 inst = inst->Next_1xx();
2074 break;
2075 }
2076 case Instruction::MUL_DOUBLE_2ADDR: {
2077 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002078 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002079 shadow_frame.SetVRegDouble(vregA,
2080 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002081 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002082 inst = inst->Next_1xx();
2083 break;
2084 }
2085 case Instruction::DIV_DOUBLE_2ADDR: {
2086 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002087 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002088 shadow_frame.SetVRegDouble(vregA,
2089 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002090 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002091 inst = inst->Next_1xx();
2092 break;
2093 }
2094 case Instruction::REM_DOUBLE_2ADDR: {
2095 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002096 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002097 shadow_frame.SetVRegDouble(vregA,
2098 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002099 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002100 inst = inst->Next_1xx();
2101 break;
2102 }
2103 case Instruction::ADD_INT_LIT16:
2104 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002105 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002106 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2107 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002108 inst = inst->Next_2xx();
2109 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002110 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002111 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002112 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002113 SafeSub(inst->VRegC_22s(),
2114 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002115 inst = inst->Next_2xx();
2116 break;
2117 case Instruction::MUL_INT_LIT16:
2118 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002119 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002120 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2121 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002122 inst = inst->Next_2xx();
2123 break;
2124 case Instruction::DIV_INT_LIT16: {
2125 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002126 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002127 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2128 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002129 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2130 break;
2131 }
2132 case Instruction::REM_INT_LIT16: {
2133 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002134 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002135 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2136 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002137 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2138 break;
2139 }
2140 case Instruction::AND_INT_LIT16:
2141 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002142 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2143 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002144 inst->VRegC_22s());
2145 inst = inst->Next_2xx();
2146 break;
2147 case Instruction::OR_INT_LIT16:
2148 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002149 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2150 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002151 inst->VRegC_22s());
2152 inst = inst->Next_2xx();
2153 break;
2154 case Instruction::XOR_INT_LIT16:
2155 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002156 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2157 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002158 inst->VRegC_22s());
2159 inst = inst->Next_2xx();
2160 break;
2161 case Instruction::ADD_INT_LIT8:
2162 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002163 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002164 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002165 inst = inst->Next_2xx();
2166 break;
2167 case Instruction::RSUB_INT_LIT8:
2168 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002169 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002170 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002171 inst = inst->Next_2xx();
2172 break;
2173 case Instruction::MUL_INT_LIT8:
2174 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002175 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002176 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002177 inst = inst->Next_2xx();
2178 break;
2179 case Instruction::DIV_INT_LIT8: {
2180 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002181 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002182 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2183 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2184 break;
2185 }
2186 case Instruction::REM_INT_LIT8: {
2187 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002188 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002189 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2190 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2191 break;
2192 }
2193 case Instruction::AND_INT_LIT8:
2194 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002195 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002196 shadow_frame.GetVReg(inst->VRegB_22b()) &
2197 inst->VRegC_22b());
2198 inst = inst->Next_2xx();
2199 break;
2200 case Instruction::OR_INT_LIT8:
2201 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002202 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002203 shadow_frame.GetVReg(inst->VRegB_22b()) |
2204 inst->VRegC_22b());
2205 inst = inst->Next_2xx();
2206 break;
2207 case Instruction::XOR_INT_LIT8:
2208 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002209 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002210 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2211 inst->VRegC_22b());
2212 inst = inst->Next_2xx();
2213 break;
2214 case Instruction::SHL_INT_LIT8:
2215 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002216 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002217 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2218 (inst->VRegC_22b() & 0x1f));
2219 inst = inst->Next_2xx();
2220 break;
2221 case Instruction::SHR_INT_LIT8:
2222 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002223 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002224 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2225 (inst->VRegC_22b() & 0x1f));
2226 inst = inst->Next_2xx();
2227 break;
2228 case Instruction::USHR_INT_LIT8:
2229 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002230 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002231 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2232 (inst->VRegC_22b() & 0x1f));
2233 inst = inst->Next_2xx();
2234 break;
Igor Murashkin158f35c2015-06-10 15:55:30 -07002235 case Instruction::INVOKE_LAMBDA: {
2236 if (!IsExperimentalInstructionEnabled(inst)) {
2237 UnexpectedOpcode(inst, shadow_frame);
2238 }
2239
2240 PREAMBLE();
2241 bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
2242 &result_register);
2243 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2244 break;
2245 }
Igor Murashkin6918bf12015-09-27 19:19:06 -07002246 case Instruction::CAPTURE_VARIABLE: {
2247 if (!IsExperimentalInstructionEnabled(inst)) {
2248 UnexpectedOpcode(inst, shadow_frame);
2249 }
2250
2251 if (lambda_closure_builder == nullptr) {
2252 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2253 }
2254
2255 PREAMBLE();
2256 bool success = DoCaptureVariable<do_access_check>(self,
2257 inst,
2258 /*inout*/shadow_frame,
2259 /*inout*/lambda_closure_builder.get());
2260 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2261 break;
2262 }
Igor Murashkin158f35c2015-06-10 15:55:30 -07002263 case Instruction::CREATE_LAMBDA: {
2264 if (!IsExperimentalInstructionEnabled(inst)) {
2265 UnexpectedOpcode(inst, shadow_frame);
2266 }
2267
2268 PREAMBLE();
Igor Murashkin6918bf12015-09-27 19:19:06 -07002269
2270 if (lambda_closure_builder == nullptr) {
2271 // DoCreateLambda always needs a ClosureBuilder, even if it has 0 captured variables.
2272 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2273 }
2274
2275 // TODO: these allocations should not leak, and the lambda method should not be local.
2276 lambda::Closure* lambda_closure =
2277 reinterpret_cast<lambda::Closure*>(alloca(lambda_closure_builder->GetSize()));
2278 bool success = DoCreateLambda<do_access_check>(self,
2279 inst,
2280 /*inout*/shadow_frame,
2281 /*inout*/lambda_closure_builder.get(),
2282 /*inout*/lambda_closure);
2283 lambda_closure_builder.reset(nullptr); // reset state of variables captured
Igor Murashkin158f35c2015-06-10 15:55:30 -07002284 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2285 break;
2286 }
Igor Murashkin6918bf12015-09-27 19:19:06 -07002287 case Instruction::LIBERATE_VARIABLE: {
2288 if (!IsExperimentalInstructionEnabled(inst)) {
2289 UnexpectedOpcode(inst, shadow_frame);
2290 }
2291
2292 PREAMBLE();
2293 bool success = DoLiberateVariable<do_access_check>(self,
2294 inst,
2295 lambda_captured_variable_index,
2296 /*inout*/shadow_frame);
2297 // Temporarily only allow sequences of 'liberate-variable, liberate-variable, ...'
2298 lambda_captured_variable_index++;
2299 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2300 break;
2301 }
2302 case Instruction::UNUSED_F4: {
Igor Murashkin158f35c2015-06-10 15:55:30 -07002303 if (!IsExperimentalInstructionEnabled(inst)) {
2304 UnexpectedOpcode(inst, shadow_frame);
2305 }
2306
2307 CHECK(false); // TODO(iam): Implement opcodes for lambdas
2308 break;
2309 }
Igor Murashkin2ee54e22015-06-18 10:05:11 -07002310 case Instruction::BOX_LAMBDA: {
2311 if (!IsExperimentalInstructionEnabled(inst)) {
2312 UnexpectedOpcode(inst, shadow_frame);
2313 }
2314
2315 PREAMBLE();
2316 bool success = DoBoxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2317 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2318 break;
2319 }
2320 case Instruction::UNBOX_LAMBDA: {
2321 if (!IsExperimentalInstructionEnabled(inst)) {
2322 UnexpectedOpcode(inst, shadow_frame);
2323 }
2324
2325 PREAMBLE();
2326 bool success = DoUnboxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2327 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2328 break;
2329 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002330 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Igor Murashkin158f35c2015-06-10 15:55:30 -07002331 case Instruction::UNUSED_FA ... Instruction::UNUSED_FF:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002332 case Instruction::UNUSED_79:
2333 case Instruction::UNUSED_7A:
Ian Rogerse94652f2014-12-02 11:13:19 -08002334 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002335 }
2336 }
2337} // NOLINT(readability/fn_size)
2338
2339// Explicit definitions of ExecuteSwitchImpl.
Mathieu Chartier90443472015-07-16 20:32:27 -07002340template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002341JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002342 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002343template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002344JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002345 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002346template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002347JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002348 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002349template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002350JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002351 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002352
2353} // namespace interpreter
2354} // namespace art