blob: bf95a0e46f7fe687bf84c1ab8fa1e4f795f49d5d [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Igor Murashkin6918bf12015-09-27 19:19:06 -070017#include "base/stl_util.h" // MakeUnique
Alex Lighteb7c1442015-08-31 13:17:42 -070018#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020019#include "interpreter_common.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070020#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020021
Igor Murashkin6918bf12015-09-27 19:19:06 -070022#include <memory> // std::unique_ptr
23
Sebastien Hertz8ece0502013-08-07 11:26:41 +020024namespace art {
25namespace interpreter {
26
27#define HANDLE_PENDING_EXCEPTION() \
28 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020029 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070030 self->AllowThreadSuspension(); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020031 uint32_t found_dex_pc = FindNextInstructionFollowingException(self, shadow_frame, \
32 inst->GetDexPc(insns), \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020033 instrumentation); \
34 if (found_dex_pc == DexFile::kDexNoIndex) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070035 /* Structured locking is to be enforced for abnormal termination, too. */ \
36 shadow_frame.GetLockCountData(). \
37 CheckAllMonitorsReleasedOrThrow<do_assignability_check>(self); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020038 return JValue(); /* Handled in caller. */ \
39 } else { \
40 int32_t displacement = static_cast<int32_t>(found_dex_pc) - static_cast<int32_t>(dex_pc); \
41 inst = inst->RelativeAt(displacement); \
42 } \
43 } while (false)
44
45#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
46 do { \
47 if (UNLIKELY(_is_exception_pending)) { \
48 HANDLE_PENDING_EXCEPTION(); \
49 } else { \
50 inst = inst->_next_function(); \
51 } \
52 } while (false)
53
Andreas Gampe03ec9302015-08-27 17:41:47 -070054#define HANDLE_MONITOR_CHECKS() \
55 if (!shadow_frame.GetLockCountData(). \
56 CheckAllMonitorsReleasedOrThrow<do_assignability_check>(self)) { \
57 HANDLE_PENDING_EXCEPTION(); \
58 }
59
Sebastien Hertz8ece0502013-08-07 11:26:41 +020060// Code to run before each dex instruction.
Sebastien Hertz8379b222014-02-24 17:38:15 +010061#define PREAMBLE() \
62 do { \
Sebastien Hertz9d6bf692015-04-10 12:12:33 +020063 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
Sebastien Hertz8379b222014-02-24 17:38:15 +010064 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), \
65 shadow_frame.GetMethod(), dex_pc); \
66 } \
67 } while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020068
Igor Murashkin158f35c2015-06-10 15:55:30 -070069static bool IsExperimentalInstructionEnabled(const Instruction *inst) {
70 DCHECK(inst->IsExperimental());
Alex Lighteb7c1442015-08-31 13:17:42 -070071 return Runtime::Current()->AreExperimentalFlagsEnabled(ExperimentalFlags::kLambdas);
Igor Murashkin158f35c2015-06-10 15:55:30 -070072}
73
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +010074template<bool do_access_check, bool transaction_active>
Ian Rogerse94652f2014-12-02 11:13:19 -080075JValue ExecuteSwitchImpl(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertz8379b222014-02-24 17:38:15 +010076 ShadowFrame& shadow_frame, JValue result_register) {
Igor Murashkinc449e8b2015-06-10 15:56:42 -070077 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +020078 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
79 LOG(FATAL) << "Invalid shadow frame for interpreter use";
80 return JValue();
81 }
82 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +020083
84 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -070085 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Sebastien Hertz270a0e12015-01-16 19:49:09 +010086 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.
87 if (kIsDebugBuild) {
88 self->AssertNoPendingException();
89 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +020090 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +020091 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +020092 shadow_frame.GetMethod(), 0);
93 }
94 }
95 const uint16_t* const insns = code_item->insns_;
96 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +020097 uint16_t inst_data;
Igor Murashkin6918bf12015-09-27 19:19:06 -070098
99 // TODO: collapse capture-variable+create-lambda into one opcode, then we won't need
100 // to keep this live for the scope of the entire function call.
101 std::unique_ptr<lambda::ClosureBuilder> lambda_closure_builder;
102 size_t lambda_captured_variable_index = 0;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200103 while (true) {
104 dex_pc = inst->GetDexPc(insns);
105 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800106 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200107 inst_data = inst->Fetch16(0);
108 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200109 case Instruction::NOP:
110 PREAMBLE();
111 inst = inst->Next_1xx();
112 break;
113 case Instruction::MOVE:
114 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200115 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
116 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200117 inst = inst->Next_1xx();
118 break;
119 case Instruction::MOVE_FROM16:
120 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200121 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200122 shadow_frame.GetVReg(inst->VRegB_22x()));
123 inst = inst->Next_2xx();
124 break;
125 case Instruction::MOVE_16:
126 PREAMBLE();
127 shadow_frame.SetVReg(inst->VRegA_32x(),
128 shadow_frame.GetVReg(inst->VRegB_32x()));
129 inst = inst->Next_3xx();
130 break;
131 case Instruction::MOVE_WIDE:
132 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200133 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
134 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200135 inst = inst->Next_1xx();
136 break;
137 case Instruction::MOVE_WIDE_FROM16:
138 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200139 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200140 shadow_frame.GetVRegLong(inst->VRegB_22x()));
141 inst = inst->Next_2xx();
142 break;
143 case Instruction::MOVE_WIDE_16:
144 PREAMBLE();
145 shadow_frame.SetVRegLong(inst->VRegA_32x(),
146 shadow_frame.GetVRegLong(inst->VRegB_32x()));
147 inst = inst->Next_3xx();
148 break;
149 case Instruction::MOVE_OBJECT:
150 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200151 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
152 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200153 inst = inst->Next_1xx();
154 break;
155 case Instruction::MOVE_OBJECT_FROM16:
156 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200157 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200158 shadow_frame.GetVRegReference(inst->VRegB_22x()));
159 inst = inst->Next_2xx();
160 break;
161 case Instruction::MOVE_OBJECT_16:
162 PREAMBLE();
163 shadow_frame.SetVRegReference(inst->VRegA_32x(),
164 shadow_frame.GetVRegReference(inst->VRegB_32x()));
165 inst = inst->Next_3xx();
166 break;
167 case Instruction::MOVE_RESULT:
168 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200169 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200170 inst = inst->Next_1xx();
171 break;
172 case Instruction::MOVE_RESULT_WIDE:
173 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200174 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200175 inst = inst->Next_1xx();
176 break;
177 case Instruction::MOVE_RESULT_OBJECT:
178 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200179 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200180 inst = inst->Next_1xx();
181 break;
182 case Instruction::MOVE_EXCEPTION: {
183 PREAMBLE();
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000184 Throwable* exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100185 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200186 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200187 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200188 inst = inst->Next_1xx();
189 break;
190 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700191 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200192 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200193 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700194 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700195 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200196 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200197 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200198 shadow_frame.GetMethod(), inst->GetDexPc(insns),
199 result);
200 }
201 return result;
202 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700203 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200204 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700205 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200206 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700207 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700208 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200209 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200210 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200211 shadow_frame.GetMethod(), inst->GetDexPc(insns),
212 result);
213 }
214 return result;
215 }
216 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200217 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200218 JValue result;
219 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200220 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700221 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700222 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200223 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200224 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200225 shadow_frame.GetMethod(), inst->GetDexPc(insns),
226 result);
227 }
228 return result;
229 }
230 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200231 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200232 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200233 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700234 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700235 HANDLE_MONITOR_CHECKS();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200236 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200237 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200238 shadow_frame.GetMethod(), inst->GetDexPc(insns),
239 result);
240 }
241 return result;
242 }
243 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200244 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200245 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700246 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700247 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700248 const size_t ref_idx = inst->VRegA_11x(inst_data);
249 Object* obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700250 if (do_assignability_check && obj_result != nullptr) {
Vladimir Marko05792b92015-08-03 11:56:49 +0100251 size_t pointer_size = Runtime::Current()->GetClassLinker()->GetImagePointerSize();
252 Class* return_type = shadow_frame.GetMethod()->GetReturnType(true /* resolve */,
253 pointer_size);
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700254 // Re-load since it might have moved.
255 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700256 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700257 // Return the pending exception.
258 HANDLE_PENDING_EXCEPTION();
259 }
260 if (!obj_result->VerifierInstanceOf(return_type)) {
261 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700262 std::string temp1, temp2;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000263 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700264 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700265 obj_result->GetClass()->GetDescriptor(&temp1),
266 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700267 HANDLE_PENDING_EXCEPTION();
268 }
269 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700270 result.SetL(obj_result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200271 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
Sebastien Hertz947ff082013-09-17 14:10:13 +0200272 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200273 shadow_frame.GetMethod(), inst->GetDexPc(insns),
274 result);
275 }
276 return result;
277 }
278 case Instruction::CONST_4: {
279 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200280 uint4_t dst = inst->VRegA_11n(inst_data);
281 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200282 shadow_frame.SetVReg(dst, val);
283 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700284 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200285 }
286 inst = inst->Next_1xx();
287 break;
288 }
289 case Instruction::CONST_16: {
290 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200291 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200292 int16_t val = inst->VRegB_21s();
293 shadow_frame.SetVReg(dst, val);
294 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700295 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200296 }
297 inst = inst->Next_2xx();
298 break;
299 }
300 case Instruction::CONST: {
301 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200302 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200303 int32_t val = inst->VRegB_31i();
304 shadow_frame.SetVReg(dst, val);
305 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700306 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200307 }
308 inst = inst->Next_3xx();
309 break;
310 }
311 case Instruction::CONST_HIGH16: {
312 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200313 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200314 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
315 shadow_frame.SetVReg(dst, val);
316 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700317 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200318 }
319 inst = inst->Next_2xx();
320 break;
321 }
322 case Instruction::CONST_WIDE_16:
323 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200324 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200325 inst = inst->Next_2xx();
326 break;
327 case Instruction::CONST_WIDE_32:
328 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200329 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200330 inst = inst->Next_3xx();
331 break;
332 case Instruction::CONST_WIDE:
333 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200334 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200335 inst = inst->Next_51l();
336 break;
337 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200338 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200339 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200340 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
341 inst = inst->Next_2xx();
342 break;
343 case Instruction::CONST_STRING: {
344 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700345 String* s = ResolveString(self, shadow_frame, inst->VRegB_21c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700346 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200347 HANDLE_PENDING_EXCEPTION();
348 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200349 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200350 inst = inst->Next_2xx();
351 }
352 break;
353 }
354 case Instruction::CONST_STRING_JUMBO: {
355 PREAMBLE();
Ian Rogers6786a582014-10-28 12:49:06 -0700356 String* s = ResolveString(self, shadow_frame, inst->VRegB_31c());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700357 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200358 HANDLE_PENDING_EXCEPTION();
359 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200360 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200361 inst = inst->Next_3xx();
362 }
363 break;
364 }
365 case Instruction::CONST_CLASS: {
366 PREAMBLE();
367 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
368 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700369 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200370 HANDLE_PENDING_EXCEPTION();
371 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200372 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200373 inst = inst->Next_2xx();
374 }
375 break;
376 }
377 case Instruction::MONITOR_ENTER: {
378 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200379 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700380 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000381 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200382 HANDLE_PENDING_EXCEPTION();
383 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700384 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200385 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
386 }
387 break;
388 }
389 case Instruction::MONITOR_EXIT: {
390 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200391 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700392 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000393 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200394 HANDLE_PENDING_EXCEPTION();
395 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700396 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200397 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
398 }
399 break;
400 }
401 case Instruction::CHECK_CAST: {
402 PREAMBLE();
403 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
404 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700405 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200406 HANDLE_PENDING_EXCEPTION();
407 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200408 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700409 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200410 ThrowClassCastException(c, obj->GetClass());
411 HANDLE_PENDING_EXCEPTION();
412 } else {
413 inst = inst->Next_2xx();
414 }
415 }
416 break;
417 }
418 case Instruction::INSTANCE_OF: {
419 PREAMBLE();
420 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(),
421 self, false, do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700422 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200423 HANDLE_PENDING_EXCEPTION();
424 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200425 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700426 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
427 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200428 inst = inst->Next_2xx();
429 }
430 break;
431 }
432 case Instruction::ARRAY_LENGTH: {
433 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200434 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700435 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000436 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200437 HANDLE_PENDING_EXCEPTION();
438 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200439 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200440 inst = inst->Next_1xx();
441 }
442 break;
443 }
444 case Instruction::NEW_INSTANCE: {
445 PREAMBLE();
Jeff Hao848f70a2014-01-15 13:49:50 -0800446 Object* obj = nullptr;
447 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(),
448 self, false, do_access_check);
449 if (LIKELY(c != nullptr)) {
450 if (UNLIKELY(c->IsStringClass())) {
451 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
452 mirror::SetStringCountVisitor visitor(0);
453 obj = String::Alloc<true>(self, 0, allocator_type, visitor);
454 } else {
455 obj = AllocObjectFromCode<do_access_check, true>(
456 inst->VRegB_21c(), shadow_frame.GetMethod(), self,
457 Runtime::Current()->GetHeap()->GetCurrentAllocator());
458 }
459 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700460 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200461 HANDLE_PENDING_EXCEPTION();
462 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200463 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700464 // Don't allow finalizable objects to be allocated during a transaction since these can't
465 // be finalized without a started runtime.
466 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200467 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
468 PrettyTypeOf(obj).c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700469 HANDLE_PENDING_EXCEPTION();
470 break;
471 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200472 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200473 inst = inst->Next_2xx();
474 }
475 break;
476 }
477 case Instruction::NEW_ARRAY: {
478 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200479 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800480 Object* obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampe1cc7dba2014-12-17 18:43:01 -0800481 inst->VRegC_22c(), length, shadow_frame.GetMethod(), self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800482 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700483 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200484 HANDLE_PENDING_EXCEPTION();
485 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200486 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200487 inst = inst->Next_2xx();
488 }
489 break;
490 }
491 case Instruction::FILLED_NEW_ARRAY: {
492 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100493 bool success =
494 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
495 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200496 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
497 break;
498 }
499 case Instruction::FILLED_NEW_ARRAY_RANGE: {
500 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100501 bool success =
502 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
503 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200504 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
505 break;
506 }
507 case Instruction::FILL_ARRAY_DATA: {
508 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200509 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
510 const Instruction::ArrayDataPayload* payload =
511 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Ian Rogers832336b2014-10-08 15:35:22 -0700512 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
513 bool success = FillArrayData(obj, payload);
514 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200515 HANDLE_PENDING_EXCEPTION();
516 break;
517 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100518 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700519 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100520 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200521 inst = inst->Next_3xx();
522 break;
523 }
524 case Instruction::THROW: {
525 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200526 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700527 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000528 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700529 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
530 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700531 std::string temp;
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000532 self->ThrowNewExceptionF("Ljava/lang/VirtualMachineError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700533 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700534 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200535 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000536 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200537 }
538 HANDLE_PENDING_EXCEPTION();
539 break;
540 }
541 case Instruction::GOTO: {
542 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200543 int8_t offset = inst->VRegA_10t(inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200544 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700545 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200546 }
547 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200548 break;
549 }
550 case Instruction::GOTO_16: {
551 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200552 int16_t offset = inst->VRegA_20t();
553 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700554 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200555 }
556 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200557 break;
558 }
559 case Instruction::GOTO_32: {
560 PREAMBLE();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200561 int32_t offset = inst->VRegA_30t();
562 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700563 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200564 }
565 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200566 break;
567 }
568 case Instruction::PACKED_SWITCH: {
569 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200570 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200571 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700572 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200573 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200574 inst = inst->RelativeAt(offset);
575 break;
576 }
577 case Instruction::SPARSE_SWITCH: {
578 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200579 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200580 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700581 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200582 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200583 inst = inst->RelativeAt(offset);
584 break;
585 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700586
587#if defined(__clang__)
588#pragma clang diagnostic push
589#pragma clang diagnostic ignored "-Wfloat-equal"
590#endif
591
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200592 case Instruction::CMPL_FLOAT: {
593 PREAMBLE();
594 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
595 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
596 int32_t result;
597 if (val1 > val2) {
598 result = 1;
599 } else if (val1 == val2) {
600 result = 0;
601 } else {
602 result = -1;
603 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200604 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200605 inst = inst->Next_2xx();
606 break;
607 }
608 case Instruction::CMPG_FLOAT: {
609 PREAMBLE();
610 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
611 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
612 int32_t result;
613 if (val1 < val2) {
614 result = -1;
615 } else if (val1 == val2) {
616 result = 0;
617 } else {
618 result = 1;
619 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200620 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200621 inst = inst->Next_2xx();
622 break;
623 }
624 case Instruction::CMPL_DOUBLE: {
625 PREAMBLE();
626 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
627 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
628 int32_t result;
629 if (val1 > val2) {
630 result = 1;
631 } else if (val1 == val2) {
632 result = 0;
633 } else {
634 result = -1;
635 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200636 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200637 inst = inst->Next_2xx();
638 break;
639 }
640
641 case Instruction::CMPG_DOUBLE: {
642 PREAMBLE();
643 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
644 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
645 int32_t result;
646 if (val1 < val2) {
647 result = -1;
648 } else if (val1 == val2) {
649 result = 0;
650 } else {
651 result = 1;
652 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200653 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200654 inst = inst->Next_2xx();
655 break;
656 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700657
658#if defined(__clang__)
659#pragma clang diagnostic pop
660#endif
661
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200662 case Instruction::CMP_LONG: {
663 PREAMBLE();
664 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
665 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
666 int32_t result;
667 if (val1 > val2) {
668 result = 1;
669 } else if (val1 == val2) {
670 result = 0;
671 } else {
672 result = -1;
673 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200674 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200675 inst = inst->Next_2xx();
676 break;
677 }
678 case Instruction::IF_EQ: {
679 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700680 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
681 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200682 int16_t offset = inst->VRegC_22t();
683 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700684 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200685 }
686 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200687 } else {
688 inst = inst->Next_2xx();
689 }
690 break;
691 }
692 case Instruction::IF_NE: {
693 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700694 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
695 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200696 int16_t offset = inst->VRegC_22t();
697 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700698 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200699 }
700 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200701 } else {
702 inst = inst->Next_2xx();
703 }
704 break;
705 }
706 case Instruction::IF_LT: {
707 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700708 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
709 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200710 int16_t offset = inst->VRegC_22t();
711 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700712 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200713 }
714 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200715 } else {
716 inst = inst->Next_2xx();
717 }
718 break;
719 }
720 case Instruction::IF_GE: {
721 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700722 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
723 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200724 int16_t offset = inst->VRegC_22t();
725 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700726 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200727 }
728 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200729 } else {
730 inst = inst->Next_2xx();
731 }
732 break;
733 }
734 case Instruction::IF_GT: {
735 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700736 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
737 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200738 int16_t offset = inst->VRegC_22t();
739 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700740 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200741 }
742 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200743 } else {
744 inst = inst->Next_2xx();
745 }
746 break;
747 }
748 case Instruction::IF_LE: {
749 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700750 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
751 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200752 int16_t offset = inst->VRegC_22t();
753 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700754 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200755 }
756 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200757 } else {
758 inst = inst->Next_2xx();
759 }
760 break;
761 }
762 case Instruction::IF_EQZ: {
763 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200764 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200765 int16_t offset = inst->VRegB_21t();
766 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700767 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200768 }
769 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200770 } else {
771 inst = inst->Next_2xx();
772 }
773 break;
774 }
775 case Instruction::IF_NEZ: {
776 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200777 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200778 int16_t offset = inst->VRegB_21t();
779 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700780 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200781 }
782 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200783 } else {
784 inst = inst->Next_2xx();
785 }
786 break;
787 }
788 case Instruction::IF_LTZ: {
789 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200790 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200791 int16_t offset = inst->VRegB_21t();
792 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700793 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200794 }
795 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200796 } else {
797 inst = inst->Next_2xx();
798 }
799 break;
800 }
801 case Instruction::IF_GEZ: {
802 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200803 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200804 int16_t offset = inst->VRegB_21t();
805 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700806 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200807 }
808 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200809 } else {
810 inst = inst->Next_2xx();
811 }
812 break;
813 }
814 case Instruction::IF_GTZ: {
815 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200816 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200817 int16_t offset = inst->VRegB_21t();
818 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700819 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200820 }
821 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200822 } else {
823 inst = inst->Next_2xx();
824 }
825 break;
826 }
827 case Instruction::IF_LEZ: {
828 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200829 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200830 int16_t offset = inst->VRegB_21t();
831 if (IsBackwardBranch(offset)) {
Ian Rogers7b078e82014-09-10 14:44:24 -0700832 self->AllowThreadSuspension();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200833 }
834 inst = inst->RelativeAt(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200835 } else {
836 inst = inst->Next_2xx();
837 }
838 break;
839 }
840 case Instruction::AGET_BOOLEAN: {
841 PREAMBLE();
842 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700843 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000844 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200845 HANDLE_PENDING_EXCEPTION();
846 break;
847 }
848 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
849 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700850 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100851 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200852 inst = inst->Next_2xx();
853 } else {
854 HANDLE_PENDING_EXCEPTION();
855 }
856 break;
857 }
858 case Instruction::AGET_BYTE: {
859 PREAMBLE();
860 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700861 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000862 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200863 HANDLE_PENDING_EXCEPTION();
864 break;
865 }
866 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
867 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700868 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100869 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200870 inst = inst->Next_2xx();
871 } else {
872 HANDLE_PENDING_EXCEPTION();
873 }
874 break;
875 }
876 case Instruction::AGET_CHAR: {
877 PREAMBLE();
878 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700879 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000880 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200881 HANDLE_PENDING_EXCEPTION();
882 break;
883 }
884 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
885 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700886 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100887 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200888 inst = inst->Next_2xx();
889 } else {
890 HANDLE_PENDING_EXCEPTION();
891 }
892 break;
893 }
894 case Instruction::AGET_SHORT: {
895 PREAMBLE();
896 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700897 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000898 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200899 HANDLE_PENDING_EXCEPTION();
900 break;
901 }
902 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
903 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700904 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100905 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200906 inst = inst->Next_2xx();
907 } else {
908 HANDLE_PENDING_EXCEPTION();
909 }
910 break;
911 }
912 case Instruction::AGET: {
913 PREAMBLE();
914 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700915 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000916 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200917 HANDLE_PENDING_EXCEPTION();
918 break;
919 }
920 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700921 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
922 auto* array = down_cast<IntArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700923 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100924 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200925 inst = inst->Next_2xx();
926 } else {
927 HANDLE_PENDING_EXCEPTION();
928 }
929 break;
930 }
931 case Instruction::AGET_WIDE: {
932 PREAMBLE();
933 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700934 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000935 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200936 HANDLE_PENDING_EXCEPTION();
937 break;
938 }
939 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -0700940 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
941 auto* array = down_cast<LongArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700942 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +0100943 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200944 inst = inst->Next_2xx();
945 } else {
946 HANDLE_PENDING_EXCEPTION();
947 }
948 break;
949 }
950 case Instruction::AGET_OBJECT: {
951 PREAMBLE();
952 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700953 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000954 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200955 HANDLE_PENDING_EXCEPTION();
956 break;
957 }
958 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
959 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700960 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200961 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200962 inst = inst->Next_2xx();
963 } else {
964 HANDLE_PENDING_EXCEPTION();
965 }
966 break;
967 }
968 case Instruction::APUT_BOOLEAN: {
969 PREAMBLE();
970 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700971 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000972 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200973 HANDLE_PENDING_EXCEPTION();
974 break;
975 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200976 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200977 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
978 BooleanArray* array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700979 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100980 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200981 inst = inst->Next_2xx();
982 } else {
983 HANDLE_PENDING_EXCEPTION();
984 }
985 break;
986 }
987 case Instruction::APUT_BYTE: {
988 PREAMBLE();
989 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700990 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000991 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200992 HANDLE_PENDING_EXCEPTION();
993 break;
994 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200995 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200996 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
997 ByteArray* array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -0700998 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100999 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001000 inst = inst->Next_2xx();
1001 } else {
1002 HANDLE_PENDING_EXCEPTION();
1003 }
1004 break;
1005 }
1006 case Instruction::APUT_CHAR: {
1007 PREAMBLE();
1008 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001009 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001010 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001011 HANDLE_PENDING_EXCEPTION();
1012 break;
1013 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001014 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001015 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1016 CharArray* array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001017 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001018 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001019 inst = inst->Next_2xx();
1020 } else {
1021 HANDLE_PENDING_EXCEPTION();
1022 }
1023 break;
1024 }
1025 case Instruction::APUT_SHORT: {
1026 PREAMBLE();
1027 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001028 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001029 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001030 HANDLE_PENDING_EXCEPTION();
1031 break;
1032 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001033 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001034 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
1035 ShortArray* array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001036 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001037 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001038 inst = inst->Next_2xx();
1039 } else {
1040 HANDLE_PENDING_EXCEPTION();
1041 }
1042 break;
1043 }
1044 case Instruction::APUT: {
1045 PREAMBLE();
1046 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001047 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001048 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001049 HANDLE_PENDING_EXCEPTION();
1050 break;
1051 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001052 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001053 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001054 DCHECK(a->IsIntArray() || a->IsFloatArray()) << PrettyTypeOf(a);
1055 auto* array = down_cast<IntArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001056 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001057 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001058 inst = inst->Next_2xx();
1059 } else {
1060 HANDLE_PENDING_EXCEPTION();
1061 }
1062 break;
1063 }
1064 case Instruction::APUT_WIDE: {
1065 PREAMBLE();
1066 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001067 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001068 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001069 HANDLE_PENDING_EXCEPTION();
1070 break;
1071 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001072 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001073 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartiere401d142015-04-22 13:56:20 -07001074 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << PrettyTypeOf(a);
1075 LongArray* array = down_cast<LongArray*>(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001076 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001077 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001078 inst = inst->Next_2xx();
1079 } else {
1080 HANDLE_PENDING_EXCEPTION();
1081 }
1082 break;
1083 }
1084 case Instruction::APUT_OBJECT: {
1085 PREAMBLE();
1086 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001087 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001088 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001089 HANDLE_PENDING_EXCEPTION();
1090 break;
1091 }
1092 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001093 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001094 ObjectArray<Object>* array = a->AsObjectArray<Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001095 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001096 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001097 inst = inst->Next_2xx();
1098 } else {
1099 HANDLE_PENDING_EXCEPTION();
1100 }
1101 break;
1102 }
1103 case Instruction::IGET_BOOLEAN: {
1104 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001105 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1106 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001107 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1108 break;
1109 }
1110 case Instruction::IGET_BYTE: {
1111 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001112 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1113 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001114 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1115 break;
1116 }
1117 case Instruction::IGET_CHAR: {
1118 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001119 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1120 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001121 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1122 break;
1123 }
1124 case Instruction::IGET_SHORT: {
1125 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001126 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1127 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001128 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1129 break;
1130 }
1131 case Instruction::IGET: {
1132 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001133 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1134 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001135 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1136 break;
1137 }
1138 case Instruction::IGET_WIDE: {
1139 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001140 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1141 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001142 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1143 break;
1144 }
1145 case Instruction::IGET_OBJECT: {
1146 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001147 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1148 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001149 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1150 break;
1151 }
1152 case Instruction::IGET_QUICK: {
1153 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001154 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001155 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1156 break;
1157 }
1158 case Instruction::IGET_WIDE_QUICK: {
1159 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001160 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001161 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1162 break;
1163 }
1164 case Instruction::IGET_OBJECT_QUICK: {
1165 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001166 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001167 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1168 break;
1169 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001170 case Instruction::IGET_BOOLEAN_QUICK: {
1171 PREAMBLE();
1172 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1173 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1174 break;
1175 }
1176 case Instruction::IGET_BYTE_QUICK: {
1177 PREAMBLE();
1178 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1179 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1180 break;
1181 }
1182 case Instruction::IGET_CHAR_QUICK: {
1183 PREAMBLE();
1184 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1185 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1186 break;
1187 }
1188 case Instruction::IGET_SHORT_QUICK: {
1189 PREAMBLE();
1190 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1191 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1192 break;
1193 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001194 case Instruction::SGET_BOOLEAN: {
1195 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001196 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1197 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001198 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1199 break;
1200 }
1201 case Instruction::SGET_BYTE: {
1202 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001203 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(
1204 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001205 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1206 break;
1207 }
1208 case Instruction::SGET_CHAR: {
1209 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001210 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(
1211 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001212 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1213 break;
1214 }
1215 case Instruction::SGET_SHORT: {
1216 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001217 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(
1218 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001219 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1220 break;
1221 }
1222 case Instruction::SGET: {
1223 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001224 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(
1225 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001226 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1227 break;
1228 }
1229 case Instruction::SGET_WIDE: {
1230 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001231 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(
1232 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001233 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1234 break;
1235 }
1236 case Instruction::SGET_OBJECT: {
1237 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001238 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(
1239 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001240 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1241 break;
1242 }
1243 case Instruction::IPUT_BOOLEAN: {
1244 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001245 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1246 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001247 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1248 break;
1249 }
1250 case Instruction::IPUT_BYTE: {
1251 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001252 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1253 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001254 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1255 break;
1256 }
1257 case Instruction::IPUT_CHAR: {
1258 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001259 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1260 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001261 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1262 break;
1263 }
1264 case Instruction::IPUT_SHORT: {
1265 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001266 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1267 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001268 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1269 break;
1270 }
1271 case Instruction::IPUT: {
1272 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001273 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1274 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001275 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1276 break;
1277 }
1278 case Instruction::IPUT_WIDE: {
1279 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001280 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1281 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001282 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1283 break;
1284 }
1285 case Instruction::IPUT_OBJECT: {
1286 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001287 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1288 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001289 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1290 break;
1291 }
1292 case Instruction::IPUT_QUICK: {
1293 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001294 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1295 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001296 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1297 break;
1298 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001299 case Instruction::IPUT_BOOLEAN_QUICK: {
1300 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001301 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1302 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001303 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1304 break;
1305 }
1306 case Instruction::IPUT_BYTE_QUICK: {
1307 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001308 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1309 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001310 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1311 break;
1312 }
1313 case Instruction::IPUT_CHAR_QUICK: {
1314 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001315 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1316 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001317 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1318 break;
1319 }
1320 case Instruction::IPUT_SHORT_QUICK: {
1321 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001322 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1323 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001324 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1325 break;
1326 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001327 case Instruction::IPUT_WIDE_QUICK: {
1328 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001329 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1330 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001331 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1332 break;
1333 }
1334 case Instruction::IPUT_OBJECT_QUICK: {
1335 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001336 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1337 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001338 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1339 break;
1340 }
1341 case Instruction::SPUT_BOOLEAN: {
1342 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001343 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1344 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001345 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1346 break;
1347 }
1348 case Instruction::SPUT_BYTE: {
1349 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001350 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1351 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001352 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1353 break;
1354 }
1355 case Instruction::SPUT_CHAR: {
1356 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001357 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1358 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001359 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1360 break;
1361 }
1362 case Instruction::SPUT_SHORT: {
1363 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001364 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1365 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001366 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1367 break;
1368 }
1369 case Instruction::SPUT: {
1370 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001371 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1372 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001373 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1374 break;
1375 }
1376 case Instruction::SPUT_WIDE: {
1377 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001378 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1379 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001380 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1381 break;
1382 }
1383 case Instruction::SPUT_OBJECT: {
1384 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001385 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1386 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001387 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1388 break;
1389 }
1390 case Instruction::INVOKE_VIRTUAL: {
1391 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001392 bool success = DoInvoke<kVirtual, false, do_access_check>(
1393 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001394 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1395 break;
1396 }
1397 case Instruction::INVOKE_VIRTUAL_RANGE: {
1398 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001399 bool success = DoInvoke<kVirtual, true, do_access_check>(
1400 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001401 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1402 break;
1403 }
1404 case Instruction::INVOKE_SUPER: {
1405 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001406 bool success = DoInvoke<kSuper, false, do_access_check>(
1407 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001408 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1409 break;
1410 }
1411 case Instruction::INVOKE_SUPER_RANGE: {
1412 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001413 bool success = DoInvoke<kSuper, true, do_access_check>(
1414 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001415 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1416 break;
1417 }
1418 case Instruction::INVOKE_DIRECT: {
1419 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001420 bool success = DoInvoke<kDirect, false, do_access_check>(
1421 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001422 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1423 break;
1424 }
1425 case Instruction::INVOKE_DIRECT_RANGE: {
1426 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001427 bool success = DoInvoke<kDirect, true, do_access_check>(
1428 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001429 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1430 break;
1431 }
1432 case Instruction::INVOKE_INTERFACE: {
1433 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001434 bool success = DoInvoke<kInterface, false, do_access_check>(
1435 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001436 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1437 break;
1438 }
1439 case Instruction::INVOKE_INTERFACE_RANGE: {
1440 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001441 bool success = DoInvoke<kInterface, true, do_access_check>(
1442 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001443 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1444 break;
1445 }
1446 case Instruction::INVOKE_STATIC: {
1447 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001448 bool success = DoInvoke<kStatic, false, do_access_check>(
1449 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001450 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1451 break;
1452 }
1453 case Instruction::INVOKE_STATIC_RANGE: {
1454 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001455 bool success = DoInvoke<kStatic, true, do_access_check>(
1456 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001457 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1458 break;
1459 }
1460 case Instruction::INVOKE_VIRTUAL_QUICK: {
1461 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001462 bool success = DoInvokeVirtualQuick<false>(
1463 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001464 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1465 break;
1466 }
1467 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1468 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001469 bool success = DoInvokeVirtualQuick<true>(
1470 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001471 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1472 break;
1473 }
1474 case Instruction::NEG_INT:
1475 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001476 shadow_frame.SetVReg(
1477 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001478 inst = inst->Next_1xx();
1479 break;
1480 case Instruction::NOT_INT:
1481 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001482 shadow_frame.SetVReg(
1483 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001484 inst = inst->Next_1xx();
1485 break;
1486 case Instruction::NEG_LONG:
1487 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001488 shadow_frame.SetVRegLong(
1489 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001490 inst = inst->Next_1xx();
1491 break;
1492 case Instruction::NOT_LONG:
1493 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001494 shadow_frame.SetVRegLong(
1495 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001496 inst = inst->Next_1xx();
1497 break;
1498 case Instruction::NEG_FLOAT:
1499 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001500 shadow_frame.SetVRegFloat(
1501 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001502 inst = inst->Next_1xx();
1503 break;
1504 case Instruction::NEG_DOUBLE:
1505 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001506 shadow_frame.SetVRegDouble(
1507 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001508 inst = inst->Next_1xx();
1509 break;
1510 case Instruction::INT_TO_LONG:
1511 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001512 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1513 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001514 inst = inst->Next_1xx();
1515 break;
1516 case Instruction::INT_TO_FLOAT:
1517 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001518 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1519 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001520 inst = inst->Next_1xx();
1521 break;
1522 case Instruction::INT_TO_DOUBLE:
1523 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001524 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1525 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001526 inst = inst->Next_1xx();
1527 break;
1528 case Instruction::LONG_TO_INT:
1529 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001530 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1531 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001532 inst = inst->Next_1xx();
1533 break;
1534 case Instruction::LONG_TO_FLOAT:
1535 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001536 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1537 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001538 inst = inst->Next_1xx();
1539 break;
1540 case Instruction::LONG_TO_DOUBLE:
1541 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001542 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1543 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001544 inst = inst->Next_1xx();
1545 break;
1546 case Instruction::FLOAT_TO_INT: {
1547 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001548 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001549 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001550 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001551 inst = inst->Next_1xx();
1552 break;
1553 }
1554 case Instruction::FLOAT_TO_LONG: {
1555 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001556 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001557 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001558 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001559 inst = inst->Next_1xx();
1560 break;
1561 }
1562 case Instruction::FLOAT_TO_DOUBLE:
1563 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001564 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1565 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001566 inst = inst->Next_1xx();
1567 break;
1568 case Instruction::DOUBLE_TO_INT: {
1569 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001570 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001571 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001572 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001573 inst = inst->Next_1xx();
1574 break;
1575 }
1576 case Instruction::DOUBLE_TO_LONG: {
1577 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001578 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001579 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001580 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001581 inst = inst->Next_1xx();
1582 break;
1583 }
1584 case Instruction::DOUBLE_TO_FLOAT:
1585 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001586 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1587 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001588 inst = inst->Next_1xx();
1589 break;
1590 case Instruction::INT_TO_BYTE:
1591 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001592 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1593 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001594 inst = inst->Next_1xx();
1595 break;
1596 case Instruction::INT_TO_CHAR:
1597 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001598 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1599 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001600 inst = inst->Next_1xx();
1601 break;
1602 case Instruction::INT_TO_SHORT:
1603 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001604 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1605 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001606 inst = inst->Next_1xx();
1607 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001608 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001609 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 SafeAdd(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;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001615 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001616 case Instruction::SUB_INT:
1617 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001618 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001619 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1620 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001621 inst = inst->Next_2xx();
1622 break;
1623 case Instruction::MUL_INT:
1624 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001625 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001626 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1627 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001628 inst = inst->Next_2xx();
1629 break;
1630 case Instruction::DIV_INT: {
1631 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001632 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001633 shadow_frame.GetVReg(inst->VRegB_23x()),
1634 shadow_frame.GetVReg(inst->VRegC_23x()));
1635 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1636 break;
1637 }
1638 case Instruction::REM_INT: {
1639 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001640 bool success = DoIntRemainder(shadow_frame, 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()));
1643 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1644 break;
1645 }
1646 case Instruction::SHL_INT:
1647 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001648 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001649 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1650 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1651 inst = inst->Next_2xx();
1652 break;
1653 case Instruction::SHR_INT:
1654 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001655 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001656 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1657 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1658 inst = inst->Next_2xx();
1659 break;
1660 case Instruction::USHR_INT:
1661 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001662 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001663 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1664 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1665 inst = inst->Next_2xx();
1666 break;
1667 case Instruction::AND_INT:
1668 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001669 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001670 shadow_frame.GetVReg(inst->VRegB_23x()) &
1671 shadow_frame.GetVReg(inst->VRegC_23x()));
1672 inst = inst->Next_2xx();
1673 break;
1674 case Instruction::OR_INT:
1675 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001676 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001677 shadow_frame.GetVReg(inst->VRegB_23x()) |
1678 shadow_frame.GetVReg(inst->VRegC_23x()));
1679 inst = inst->Next_2xx();
1680 break;
1681 case Instruction::XOR_INT:
1682 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001683 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001684 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1685 shadow_frame.GetVReg(inst->VRegC_23x()));
1686 inst = inst->Next_2xx();
1687 break;
1688 case Instruction::ADD_LONG:
1689 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001690 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001691 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1692 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001693 inst = inst->Next_2xx();
1694 break;
1695 case Instruction::SUB_LONG:
1696 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001697 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001698 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1699 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001700 inst = inst->Next_2xx();
1701 break;
1702 case Instruction::MUL_LONG:
1703 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001704 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001705 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1706 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001707 inst = inst->Next_2xx();
1708 break;
1709 case Instruction::DIV_LONG:
1710 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001711 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001712 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001713 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001714 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1715 break;
1716 case Instruction::REM_LONG:
1717 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001718 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001719 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1720 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1721 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1722 break;
1723 case Instruction::AND_LONG:
1724 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001725 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001726 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1727 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1728 inst = inst->Next_2xx();
1729 break;
1730 case Instruction::OR_LONG:
1731 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001732 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001733 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1734 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1735 inst = inst->Next_2xx();
1736 break;
1737 case Instruction::XOR_LONG:
1738 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001739 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001740 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1741 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1742 inst = inst->Next_2xx();
1743 break;
1744 case Instruction::SHL_LONG:
1745 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001746 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001747 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1748 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1749 inst = inst->Next_2xx();
1750 break;
1751 case Instruction::SHR_LONG:
1752 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001753 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001754 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1755 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1756 inst = inst->Next_2xx();
1757 break;
1758 case Instruction::USHR_LONG:
1759 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001760 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001761 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1762 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1763 inst = inst->Next_2xx();
1764 break;
1765 case Instruction::ADD_FLOAT:
1766 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001767 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001768 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1769 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1770 inst = inst->Next_2xx();
1771 break;
1772 case Instruction::SUB_FLOAT:
1773 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001774 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001775 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
1776 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1777 inst = inst->Next_2xx();
1778 break;
1779 case Instruction::MUL_FLOAT:
1780 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001781 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001782 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
1783 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1784 inst = inst->Next_2xx();
1785 break;
1786 case Instruction::DIV_FLOAT:
1787 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001788 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001789 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
1790 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1791 inst = inst->Next_2xx();
1792 break;
1793 case Instruction::REM_FLOAT:
1794 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001795 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001796 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
1797 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
1798 inst = inst->Next_2xx();
1799 break;
1800 case Instruction::ADD_DOUBLE:
1801 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001802 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001803 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
1804 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1805 inst = inst->Next_2xx();
1806 break;
1807 case Instruction::SUB_DOUBLE:
1808 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001809 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001810 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
1811 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1812 inst = inst->Next_2xx();
1813 break;
1814 case Instruction::MUL_DOUBLE:
1815 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001816 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001817 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
1818 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1819 inst = inst->Next_2xx();
1820 break;
1821 case Instruction::DIV_DOUBLE:
1822 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001823 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001824 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
1825 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
1826 inst = inst->Next_2xx();
1827 break;
1828 case Instruction::REM_DOUBLE:
1829 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001830 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001831 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
1832 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
1833 inst = inst->Next_2xx();
1834 break;
1835 case Instruction::ADD_INT_2ADDR: {
1836 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001837 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07001838 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
1839 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001840 inst = inst->Next_1xx();
1841 break;
1842 }
1843 case Instruction::SUB_INT_2ADDR: {
1844 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001845 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001846 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001847 SafeSub(shadow_frame.GetVReg(vregA),
1848 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001849 inst = inst->Next_1xx();
1850 break;
1851 }
1852 case Instruction::MUL_INT_2ADDR: {
1853 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001854 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001855 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001856 SafeMul(shadow_frame.GetVReg(vregA),
1857 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001858 inst = inst->Next_1xx();
1859 break;
1860 }
1861 case Instruction::DIV_INT_2ADDR: {
1862 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001863 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001864 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001865 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001866 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1867 break;
1868 }
1869 case Instruction::REM_INT_2ADDR: {
1870 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001871 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001872 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001873 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001874 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
1875 break;
1876 }
1877 case Instruction::SHL_INT_2ADDR: {
1878 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001879 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001880 shadow_frame.SetVReg(vregA,
1881 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001882 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001883 inst = inst->Next_1xx();
1884 break;
1885 }
1886 case Instruction::SHR_INT_2ADDR: {
1887 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001888 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001889 shadow_frame.SetVReg(vregA,
1890 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001891 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001892 inst = inst->Next_1xx();
1893 break;
1894 }
1895 case Instruction::USHR_INT_2ADDR: {
1896 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001897 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001898 shadow_frame.SetVReg(vregA,
1899 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001900 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001901 inst = inst->Next_1xx();
1902 break;
1903 }
1904 case Instruction::AND_INT_2ADDR: {
1905 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001906 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001907 shadow_frame.SetVReg(vregA,
1908 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001909 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001910 inst = inst->Next_1xx();
1911 break;
1912 }
1913 case Instruction::OR_INT_2ADDR: {
1914 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001915 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001916 shadow_frame.SetVReg(vregA,
1917 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001918 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001919 inst = inst->Next_1xx();
1920 break;
1921 }
1922 case Instruction::XOR_INT_2ADDR: {
1923 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001924 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001925 shadow_frame.SetVReg(vregA,
1926 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001927 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001928 inst = inst->Next_1xx();
1929 break;
1930 }
1931 case Instruction::ADD_LONG_2ADDR: {
1932 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001933 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001934 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001935 SafeAdd(shadow_frame.GetVRegLong(vregA),
1936 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001937 inst = inst->Next_1xx();
1938 break;
1939 }
1940 case Instruction::SUB_LONG_2ADDR: {
1941 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001942 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001943 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001944 SafeSub(shadow_frame.GetVRegLong(vregA),
1945 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001946 inst = inst->Next_1xx();
1947 break;
1948 }
1949 case Instruction::MUL_LONG_2ADDR: {
1950 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001951 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001952 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07001953 SafeMul(shadow_frame.GetVRegLong(vregA),
1954 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001955 inst = inst->Next_1xx();
1956 break;
1957 }
1958 case Instruction::DIV_LONG_2ADDR: {
1959 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001960 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001961 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001962 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001963 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1964 break;
1965 }
1966 case Instruction::REM_LONG_2ADDR: {
1967 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001968 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001969 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001970 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001971 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
1972 break;
1973 }
1974 case Instruction::AND_LONG_2ADDR: {
1975 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001976 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001977 shadow_frame.SetVRegLong(vregA,
1978 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001979 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001980 inst = inst->Next_1xx();
1981 break;
1982 }
1983 case Instruction::OR_LONG_2ADDR: {
1984 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001985 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001986 shadow_frame.SetVRegLong(vregA,
1987 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001988 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001989 inst = inst->Next_1xx();
1990 break;
1991 }
1992 case Instruction::XOR_LONG_2ADDR: {
1993 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001994 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001995 shadow_frame.SetVRegLong(vregA,
1996 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001997 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001998 inst = inst->Next_1xx();
1999 break;
2000 }
2001 case Instruction::SHL_LONG_2ADDR: {
2002 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002003 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002004 shadow_frame.SetVRegLong(vregA,
2005 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002006 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002007 inst = inst->Next_1xx();
2008 break;
2009 }
2010 case Instruction::SHR_LONG_2ADDR: {
2011 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002012 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002013 shadow_frame.SetVRegLong(vregA,
2014 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002015 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002016 inst = inst->Next_1xx();
2017 break;
2018 }
2019 case Instruction::USHR_LONG_2ADDR: {
2020 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002021 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002022 shadow_frame.SetVRegLong(vregA,
2023 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002024 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002025 inst = inst->Next_1xx();
2026 break;
2027 }
2028 case Instruction::ADD_FLOAT_2ADDR: {
2029 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002030 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002031 shadow_frame.SetVRegFloat(vregA,
2032 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002033 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002034 inst = inst->Next_1xx();
2035 break;
2036 }
2037 case Instruction::SUB_FLOAT_2ADDR: {
2038 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002039 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002040 shadow_frame.SetVRegFloat(vregA,
2041 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002042 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002043 inst = inst->Next_1xx();
2044 break;
2045 }
2046 case Instruction::MUL_FLOAT_2ADDR: {
2047 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002048 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002049 shadow_frame.SetVRegFloat(vregA,
2050 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002051 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002052 inst = inst->Next_1xx();
2053 break;
2054 }
2055 case Instruction::DIV_FLOAT_2ADDR: {
2056 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002057 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002058 shadow_frame.SetVRegFloat(vregA,
2059 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002060 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002061 inst = inst->Next_1xx();
2062 break;
2063 }
2064 case Instruction::REM_FLOAT_2ADDR: {
2065 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002066 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002067 shadow_frame.SetVRegFloat(vregA,
2068 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002069 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002070 inst = inst->Next_1xx();
2071 break;
2072 }
2073 case Instruction::ADD_DOUBLE_2ADDR: {
2074 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002075 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002076 shadow_frame.SetVRegDouble(vregA,
2077 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002078 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002079 inst = inst->Next_1xx();
2080 break;
2081 }
2082 case Instruction::SUB_DOUBLE_2ADDR: {
2083 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002084 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002085 shadow_frame.SetVRegDouble(vregA,
2086 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002087 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002088 inst = inst->Next_1xx();
2089 break;
2090 }
2091 case Instruction::MUL_DOUBLE_2ADDR: {
2092 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002093 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002094 shadow_frame.SetVRegDouble(vregA,
2095 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002096 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002097 inst = inst->Next_1xx();
2098 break;
2099 }
2100 case Instruction::DIV_DOUBLE_2ADDR: {
2101 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002102 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002103 shadow_frame.SetVRegDouble(vregA,
2104 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002105 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002106 inst = inst->Next_1xx();
2107 break;
2108 }
2109 case Instruction::REM_DOUBLE_2ADDR: {
2110 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002111 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002112 shadow_frame.SetVRegDouble(vregA,
2113 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002114 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002115 inst = inst->Next_1xx();
2116 break;
2117 }
2118 case Instruction::ADD_INT_LIT16:
2119 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002120 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002121 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2122 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002123 inst = inst->Next_2xx();
2124 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002125 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002126 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002127 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002128 SafeSub(inst->VRegC_22s(),
2129 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002130 inst = inst->Next_2xx();
2131 break;
2132 case Instruction::MUL_INT_LIT16:
2133 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002134 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002135 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2136 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002137 inst = inst->Next_2xx();
2138 break;
2139 case Instruction::DIV_INT_LIT16: {
2140 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002141 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002142 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2143 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002144 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2145 break;
2146 }
2147 case Instruction::REM_INT_LIT16: {
2148 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002149 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002150 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2151 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002152 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2153 break;
2154 }
2155 case Instruction::AND_INT_LIT16:
2156 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002157 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2158 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002159 inst->VRegC_22s());
2160 inst = inst->Next_2xx();
2161 break;
2162 case Instruction::OR_INT_LIT16:
2163 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002164 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2165 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002166 inst->VRegC_22s());
2167 inst = inst->Next_2xx();
2168 break;
2169 case Instruction::XOR_INT_LIT16:
2170 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002171 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2172 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002173 inst->VRegC_22s());
2174 inst = inst->Next_2xx();
2175 break;
2176 case Instruction::ADD_INT_LIT8:
2177 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002178 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002179 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002180 inst = inst->Next_2xx();
2181 break;
2182 case Instruction::RSUB_INT_LIT8:
2183 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002184 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002185 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002186 inst = inst->Next_2xx();
2187 break;
2188 case Instruction::MUL_INT_LIT8:
2189 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002190 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002191 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002192 inst = inst->Next_2xx();
2193 break;
2194 case Instruction::DIV_INT_LIT8: {
2195 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002196 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002197 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2198 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2199 break;
2200 }
2201 case Instruction::REM_INT_LIT8: {
2202 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002203 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002204 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2205 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2206 break;
2207 }
2208 case Instruction::AND_INT_LIT8:
2209 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002210 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002211 shadow_frame.GetVReg(inst->VRegB_22b()) &
2212 inst->VRegC_22b());
2213 inst = inst->Next_2xx();
2214 break;
2215 case Instruction::OR_INT_LIT8:
2216 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002217 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002218 shadow_frame.GetVReg(inst->VRegB_22b()) |
2219 inst->VRegC_22b());
2220 inst = inst->Next_2xx();
2221 break;
2222 case Instruction::XOR_INT_LIT8:
2223 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002224 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002225 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2226 inst->VRegC_22b());
2227 inst = inst->Next_2xx();
2228 break;
2229 case Instruction::SHL_INT_LIT8:
2230 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002231 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002232 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2233 (inst->VRegC_22b() & 0x1f));
2234 inst = inst->Next_2xx();
2235 break;
2236 case Instruction::SHR_INT_LIT8:
2237 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002238 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002239 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2240 (inst->VRegC_22b() & 0x1f));
2241 inst = inst->Next_2xx();
2242 break;
2243 case Instruction::USHR_INT_LIT8:
2244 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002245 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002246 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2247 (inst->VRegC_22b() & 0x1f));
2248 inst = inst->Next_2xx();
2249 break;
Igor Murashkin158f35c2015-06-10 15:55:30 -07002250 case Instruction::INVOKE_LAMBDA: {
2251 if (!IsExperimentalInstructionEnabled(inst)) {
2252 UnexpectedOpcode(inst, shadow_frame);
2253 }
2254
2255 PREAMBLE();
2256 bool success = DoInvokeLambda<do_access_check>(self, shadow_frame, inst, inst_data,
2257 &result_register);
2258 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2259 break;
2260 }
Igor Murashkin6918bf12015-09-27 19:19:06 -07002261 case Instruction::CAPTURE_VARIABLE: {
2262 if (!IsExperimentalInstructionEnabled(inst)) {
2263 UnexpectedOpcode(inst, shadow_frame);
2264 }
2265
2266 if (lambda_closure_builder == nullptr) {
2267 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2268 }
2269
2270 PREAMBLE();
2271 bool success = DoCaptureVariable<do_access_check>(self,
2272 inst,
2273 /*inout*/shadow_frame,
2274 /*inout*/lambda_closure_builder.get());
2275 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2276 break;
2277 }
Igor Murashkin158f35c2015-06-10 15:55:30 -07002278 case Instruction::CREATE_LAMBDA: {
2279 if (!IsExperimentalInstructionEnabled(inst)) {
2280 UnexpectedOpcode(inst, shadow_frame);
2281 }
2282
2283 PREAMBLE();
Igor Murashkin6918bf12015-09-27 19:19:06 -07002284
2285 if (lambda_closure_builder == nullptr) {
2286 // DoCreateLambda always needs a ClosureBuilder, even if it has 0 captured variables.
2287 lambda_closure_builder = MakeUnique<lambda::ClosureBuilder>();
2288 }
2289
2290 // TODO: these allocations should not leak, and the lambda method should not be local.
2291 lambda::Closure* lambda_closure =
2292 reinterpret_cast<lambda::Closure*>(alloca(lambda_closure_builder->GetSize()));
2293 bool success = DoCreateLambda<do_access_check>(self,
2294 inst,
2295 /*inout*/shadow_frame,
2296 /*inout*/lambda_closure_builder.get(),
2297 /*inout*/lambda_closure);
2298 lambda_closure_builder.reset(nullptr); // reset state of variables captured
Igor Murashkin158f35c2015-06-10 15:55:30 -07002299 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2300 break;
2301 }
Igor Murashkin6918bf12015-09-27 19:19:06 -07002302 case Instruction::LIBERATE_VARIABLE: {
2303 if (!IsExperimentalInstructionEnabled(inst)) {
2304 UnexpectedOpcode(inst, shadow_frame);
2305 }
2306
2307 PREAMBLE();
2308 bool success = DoLiberateVariable<do_access_check>(self,
2309 inst,
2310 lambda_captured_variable_index,
2311 /*inout*/shadow_frame);
2312 // Temporarily only allow sequences of 'liberate-variable, liberate-variable, ...'
2313 lambda_captured_variable_index++;
2314 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2315 break;
2316 }
2317 case Instruction::UNUSED_F4: {
Igor Murashkin158f35c2015-06-10 15:55:30 -07002318 if (!IsExperimentalInstructionEnabled(inst)) {
2319 UnexpectedOpcode(inst, shadow_frame);
2320 }
2321
2322 CHECK(false); // TODO(iam): Implement opcodes for lambdas
2323 break;
2324 }
Igor Murashkin2ee54e22015-06-18 10:05:11 -07002325 case Instruction::BOX_LAMBDA: {
2326 if (!IsExperimentalInstructionEnabled(inst)) {
2327 UnexpectedOpcode(inst, shadow_frame);
2328 }
2329
2330 PREAMBLE();
2331 bool success = DoBoxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2332 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2333 break;
2334 }
2335 case Instruction::UNBOX_LAMBDA: {
2336 if (!IsExperimentalInstructionEnabled(inst)) {
2337 UnexpectedOpcode(inst, shadow_frame);
2338 }
2339
2340 PREAMBLE();
2341 bool success = DoUnboxLambda<do_access_check>(self, shadow_frame, inst, inst_data);
2342 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2343 break;
2344 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002345 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Igor Murashkin158f35c2015-06-10 15:55:30 -07002346 case Instruction::UNUSED_FA ... Instruction::UNUSED_FF:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002347 case Instruction::UNUSED_79:
2348 case Instruction::UNUSED_7A:
Ian Rogerse94652f2014-12-02 11:13:19 -08002349 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002350 }
2351 }
2352} // NOLINT(readability/fn_size)
2353
2354// Explicit definitions of ExecuteSwitchImpl.
Mathieu Chartier90443472015-07-16 20:32:27 -07002355template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002356JValue ExecuteSwitchImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002357 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002358template SHARED_REQUIRES(Locks::mutator_lock_) HOT_ATTR
Ian Rogerse94652f2014-12-02 11:13:19 -08002359JValue ExecuteSwitchImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002360 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002361template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002362JValue ExecuteSwitchImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002363 ShadowFrame& shadow_frame, JValue result_register);
Mathieu Chartier90443472015-07-16 20:32:27 -07002364template SHARED_REQUIRES(Locks::mutator_lock_)
Ian Rogerse94652f2014-12-02 11:13:19 -08002365JValue ExecuteSwitchImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002366 ShadowFrame& shadow_frame, JValue result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002367
2368} // namespace interpreter
2369} // namespace art