blob: e35d80f724332cfbb484f5b0645af7097510cd3a [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
Andreas Gampe5e26eb12016-08-22 17:54:17 -070017#include "interpreter_switch_impl.h"
18
Andreas Gampe542451c2016-07-26 09:02:02 -070019#include "base/enums.h"
David Sehrc431b9d2018-03-02 12:01:51 -080020#include "base/quasi_atomic.h"
David Sehr9e734c72018-01-04 17:56:19 -080021#include "dex/dex_file_types.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070022#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020023#include "interpreter_common.h"
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000024#include "jit/jit.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070025#include "jvalue-inl.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070026#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020027
28namespace art {
29namespace interpreter {
30
Alex Lightb7edcda2017-04-27 13:20:31 -070031#define HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instr) \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020032 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020033 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070034 self->AllowThreadSuspension(); \
Alex Light9fb1ab12017-09-05 09:32:49 -070035 if (!MoveToExceptionHandler(self, shadow_frame, instr)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070036 /* Structured locking is to be enforced for abnormal termination, too. */ \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070037 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame); \
buzbee1452bee2015-03-06 14:43:04 -080038 if (interpret_one_instruction) { \
buzbee93e94f22016-04-07 13:52:48 -070039 /* Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -070040 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee1452bee2015-03-06 14:43:04 -080041 } \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020042 return JValue(); /* Handled in caller. */ \
43 } else { \
Alex Light9fb1ab12017-09-05 09:32:49 -070044 int32_t displacement = \
45 static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020046 inst = inst->RelativeAt(displacement); \
47 } \
48 } while (false)
49
Alex Lightb7edcda2017-04-27 13:20:31 -070050#define HANDLE_PENDING_EXCEPTION() HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instrumentation)
51
Sebastien Hertz8ece0502013-08-07 11:26:41 +020052#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
53 do { \
54 if (UNLIKELY(_is_exception_pending)) { \
55 HANDLE_PENDING_EXCEPTION(); \
56 } else { \
57 inst = inst->_next_function(); \
58 } \
59 } while (false)
60
Andreas Gampe03ec9302015-08-27 17:41:47 -070061#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070062 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070063 HANDLE_PENDING_EXCEPTION(); \
64 }
65
Sebastien Hertz8ece0502013-08-07 11:26:41 +020066// Code to run before each dex instruction.
Alex Lightfc905672017-06-27 17:53:15 -070067#define PREAMBLE_SAVE(save_ref) \
68 { \
69 if (UNLIKELY(instrumentation->HasDexPcListeners()) && \
70 UNLIKELY(!DoDexPcMoveEvent(self, \
Mathieu Chartier808c7a52017-12-15 11:19:33 -080071 accessor, \
Alex Lightfc905672017-06-27 17:53:15 -070072 shadow_frame, \
73 dex_pc, \
74 instrumentation, \
75 save_ref))) { \
76 HANDLE_PENDING_EXCEPTION(); \
77 break; \
Sebastien Hertz8379b222014-02-24 17:38:15 +010078 } \
Alex Lightfc905672017-06-27 17:53:15 -070079 } \
80 do {} while (false)
81
82#define PREAMBLE() PREAMBLE_SAVE(nullptr)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020083
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000084#define BRANCH_INSTRUMENTATION(offset) \
85 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010086 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
Alex Lightcc917d92018-02-22 13:28:28 -080087 instrumentation->Branch(self, shadow_frame.GetMethod(), dex_pc, offset); \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010088 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000089 JValue result; \
Alex Lightcc917d92018-02-22 13:28:28 -080090 if (jit::Jit::MaybeDoOnStackReplacement(self, \
91 shadow_frame.GetMethod(), \
92 dex_pc, \
93 offset, \
94 &result)) { \
buzbee93e94f22016-04-07 13:52:48 -070095 if (interpret_one_instruction) { \
96 /* OSR has completed execution of the method. Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -070097 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee93e94f22016-04-07 13:52:48 -070098 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000099 return result; \
100 } \
Nicolas Geoffray3108daf2015-11-24 16:32:33 +0000101 } while (false)
102
Bill Buzbee1d011d92016-04-04 16:59:29 +0000103#define HOTNESS_UPDATE() \
104 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100105 if (jit != nullptr) { \
Alex Lightcc917d92018-02-22 13:28:28 -0800106 jit->AddSamples(self, shadow_frame.GetMethod(), 1, /*with_backedges*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +0000107 } \
108 } while (false)
109
Alex Light848574c2017-09-25 16:59:39 -0700110#define HANDLE_ASYNC_EXCEPTION() \
111 if (UNLIKELY(self->ObserveAsyncException())) { \
112 HANDLE_PENDING_EXCEPTION(); \
113 break; \
114 } \
115 do {} while (false)
116
Andreas Gampef4f76372016-12-13 14:43:58 -0800117#define HANDLE_BACKWARD_BRANCH(offset) \
118 do { \
119 if (IsBackwardBranch(offset)) { \
120 HOTNESS_UPDATE(); \
121 /* Record new dex pc early to have consistent suspend point at loop header. */ \
122 shadow_frame.SetDexPC(inst->GetDexPc(insns)); \
123 self->AllowThreadSuspension(); \
124 } \
125 } while (false)
126
Alex Lightfc905672017-06-27 17:53:15 -0700127// Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
128// the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
129// to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
130// jvmti-agents while handling breakpoint or single step events. We had to move this into its own
131// function because it was making ExecuteSwitchImpl have too large a stack.
Alex Light2989a4a2017-06-29 09:44:57 -0700132NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800133 const CodeItemDataAccessor& accessor,
Alex Light2989a4a2017-06-29 09:44:57 -0700134 const ShadowFrame& shadow_frame,
135 uint32_t dex_pc,
136 const instrumentation::Instrumentation* instrumentation,
137 JValue* save_ref)
Alex Lightfc905672017-06-27 17:53:15 -0700138 REQUIRES_SHARED(Locks::mutator_lock_) {
139 DCHECK(instrumentation->HasDexPcListeners());
140 StackHandleScope<2> hs(self);
141 Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
142 mirror::Object* null_obj = nullptr;
143 HandleWrapper<mirror::Object> h(
144 hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
145 self->ClearException();
146 instrumentation->DexPcMovedEvent(self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800147 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lightfc905672017-06-27 17:53:15 -0700148 shadow_frame.GetMethod(),
149 dex_pc);
150 if (UNLIKELY(self->IsExceptionPending())) {
151 // We got a new exception in the dex-pc-moved event. We just let this exception replace the old
152 // one.
153 // TODO It would be good to add the old exception to the suppressed exceptions of the new one if
154 // possible.
155 return false;
156 } else {
157 if (UNLIKELY(!thr.IsNull())) {
158 self->SetException(thr.Get());
159 }
160 return true;
161 }
162}
163
Alex Lighte814f9d2017-07-31 16:14:39 -0700164static bool NeedsMethodExitEvent(const instrumentation::Instrumentation* ins)
165 REQUIRES_SHARED(Locks::mutator_lock_) {
166 return ins->HasMethodExitListeners() || ins->HasWatchedFramePopListeners();
167}
168
169// Sends the normal method exit event. Returns true if the events succeeded and false if there is a
170// pending exception.
171NO_INLINE static bool SendMethodExitEvents(Thread* self,
172 const instrumentation::Instrumentation* instrumentation,
173 const ShadowFrame& frame,
174 ObjPtr<mirror::Object> thiz,
175 ArtMethod* method,
176 uint32_t dex_pc,
177 const JValue& result)
178 REQUIRES_SHARED(Locks::mutator_lock_) {
179 bool had_event = false;
180 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
181 had_event = true;
182 instrumentation->MethodExitEvent(self, thiz.Ptr(), method, dex_pc, result);
183 }
184 if (UNLIKELY(frame.NeedsNotifyPop() && instrumentation->HasWatchedFramePopListeners())) {
185 had_event = true;
186 instrumentation->WatchedFramePopped(self, frame);
187 }
188 if (UNLIKELY(had_event)) {
189 return !self->IsExceptionPending();
190 } else {
191 return true;
192 }
193}
194
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100195template<bool do_access_check, bool transaction_active>
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800196JValue ExecuteSwitchImpl(Thread* self, const CodeItemDataAccessor& accessor,
buzbee1452bee2015-03-06 14:43:04 -0800197 ShadowFrame& shadow_frame, JValue result_register,
198 bool interpret_one_instruction) {
Igor Murashkinc449e8b2015-06-10 15:56:42 -0700199 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200200 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
201 LOG(FATAL) << "Invalid shadow frame for interpreter use";
202 return JValue();
203 }
204 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200205
206 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700207 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800208 const uint16_t* const insns = accessor.Insns();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200209 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200210 uint16_t inst_data;
Bill Buzbee1d011d92016-04-04 16:59:29 +0000211 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700212
buzbee1452bee2015-03-06 14:43:04 -0800213 do {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200214 dex_pc = inst->GetDexPc(insns);
215 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800216 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200217 inst_data = inst->Fetch16(0);
218 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200219 case Instruction::NOP:
220 PREAMBLE();
221 inst = inst->Next_1xx();
222 break;
223 case Instruction::MOVE:
224 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200225 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
226 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200227 inst = inst->Next_1xx();
228 break;
229 case Instruction::MOVE_FROM16:
230 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200231 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200232 shadow_frame.GetVReg(inst->VRegB_22x()));
233 inst = inst->Next_2xx();
234 break;
235 case Instruction::MOVE_16:
236 PREAMBLE();
237 shadow_frame.SetVReg(inst->VRegA_32x(),
238 shadow_frame.GetVReg(inst->VRegB_32x()));
239 inst = inst->Next_3xx();
240 break;
241 case Instruction::MOVE_WIDE:
242 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200243 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
244 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200245 inst = inst->Next_1xx();
246 break;
247 case Instruction::MOVE_WIDE_FROM16:
248 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200249 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200250 shadow_frame.GetVRegLong(inst->VRegB_22x()));
251 inst = inst->Next_2xx();
252 break;
253 case Instruction::MOVE_WIDE_16:
254 PREAMBLE();
255 shadow_frame.SetVRegLong(inst->VRegA_32x(),
256 shadow_frame.GetVRegLong(inst->VRegB_32x()));
257 inst = inst->Next_3xx();
258 break;
259 case Instruction::MOVE_OBJECT:
260 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200261 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
262 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200263 inst = inst->Next_1xx();
264 break;
265 case Instruction::MOVE_OBJECT_FROM16:
266 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200267 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200268 shadow_frame.GetVRegReference(inst->VRegB_22x()));
269 inst = inst->Next_2xx();
270 break;
271 case Instruction::MOVE_OBJECT_16:
272 PREAMBLE();
273 shadow_frame.SetVRegReference(inst->VRegA_32x(),
274 shadow_frame.GetVRegReference(inst->VRegB_32x()));
275 inst = inst->Next_3xx();
276 break;
277 case Instruction::MOVE_RESULT:
278 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200279 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200280 inst = inst->Next_1xx();
281 break;
282 case Instruction::MOVE_RESULT_WIDE:
283 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200284 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200285 inst = inst->Next_1xx();
286 break;
287 case Instruction::MOVE_RESULT_OBJECT:
Alex Lightfc905672017-06-27 17:53:15 -0700288 PREAMBLE_SAVE(&result_register);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200289 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200290 inst = inst->Next_1xx();
291 break;
292 case Instruction::MOVE_EXCEPTION: {
293 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700294 ObjPtr<mirror::Throwable> exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100295 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Mathieu Chartieref41db72016-10-25 15:08:01 -0700296 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception.Ptr());
Sebastien Hertz5c004902014-05-21 10:07:42 +0200297 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200298 inst = inst->Next_1xx();
299 break;
300 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700301 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200302 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200303 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700304 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700305 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700306 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
307 !SendMethodExitEvents(self,
308 instrumentation,
309 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800310 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700311 shadow_frame.GetMethod(),
312 inst->GetDexPc(insns),
313 result))) {
314 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200315 }
buzbee1452bee2015-03-06 14:43:04 -0800316 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700317 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700318 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800319 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200320 return result;
321 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700322 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200323 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700324 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200325 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700326 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700327 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700328 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
329 !SendMethodExitEvents(self,
330 instrumentation,
331 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800332 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700333 shadow_frame.GetMethod(),
334 inst->GetDexPc(insns),
335 result))) {
336 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200337 }
buzbee1452bee2015-03-06 14:43:04 -0800338 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700339 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700340 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800341 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200342 return result;
343 }
344 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200345 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200346 JValue result;
347 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200348 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700349 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700350 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700351 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
352 !SendMethodExitEvents(self,
353 instrumentation,
354 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800355 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700356 shadow_frame.GetMethod(),
357 inst->GetDexPc(insns),
358 result))) {
359 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200360 }
buzbee1452bee2015-03-06 14:43:04 -0800361 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700362 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700363 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800364 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200365 return result;
366 }
367 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200368 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200369 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200370 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700371 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700372 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700373 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
374 !SendMethodExitEvents(self,
375 instrumentation,
376 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800377 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700378 shadow_frame.GetMethod(),
379 inst->GetDexPc(insns),
380 result))) {
381 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200382 }
buzbee1452bee2015-03-06 14:43:04 -0800383 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700384 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700385 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800386 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200387 return result;
388 }
389 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200390 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200391 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700392 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700393 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700394 const size_t ref_idx = inst->VRegA_11x(inst_data);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700395 ObjPtr<mirror::Object> obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700396 if (do_assignability_check && obj_result != nullptr) {
Alex Lightcc917d92018-02-22 13:28:28 -0800397 ObjPtr<mirror::Class> return_type = shadow_frame.GetMethod()->ResolveReturnType();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700398 // Re-load since it might have moved.
399 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700400 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700401 // Return the pending exception.
402 HANDLE_PENDING_EXCEPTION();
403 }
404 if (!obj_result->VerifierInstanceOf(return_type)) {
405 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700406 std::string temp1, temp2;
Orion Hodsonfef06642016-11-25 16:07:11 +0000407 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700408 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700409 obj_result->GetClass()->GetDescriptor(&temp1),
410 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700411 HANDLE_PENDING_EXCEPTION();
412 }
413 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700414 result.SetL(obj_result);
Alex Lighte814f9d2017-07-31 16:14:39 -0700415 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
416 !SendMethodExitEvents(self,
417 instrumentation,
418 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800419 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700420 shadow_frame.GetMethod(),
421 inst->GetDexPc(insns),
422 result))) {
423 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200424 }
Alex Lighte814f9d2017-07-31 16:14:39 -0700425 // Re-load since it might have moved during the MethodExitEvent.
426 result.SetL(shadow_frame.GetVRegReference(ref_idx));
buzbee1452bee2015-03-06 14:43:04 -0800427 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700428 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700429 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800430 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200431 return result;
432 }
433 case Instruction::CONST_4: {
434 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200435 uint4_t dst = inst->VRegA_11n(inst_data);
436 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200437 shadow_frame.SetVReg(dst, val);
438 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700439 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200440 }
441 inst = inst->Next_1xx();
442 break;
443 }
444 case Instruction::CONST_16: {
445 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200446 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200447 int16_t val = inst->VRegB_21s();
448 shadow_frame.SetVReg(dst, val);
449 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700450 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200451 }
452 inst = inst->Next_2xx();
453 break;
454 }
455 case Instruction::CONST: {
456 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200457 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200458 int32_t val = inst->VRegB_31i();
459 shadow_frame.SetVReg(dst, val);
460 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700461 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200462 }
463 inst = inst->Next_3xx();
464 break;
465 }
466 case Instruction::CONST_HIGH16: {
467 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200468 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200469 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
470 shadow_frame.SetVReg(dst, val);
471 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700472 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200473 }
474 inst = inst->Next_2xx();
475 break;
476 }
477 case Instruction::CONST_WIDE_16:
478 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200479 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200480 inst = inst->Next_2xx();
481 break;
482 case Instruction::CONST_WIDE_32:
483 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200484 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200485 inst = inst->Next_3xx();
486 break;
487 case Instruction::CONST_WIDE:
488 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200489 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200490 inst = inst->Next_51l();
491 break;
492 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200493 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200494 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200495 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
496 inst = inst->Next_2xx();
497 break;
498 case Instruction::CONST_STRING: {
499 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800500 ObjPtr<mirror::String> s = ResolveString(self,
501 shadow_frame,
502 dex::StringIndex(inst->VRegB_21c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700503 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200504 HANDLE_PENDING_EXCEPTION();
505 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700506 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200507 inst = inst->Next_2xx();
508 }
509 break;
510 }
511 case Instruction::CONST_STRING_JUMBO: {
512 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800513 ObjPtr<mirror::String> s = ResolveString(self,
514 shadow_frame,
515 dex::StringIndex(inst->VRegB_31c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700516 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200517 HANDLE_PENDING_EXCEPTION();
518 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700519 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200520 inst = inst->Next_3xx();
521 }
522 break;
523 }
524 case Instruction::CONST_CLASS: {
525 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800526 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700527 shadow_frame.GetMethod(),
528 self,
529 false,
530 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700531 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200532 HANDLE_PENDING_EXCEPTION();
533 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700534 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200535 inst = inst->Next_2xx();
536 }
537 break;
538 }
Orion Hodson2e599942017-09-22 16:17:41 +0100539 case Instruction::CONST_METHOD_HANDLE: {
540 PREAMBLE();
Orion Hodsone7732be2017-10-11 14:35:20 +0100541 ClassLinker* cl = Runtime::Current()->GetClassLinker();
Alex Lightcc917d92018-02-22 13:28:28 -0800542 ObjPtr<mirror::MethodHandle> mh = cl->ResolveMethodHandle(self,
543 inst->VRegB_21c(),
544 shadow_frame.GetMethod());
Orion Hodson2e599942017-09-22 16:17:41 +0100545 if (UNLIKELY(mh == nullptr)) {
546 HANDLE_PENDING_EXCEPTION();
547 } else {
548 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mh.Ptr());
549 inst = inst->Next_2xx();
550 }
551 break;
552 }
553 case Instruction::CONST_METHOD_TYPE: {
554 PREAMBLE();
Orion Hodsone7732be2017-10-11 14:35:20 +0100555 ClassLinker* cl = Runtime::Current()->GetClassLinker();
Alex Lightcc917d92018-02-22 13:28:28 -0800556 ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(self,
557 inst->VRegB_21c(),
558 shadow_frame.GetMethod());
Orion Hodson2e599942017-09-22 16:17:41 +0100559 if (UNLIKELY(mt == nullptr)) {
560 HANDLE_PENDING_EXCEPTION();
561 } else {
562 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mt.Ptr());
563 inst = inst->Next_2xx();
564 }
565 break;
566 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200567 case Instruction::MONITOR_ENTER: {
568 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700569 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700570 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700571 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000572 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200573 HANDLE_PENDING_EXCEPTION();
574 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700575 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200576 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
577 }
578 break;
579 }
580 case Instruction::MONITOR_EXIT: {
581 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700582 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700583 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700584 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000585 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200586 HANDLE_PENDING_EXCEPTION();
587 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700588 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200589 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
590 }
591 break;
592 }
593 case Instruction::CHECK_CAST: {
594 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800595 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700596 shadow_frame.GetMethod(),
597 self,
598 false,
599 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700600 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200601 HANDLE_PENDING_EXCEPTION();
602 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700603 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700604 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200605 ThrowClassCastException(c, obj->GetClass());
606 HANDLE_PENDING_EXCEPTION();
607 } else {
608 inst = inst->Next_2xx();
609 }
610 }
611 break;
612 }
613 case Instruction::INSTANCE_OF: {
614 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800615 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegC_22c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700616 shadow_frame.GetMethod(),
617 self,
618 false,
619 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700620 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200621 HANDLE_PENDING_EXCEPTION();
622 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700623 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700624 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
625 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200626 inst = inst->Next_2xx();
627 }
628 break;
629 }
630 case Instruction::ARRAY_LENGTH: {
631 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700632 ObjPtr<mirror::Object> array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700633 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000634 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200635 HANDLE_PENDING_EXCEPTION();
636 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200637 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200638 inst = inst->Next_1xx();
639 }
640 break;
641 }
642 case Instruction::NEW_INSTANCE: {
643 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700644 ObjPtr<mirror::Object> obj = nullptr;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800645 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700646 shadow_frame.GetMethod(),
647 self,
648 false,
649 do_access_check);
Jeff Hao848f70a2014-01-15 13:49:50 -0800650 if (LIKELY(c != nullptr)) {
651 if (UNLIKELY(c->IsStringClass())) {
652 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700653 obj = mirror::String::AllocEmptyString<true>(self, allocator_type);
Jeff Hao848f70a2014-01-15 13:49:50 -0800654 } else {
Nicolas Geoffray0d3998b2017-01-12 15:35:12 +0000655 obj = AllocObjectFromCode<true>(
656 c.Ptr(),
Andreas Gampea5b09a62016-11-17 15:21:22 -0800657 self,
658 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Jeff Hao848f70a2014-01-15 13:49:50 -0800659 }
660 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700661 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200662 HANDLE_PENDING_EXCEPTION();
663 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200664 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700665 // Don't allow finalizable objects to be allocated during a transaction since these can't
666 // be finalized without a started runtime.
667 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200668 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
David Sehr709b0702016-10-13 09:12:37 -0700669 obj->PrettyTypeOf().c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700670 HANDLE_PENDING_EXCEPTION();
671 break;
672 }
Mathieu Chartieref41db72016-10-25 15:08:01 -0700673 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200674 inst = inst->Next_2xx();
675 }
676 break;
677 }
678 case Instruction::NEW_ARRAY: {
679 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200680 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartieref41db72016-10-25 15:08:01 -0700681 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800682 dex::TypeIndex(inst->VRegC_22c()),
683 length,
684 shadow_frame.GetMethod(),
685 self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800686 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700687 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200688 HANDLE_PENDING_EXCEPTION();
689 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700690 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200691 inst = inst->Next_2xx();
692 }
693 break;
694 }
695 case Instruction::FILLED_NEW_ARRAY: {
696 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100697 bool success =
698 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
699 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200700 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
701 break;
702 }
703 case Instruction::FILLED_NEW_ARRAY_RANGE: {
704 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100705 bool success =
706 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
707 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200708 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
709 break;
710 }
711 case Instruction::FILL_ARRAY_DATA: {
712 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200713 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
714 const Instruction::ArrayDataPayload* payload =
715 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700716 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700717 bool success = FillArrayData(obj, payload);
718 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200719 HANDLE_PENDING_EXCEPTION();
720 break;
721 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100722 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700723 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100724 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200725 inst = inst->Next_3xx();
726 break;
727 }
728 case Instruction::THROW: {
729 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700730 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700731 ObjPtr<mirror::Object> exception =
732 shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700733 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000734 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700735 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
736 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700737 std::string temp;
Orion Hodsonfef06642016-11-25 16:07:11 +0000738 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700739 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700740 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200741 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000742 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200743 }
744 HANDLE_PENDING_EXCEPTION();
745 break;
746 }
747 case Instruction::GOTO: {
748 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700749 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200750 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000751 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200752 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800753 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200754 break;
755 }
756 case Instruction::GOTO_16: {
757 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700758 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200759 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000760 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200761 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800762 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200763 break;
764 }
765 case Instruction::GOTO_32: {
766 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700767 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200768 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000769 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200770 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800771 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200772 break;
773 }
774 case Instruction::PACKED_SWITCH: {
775 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200776 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000777 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200778 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800779 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200780 break;
781 }
782 case Instruction::SPARSE_SWITCH: {
783 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200784 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000785 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200786 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800787 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200788 break;
789 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700790
Ian Rogers647b1a82014-10-10 11:02:11 -0700791#pragma clang diagnostic push
792#pragma clang diagnostic ignored "-Wfloat-equal"
Ian Rogers647b1a82014-10-10 11:02:11 -0700793
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200794 case Instruction::CMPL_FLOAT: {
795 PREAMBLE();
796 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
797 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
798 int32_t result;
799 if (val1 > val2) {
800 result = 1;
801 } else if (val1 == val2) {
802 result = 0;
803 } else {
804 result = -1;
805 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200806 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200807 inst = inst->Next_2xx();
808 break;
809 }
810 case Instruction::CMPG_FLOAT: {
811 PREAMBLE();
812 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
813 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
814 int32_t result;
815 if (val1 < val2) {
816 result = -1;
817 } else if (val1 == val2) {
818 result = 0;
819 } else {
820 result = 1;
821 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200822 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200823 inst = inst->Next_2xx();
824 break;
825 }
826 case Instruction::CMPL_DOUBLE: {
827 PREAMBLE();
828 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
829 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
830 int32_t result;
831 if (val1 > val2) {
832 result = 1;
833 } else if (val1 == val2) {
834 result = 0;
835 } else {
836 result = -1;
837 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200838 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200839 inst = inst->Next_2xx();
840 break;
841 }
842
843 case Instruction::CMPG_DOUBLE: {
844 PREAMBLE();
845 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
846 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
847 int32_t result;
848 if (val1 < val2) {
849 result = -1;
850 } else if (val1 == val2) {
851 result = 0;
852 } else {
853 result = 1;
854 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200855 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200856 inst = inst->Next_2xx();
857 break;
858 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700859
Ian Rogers647b1a82014-10-10 11:02:11 -0700860#pragma clang diagnostic pop
Ian Rogers647b1a82014-10-10 11:02:11 -0700861
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200862 case Instruction::CMP_LONG: {
863 PREAMBLE();
864 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
865 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
866 int32_t result;
867 if (val1 > val2) {
868 result = 1;
869 } else if (val1 == val2) {
870 result = 0;
871 } else {
872 result = -1;
873 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200874 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200875 inst = inst->Next_2xx();
876 break;
877 }
878 case Instruction::IF_EQ: {
879 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700880 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
881 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200882 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000883 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200884 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800885 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200886 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800887 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200888 inst = inst->Next_2xx();
889 }
890 break;
891 }
892 case Instruction::IF_NE: {
893 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700894 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
895 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200896 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000897 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200898 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800899 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200900 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800901 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200902 inst = inst->Next_2xx();
903 }
904 break;
905 }
906 case Instruction::IF_LT: {
907 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700908 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
909 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200910 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000911 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200912 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800913 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200914 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800915 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200916 inst = inst->Next_2xx();
917 }
918 break;
919 }
920 case Instruction::IF_GE: {
921 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700922 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
923 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200924 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000925 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200926 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800927 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200928 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800929 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200930 inst = inst->Next_2xx();
931 }
932 break;
933 }
934 case Instruction::IF_GT: {
935 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700936 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
937 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200938 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000939 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200940 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800941 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200942 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800943 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200944 inst = inst->Next_2xx();
945 }
946 break;
947 }
948 case Instruction::IF_LE: {
949 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700950 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
951 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200952 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000953 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200954 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800955 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200956 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800957 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200958 inst = inst->Next_2xx();
959 }
960 break;
961 }
962 case Instruction::IF_EQZ: {
963 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200964 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200965 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000966 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200967 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800968 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200969 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800970 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200971 inst = inst->Next_2xx();
972 }
973 break;
974 }
975 case Instruction::IF_NEZ: {
976 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200977 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200978 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000979 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200980 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800981 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200982 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800983 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200984 inst = inst->Next_2xx();
985 }
986 break;
987 }
988 case Instruction::IF_LTZ: {
989 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200990 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200991 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000992 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200993 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800994 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200995 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800996 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200997 inst = inst->Next_2xx();
998 }
999 break;
1000 }
1001 case Instruction::IF_GEZ: {
1002 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001003 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001004 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001005 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001006 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001007 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001008 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001009 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001010 inst = inst->Next_2xx();
1011 }
1012 break;
1013 }
1014 case Instruction::IF_GTZ: {
1015 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001016 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001017 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001018 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001019 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001020 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001021 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001022 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001023 inst = inst->Next_2xx();
1024 }
1025 break;
1026 }
1027 case Instruction::IF_LEZ: {
1028 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001029 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001030 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001031 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001032 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001033 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001034 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001035 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001036 inst = inst->Next_2xx();
1037 }
1038 break;
1039 }
1040 case Instruction::AGET_BOOLEAN: {
1041 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001042 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001043 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001044 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001045 HANDLE_PENDING_EXCEPTION();
1046 break;
1047 }
1048 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001049 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001050 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001051 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001052 inst = inst->Next_2xx();
1053 } else {
1054 HANDLE_PENDING_EXCEPTION();
1055 }
1056 break;
1057 }
1058 case Instruction::AGET_BYTE: {
1059 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001060 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001061 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001062 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001063 HANDLE_PENDING_EXCEPTION();
1064 break;
1065 }
1066 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001067 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001068 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001069 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001070 inst = inst->Next_2xx();
1071 } else {
1072 HANDLE_PENDING_EXCEPTION();
1073 }
1074 break;
1075 }
1076 case Instruction::AGET_CHAR: {
1077 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001078 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001079 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001080 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001081 HANDLE_PENDING_EXCEPTION();
1082 break;
1083 }
1084 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001085 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001086 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001087 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001088 inst = inst->Next_2xx();
1089 } else {
1090 HANDLE_PENDING_EXCEPTION();
1091 }
1092 break;
1093 }
1094 case Instruction::AGET_SHORT: {
1095 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001096 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001097 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001098 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001099 HANDLE_PENDING_EXCEPTION();
1100 break;
1101 }
1102 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001103 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001104 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001105 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001106 inst = inst->Next_2xx();
1107 } else {
1108 HANDLE_PENDING_EXCEPTION();
1109 }
1110 break;
1111 }
1112 case Instruction::AGET: {
1113 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001114 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001115 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001116 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001117 HANDLE_PENDING_EXCEPTION();
1118 break;
1119 }
1120 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001121 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001122 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001123 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001124 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001125 inst = inst->Next_2xx();
1126 } else {
1127 HANDLE_PENDING_EXCEPTION();
1128 }
1129 break;
1130 }
1131 case Instruction::AGET_WIDE: {
1132 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001133 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001134 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001135 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001136 HANDLE_PENDING_EXCEPTION();
1137 break;
1138 }
1139 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001140 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001141 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001142 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001143 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001144 inst = inst->Next_2xx();
1145 } else {
1146 HANDLE_PENDING_EXCEPTION();
1147 }
1148 break;
1149 }
1150 case Instruction::AGET_OBJECT: {
1151 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001152 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001153 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001154 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001155 HANDLE_PENDING_EXCEPTION();
1156 break;
1157 }
1158 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001159 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001160 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001161 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001162 inst = inst->Next_2xx();
1163 } else {
1164 HANDLE_PENDING_EXCEPTION();
1165 }
1166 break;
1167 }
1168 case Instruction::APUT_BOOLEAN: {
1169 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001170 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001171 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001172 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001173 HANDLE_PENDING_EXCEPTION();
1174 break;
1175 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001176 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001177 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001178 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001179 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001180 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001181 inst = inst->Next_2xx();
1182 } else {
1183 HANDLE_PENDING_EXCEPTION();
1184 }
1185 break;
1186 }
1187 case Instruction::APUT_BYTE: {
1188 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001189 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001190 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001191 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001192 HANDLE_PENDING_EXCEPTION();
1193 break;
1194 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001195 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001196 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001197 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001198 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001199 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001200 inst = inst->Next_2xx();
1201 } else {
1202 HANDLE_PENDING_EXCEPTION();
1203 }
1204 break;
1205 }
1206 case Instruction::APUT_CHAR: {
1207 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001208 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001209 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001210 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001211 HANDLE_PENDING_EXCEPTION();
1212 break;
1213 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001214 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001215 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001216 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001217 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001218 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001219 inst = inst->Next_2xx();
1220 } else {
1221 HANDLE_PENDING_EXCEPTION();
1222 }
1223 break;
1224 }
1225 case Instruction::APUT_SHORT: {
1226 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001227 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001228 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001229 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001230 HANDLE_PENDING_EXCEPTION();
1231 break;
1232 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001233 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001234 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001235 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001236 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001237 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001238 inst = inst->Next_2xx();
1239 } else {
1240 HANDLE_PENDING_EXCEPTION();
1241 }
1242 break;
1243 }
1244 case Instruction::APUT: {
1245 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001246 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001247 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001248 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001249 HANDLE_PENDING_EXCEPTION();
1250 break;
1251 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001252 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001253 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001254 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001255 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001256 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001257 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001258 inst = inst->Next_2xx();
1259 } else {
1260 HANDLE_PENDING_EXCEPTION();
1261 }
1262 break;
1263 }
1264 case Instruction::APUT_WIDE: {
1265 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001266 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001267 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001268 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001269 HANDLE_PENDING_EXCEPTION();
1270 break;
1271 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001272 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001273 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001274 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001275 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001276 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001277 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001278 inst = inst->Next_2xx();
1279 } else {
1280 HANDLE_PENDING_EXCEPTION();
1281 }
1282 break;
1283 }
1284 case Instruction::APUT_OBJECT: {
1285 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001286 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001287 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001288 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001289 HANDLE_PENDING_EXCEPTION();
1290 break;
1291 }
1292 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001293 ObjPtr<mirror::Object> val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
1294 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001295 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001296 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001297 inst = inst->Next_2xx();
1298 } else {
1299 HANDLE_PENDING_EXCEPTION();
1300 }
1301 break;
1302 }
1303 case Instruction::IGET_BOOLEAN: {
1304 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001305 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1306 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001307 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1308 break;
1309 }
1310 case Instruction::IGET_BYTE: {
1311 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001312 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1313 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001314 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1315 break;
1316 }
1317 case Instruction::IGET_CHAR: {
1318 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001319 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1320 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001321 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1322 break;
1323 }
1324 case Instruction::IGET_SHORT: {
1325 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001326 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1327 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001328 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1329 break;
1330 }
1331 case Instruction::IGET: {
1332 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001333 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1334 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001335 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1336 break;
1337 }
1338 case Instruction::IGET_WIDE: {
1339 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001340 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1341 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001342 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1343 break;
1344 }
1345 case Instruction::IGET_OBJECT: {
1346 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001347 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1348 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001349 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1350 break;
1351 }
1352 case Instruction::IGET_QUICK: {
1353 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001354 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001355 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1356 break;
1357 }
1358 case Instruction::IGET_WIDE_QUICK: {
1359 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001360 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001361 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1362 break;
1363 }
1364 case Instruction::IGET_OBJECT_QUICK: {
1365 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001366 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001367 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1368 break;
1369 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001370 case Instruction::IGET_BOOLEAN_QUICK: {
1371 PREAMBLE();
1372 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1373 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1374 break;
1375 }
1376 case Instruction::IGET_BYTE_QUICK: {
1377 PREAMBLE();
1378 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1379 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1380 break;
1381 }
1382 case Instruction::IGET_CHAR_QUICK: {
1383 PREAMBLE();
1384 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1385 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1386 break;
1387 }
1388 case Instruction::IGET_SHORT_QUICK: {
1389 PREAMBLE();
1390 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1391 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1392 break;
1393 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001394 case Instruction::SGET_BOOLEAN: {
1395 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001396 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check,
1397 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001398 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1399 break;
1400 }
1401 case Instruction::SGET_BYTE: {
1402 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001403 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check,
1404 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001405 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1406 break;
1407 }
1408 case Instruction::SGET_CHAR: {
1409 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001410 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check,
1411 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001412 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1413 break;
1414 }
1415 case Instruction::SGET_SHORT: {
1416 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001417 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check,
1418 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001419 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1420 break;
1421 }
1422 case Instruction::SGET: {
1423 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001424 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check,
1425 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001426 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1427 break;
1428 }
1429 case Instruction::SGET_WIDE: {
1430 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001431 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check,
1432 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001433 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1434 break;
1435 }
1436 case Instruction::SGET_OBJECT: {
1437 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001438 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check,
1439 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001440 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1441 break;
1442 }
1443 case Instruction::IPUT_BOOLEAN: {
1444 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001445 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1446 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001447 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1448 break;
1449 }
1450 case Instruction::IPUT_BYTE: {
1451 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001452 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1453 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001454 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1455 break;
1456 }
1457 case Instruction::IPUT_CHAR: {
1458 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001459 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1460 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001461 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1462 break;
1463 }
1464 case Instruction::IPUT_SHORT: {
1465 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001466 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1467 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001468 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1469 break;
1470 }
1471 case Instruction::IPUT: {
1472 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001473 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1474 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001475 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1476 break;
1477 }
1478 case Instruction::IPUT_WIDE: {
1479 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001480 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1481 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001482 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1483 break;
1484 }
1485 case Instruction::IPUT_OBJECT: {
1486 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001487 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1488 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001489 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1490 break;
1491 }
1492 case Instruction::IPUT_QUICK: {
1493 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001494 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1495 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001496 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1497 break;
1498 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001499 case Instruction::IPUT_BOOLEAN_QUICK: {
1500 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001501 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1502 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001503 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1504 break;
1505 }
1506 case Instruction::IPUT_BYTE_QUICK: {
1507 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001508 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1509 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001510 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1511 break;
1512 }
1513 case Instruction::IPUT_CHAR_QUICK: {
1514 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001515 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1516 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001517 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1518 break;
1519 }
1520 case Instruction::IPUT_SHORT_QUICK: {
1521 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001522 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1523 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001524 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1525 break;
1526 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001527 case Instruction::IPUT_WIDE_QUICK: {
1528 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001529 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1530 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001531 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1532 break;
1533 }
1534 case Instruction::IPUT_OBJECT_QUICK: {
1535 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001536 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1537 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001538 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1539 break;
1540 }
1541 case Instruction::SPUT_BOOLEAN: {
1542 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001543 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1544 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001545 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1546 break;
1547 }
1548 case Instruction::SPUT_BYTE: {
1549 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001550 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1551 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001552 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1553 break;
1554 }
1555 case Instruction::SPUT_CHAR: {
1556 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001557 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1558 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001559 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1560 break;
1561 }
1562 case Instruction::SPUT_SHORT: {
1563 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001564 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1565 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001566 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1567 break;
1568 }
1569 case Instruction::SPUT: {
1570 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001571 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1572 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001573 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1574 break;
1575 }
1576 case Instruction::SPUT_WIDE: {
1577 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001578 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1579 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001580 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1581 break;
1582 }
1583 case Instruction::SPUT_OBJECT: {
1584 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001585 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1586 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001587 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1588 break;
1589 }
1590 case Instruction::INVOKE_VIRTUAL: {
1591 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001592 bool success = DoInvoke<kVirtual, false, do_access_check>(
1593 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001594 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1595 break;
1596 }
1597 case Instruction::INVOKE_VIRTUAL_RANGE: {
1598 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001599 bool success = DoInvoke<kVirtual, true, do_access_check>(
1600 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001601 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1602 break;
1603 }
1604 case Instruction::INVOKE_SUPER: {
1605 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001606 bool success = DoInvoke<kSuper, false, do_access_check>(
1607 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001608 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1609 break;
1610 }
1611 case Instruction::INVOKE_SUPER_RANGE: {
1612 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001613 bool success = DoInvoke<kSuper, true, do_access_check>(
1614 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001615 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1616 break;
1617 }
1618 case Instruction::INVOKE_DIRECT: {
1619 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001620 bool success = DoInvoke<kDirect, false, do_access_check>(
1621 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001622 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1623 break;
1624 }
1625 case Instruction::INVOKE_DIRECT_RANGE: {
1626 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001627 bool success = DoInvoke<kDirect, true, do_access_check>(
1628 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001629 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1630 break;
1631 }
1632 case Instruction::INVOKE_INTERFACE: {
1633 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001634 bool success = DoInvoke<kInterface, false, do_access_check>(
1635 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001636 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1637 break;
1638 }
1639 case Instruction::INVOKE_INTERFACE_RANGE: {
1640 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001641 bool success = DoInvoke<kInterface, true, do_access_check>(
1642 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001643 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1644 break;
1645 }
1646 case Instruction::INVOKE_STATIC: {
1647 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001648 bool success = DoInvoke<kStatic, false, do_access_check>(
1649 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001650 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1651 break;
1652 }
1653 case Instruction::INVOKE_STATIC_RANGE: {
1654 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001655 bool success = DoInvoke<kStatic, true, do_access_check>(
1656 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001657 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1658 break;
1659 }
1660 case Instruction::INVOKE_VIRTUAL_QUICK: {
1661 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001662 bool success = DoInvokeVirtualQuick<false>(
1663 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001664 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1665 break;
1666 }
1667 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1668 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001669 bool success = DoInvokeVirtualQuick<true>(
1670 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001671 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1672 break;
1673 }
Narayan Kamath9823e782016-08-03 12:46:58 +01001674 case Instruction::INVOKE_POLYMORPHIC: {
1675 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001676 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Orion Hodsonc069a302017-01-18 09:23:12 +00001677 bool success = DoInvokePolymorphic<false /* is_range */>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001678 self, shadow_frame, inst, inst_data, &result_register);
1679 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_4xx);
1680 break;
1681 }
1682 case Instruction::INVOKE_POLYMORPHIC_RANGE: {
1683 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001684 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Orion Hodsonc069a302017-01-18 09:23:12 +00001685 bool success = DoInvokePolymorphic<true /* is_range */>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001686 self, shadow_frame, inst, inst_data, &result_register);
1687 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_4xx);
1688 break;
Narayan Kamath9823e782016-08-03 12:46:58 +01001689 }
Orion Hodsonc069a302017-01-18 09:23:12 +00001690 case Instruction::INVOKE_CUSTOM: {
1691 PREAMBLE();
1692 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1693 bool success = DoInvokeCustom<false /* is_range */>(
1694 self, shadow_frame, inst, inst_data, &result_register);
1695 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1696 break;
1697 }
1698 case Instruction::INVOKE_CUSTOM_RANGE: {
1699 PREAMBLE();
1700 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1701 bool success = DoInvokeCustom<true /* is_range */>(
1702 self, shadow_frame, inst, inst_data, &result_register);
1703 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1704 break;
1705 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001706 case Instruction::NEG_INT:
1707 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001708 shadow_frame.SetVReg(
1709 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001710 inst = inst->Next_1xx();
1711 break;
1712 case Instruction::NOT_INT:
1713 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001714 shadow_frame.SetVReg(
1715 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001716 inst = inst->Next_1xx();
1717 break;
1718 case Instruction::NEG_LONG:
1719 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001720 shadow_frame.SetVRegLong(
1721 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001722 inst = inst->Next_1xx();
1723 break;
1724 case Instruction::NOT_LONG:
1725 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001726 shadow_frame.SetVRegLong(
1727 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001728 inst = inst->Next_1xx();
1729 break;
1730 case Instruction::NEG_FLOAT:
1731 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001732 shadow_frame.SetVRegFloat(
1733 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001734 inst = inst->Next_1xx();
1735 break;
1736 case Instruction::NEG_DOUBLE:
1737 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001738 shadow_frame.SetVRegDouble(
1739 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001740 inst = inst->Next_1xx();
1741 break;
1742 case Instruction::INT_TO_LONG:
1743 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001744 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1745 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001746 inst = inst->Next_1xx();
1747 break;
1748 case Instruction::INT_TO_FLOAT:
1749 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001750 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1751 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001752 inst = inst->Next_1xx();
1753 break;
1754 case Instruction::INT_TO_DOUBLE:
1755 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001756 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1757 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001758 inst = inst->Next_1xx();
1759 break;
1760 case Instruction::LONG_TO_INT:
1761 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001762 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1763 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001764 inst = inst->Next_1xx();
1765 break;
1766 case Instruction::LONG_TO_FLOAT:
1767 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001768 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1769 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001770 inst = inst->Next_1xx();
1771 break;
1772 case Instruction::LONG_TO_DOUBLE:
1773 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001774 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1775 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001776 inst = inst->Next_1xx();
1777 break;
1778 case Instruction::FLOAT_TO_INT: {
1779 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001780 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001781 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001782 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001783 inst = inst->Next_1xx();
1784 break;
1785 }
1786 case Instruction::FLOAT_TO_LONG: {
1787 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001788 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001789 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001790 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001791 inst = inst->Next_1xx();
1792 break;
1793 }
1794 case Instruction::FLOAT_TO_DOUBLE:
1795 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001796 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1797 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001798 inst = inst->Next_1xx();
1799 break;
1800 case Instruction::DOUBLE_TO_INT: {
1801 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001802 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001803 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001804 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001805 inst = inst->Next_1xx();
1806 break;
1807 }
1808 case Instruction::DOUBLE_TO_LONG: {
1809 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001810 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001811 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001812 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001813 inst = inst->Next_1xx();
1814 break;
1815 }
1816 case Instruction::DOUBLE_TO_FLOAT:
1817 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001818 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1819 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001820 inst = inst->Next_1xx();
1821 break;
1822 case Instruction::INT_TO_BYTE:
1823 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001824 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1825 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001826 inst = inst->Next_1xx();
1827 break;
1828 case Instruction::INT_TO_CHAR:
1829 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001830 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1831 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001832 inst = inst->Next_1xx();
1833 break;
1834 case Instruction::INT_TO_SHORT:
1835 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001836 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1837 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001838 inst = inst->Next_1xx();
1839 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001840 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001841 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001842 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001843 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1844 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001845 inst = inst->Next_2xx();
1846 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001847 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001848 case Instruction::SUB_INT:
1849 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001850 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001851 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1852 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001853 inst = inst->Next_2xx();
1854 break;
1855 case Instruction::MUL_INT:
1856 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001857 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001858 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1859 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001860 inst = inst->Next_2xx();
1861 break;
1862 case Instruction::DIV_INT: {
1863 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001864 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001865 shadow_frame.GetVReg(inst->VRegB_23x()),
1866 shadow_frame.GetVReg(inst->VRegC_23x()));
1867 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1868 break;
1869 }
1870 case Instruction::REM_INT: {
1871 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001872 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001873 shadow_frame.GetVReg(inst->VRegB_23x()),
1874 shadow_frame.GetVReg(inst->VRegC_23x()));
1875 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1876 break;
1877 }
1878 case Instruction::SHL_INT:
1879 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001880 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001881 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1882 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1883 inst = inst->Next_2xx();
1884 break;
1885 case Instruction::SHR_INT:
1886 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001887 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001888 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1889 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1890 inst = inst->Next_2xx();
1891 break;
1892 case Instruction::USHR_INT:
1893 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001894 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001895 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1896 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1897 inst = inst->Next_2xx();
1898 break;
1899 case Instruction::AND_INT:
1900 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001901 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001902 shadow_frame.GetVReg(inst->VRegB_23x()) &
1903 shadow_frame.GetVReg(inst->VRegC_23x()));
1904 inst = inst->Next_2xx();
1905 break;
1906 case Instruction::OR_INT:
1907 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001908 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001909 shadow_frame.GetVReg(inst->VRegB_23x()) |
1910 shadow_frame.GetVReg(inst->VRegC_23x()));
1911 inst = inst->Next_2xx();
1912 break;
1913 case Instruction::XOR_INT:
1914 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001915 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001916 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1917 shadow_frame.GetVReg(inst->VRegC_23x()));
1918 inst = inst->Next_2xx();
1919 break;
1920 case Instruction::ADD_LONG:
1921 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001922 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001923 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1924 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001925 inst = inst->Next_2xx();
1926 break;
1927 case Instruction::SUB_LONG:
1928 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001929 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001930 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1931 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001932 inst = inst->Next_2xx();
1933 break;
1934 case Instruction::MUL_LONG:
1935 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001936 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001937 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1938 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001939 inst = inst->Next_2xx();
1940 break;
1941 case Instruction::DIV_LONG:
1942 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001943 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001944 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001945 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001946 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1947 break;
1948 case Instruction::REM_LONG:
1949 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001950 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001951 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1952 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1953 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1954 break;
1955 case Instruction::AND_LONG:
1956 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001957 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001958 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1959 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1960 inst = inst->Next_2xx();
1961 break;
1962 case Instruction::OR_LONG:
1963 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001964 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001965 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1966 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1967 inst = inst->Next_2xx();
1968 break;
1969 case Instruction::XOR_LONG:
1970 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001971 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001972 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1973 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1974 inst = inst->Next_2xx();
1975 break;
1976 case Instruction::SHL_LONG:
1977 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001978 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001979 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1980 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1981 inst = inst->Next_2xx();
1982 break;
1983 case Instruction::SHR_LONG:
1984 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001985 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001986 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1987 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1988 inst = inst->Next_2xx();
1989 break;
1990 case Instruction::USHR_LONG:
1991 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001992 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001993 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1994 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1995 inst = inst->Next_2xx();
1996 break;
1997 case Instruction::ADD_FLOAT:
1998 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001999 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002000 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
2001 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2002 inst = inst->Next_2xx();
2003 break;
2004 case Instruction::SUB_FLOAT:
2005 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002006 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002007 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
2008 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2009 inst = inst->Next_2xx();
2010 break;
2011 case Instruction::MUL_FLOAT:
2012 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002013 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002014 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
2015 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2016 inst = inst->Next_2xx();
2017 break;
2018 case Instruction::DIV_FLOAT:
2019 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002020 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002021 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
2022 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2023 inst = inst->Next_2xx();
2024 break;
2025 case Instruction::REM_FLOAT:
2026 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002027 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002028 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
2029 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
2030 inst = inst->Next_2xx();
2031 break;
2032 case Instruction::ADD_DOUBLE:
2033 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002034 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002035 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
2036 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2037 inst = inst->Next_2xx();
2038 break;
2039 case Instruction::SUB_DOUBLE:
2040 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002041 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002042 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
2043 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2044 inst = inst->Next_2xx();
2045 break;
2046 case Instruction::MUL_DOUBLE:
2047 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002048 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002049 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
2050 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2051 inst = inst->Next_2xx();
2052 break;
2053 case Instruction::DIV_DOUBLE:
2054 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002055 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002056 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2057 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2058 inst = inst->Next_2xx();
2059 break;
2060 case Instruction::REM_DOUBLE:
2061 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002062 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002063 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2064 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2065 inst = inst->Next_2xx();
2066 break;
2067 case Instruction::ADD_INT_2ADDR: {
2068 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002069 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07002070 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
2071 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002072 inst = inst->Next_1xx();
2073 break;
2074 }
2075 case Instruction::SUB_INT_2ADDR: {
2076 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002077 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002078 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002079 SafeSub(shadow_frame.GetVReg(vregA),
2080 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002081 inst = inst->Next_1xx();
2082 break;
2083 }
2084 case Instruction::MUL_INT_2ADDR: {
2085 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002086 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002087 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002088 SafeMul(shadow_frame.GetVReg(vregA),
2089 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002090 inst = inst->Next_1xx();
2091 break;
2092 }
2093 case Instruction::DIV_INT_2ADDR: {
2094 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002095 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002096 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002097 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002098 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2099 break;
2100 }
2101 case Instruction::REM_INT_2ADDR: {
2102 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002103 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002104 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002105 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002106 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2107 break;
2108 }
2109 case Instruction::SHL_INT_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.SetVReg(vregA,
2113 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002114 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002115 inst = inst->Next_1xx();
2116 break;
2117 }
2118 case Instruction::SHR_INT_2ADDR: {
2119 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002120 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002121 shadow_frame.SetVReg(vregA,
2122 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002123 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002124 inst = inst->Next_1xx();
2125 break;
2126 }
2127 case Instruction::USHR_INT_2ADDR: {
2128 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002129 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002130 shadow_frame.SetVReg(vregA,
2131 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002132 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002133 inst = inst->Next_1xx();
2134 break;
2135 }
2136 case Instruction::AND_INT_2ADDR: {
2137 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002138 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002139 shadow_frame.SetVReg(vregA,
2140 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002141 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002142 inst = inst->Next_1xx();
2143 break;
2144 }
2145 case Instruction::OR_INT_2ADDR: {
2146 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002147 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002148 shadow_frame.SetVReg(vregA,
2149 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002150 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002151 inst = inst->Next_1xx();
2152 break;
2153 }
2154 case Instruction::XOR_INT_2ADDR: {
2155 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002156 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002157 shadow_frame.SetVReg(vregA,
2158 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002159 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002160 inst = inst->Next_1xx();
2161 break;
2162 }
2163 case Instruction::ADD_LONG_2ADDR: {
2164 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002165 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002166 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002167 SafeAdd(shadow_frame.GetVRegLong(vregA),
2168 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002169 inst = inst->Next_1xx();
2170 break;
2171 }
2172 case Instruction::SUB_LONG_2ADDR: {
2173 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002174 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002175 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002176 SafeSub(shadow_frame.GetVRegLong(vregA),
2177 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002178 inst = inst->Next_1xx();
2179 break;
2180 }
2181 case Instruction::MUL_LONG_2ADDR: {
2182 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002183 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002184 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002185 SafeMul(shadow_frame.GetVRegLong(vregA),
2186 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002187 inst = inst->Next_1xx();
2188 break;
2189 }
2190 case Instruction::DIV_LONG_2ADDR: {
2191 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002192 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002193 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002194 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002195 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2196 break;
2197 }
2198 case Instruction::REM_LONG_2ADDR: {
2199 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002200 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002201 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002202 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002203 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2204 break;
2205 }
2206 case Instruction::AND_LONG_2ADDR: {
2207 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002208 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002209 shadow_frame.SetVRegLong(vregA,
2210 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002211 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002212 inst = inst->Next_1xx();
2213 break;
2214 }
2215 case Instruction::OR_LONG_2ADDR: {
2216 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002217 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002218 shadow_frame.SetVRegLong(vregA,
2219 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002220 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002221 inst = inst->Next_1xx();
2222 break;
2223 }
2224 case Instruction::XOR_LONG_2ADDR: {
2225 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002226 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002227 shadow_frame.SetVRegLong(vregA,
2228 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002229 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002230 inst = inst->Next_1xx();
2231 break;
2232 }
2233 case Instruction::SHL_LONG_2ADDR: {
2234 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002235 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002236 shadow_frame.SetVRegLong(vregA,
2237 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002238 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002239 inst = inst->Next_1xx();
2240 break;
2241 }
2242 case Instruction::SHR_LONG_2ADDR: {
2243 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002244 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002245 shadow_frame.SetVRegLong(vregA,
2246 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002247 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002248 inst = inst->Next_1xx();
2249 break;
2250 }
2251 case Instruction::USHR_LONG_2ADDR: {
2252 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002253 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002254 shadow_frame.SetVRegLong(vregA,
2255 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002256 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002257 inst = inst->Next_1xx();
2258 break;
2259 }
2260 case Instruction::ADD_FLOAT_2ADDR: {
2261 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002262 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002263 shadow_frame.SetVRegFloat(vregA,
2264 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002265 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002266 inst = inst->Next_1xx();
2267 break;
2268 }
2269 case Instruction::SUB_FLOAT_2ADDR: {
2270 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002271 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002272 shadow_frame.SetVRegFloat(vregA,
2273 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002274 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002275 inst = inst->Next_1xx();
2276 break;
2277 }
2278 case Instruction::MUL_FLOAT_2ADDR: {
2279 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002280 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002281 shadow_frame.SetVRegFloat(vregA,
2282 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002283 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002284 inst = inst->Next_1xx();
2285 break;
2286 }
2287 case Instruction::DIV_FLOAT_2ADDR: {
2288 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002289 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002290 shadow_frame.SetVRegFloat(vregA,
2291 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002292 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002293 inst = inst->Next_1xx();
2294 break;
2295 }
2296 case Instruction::REM_FLOAT_2ADDR: {
2297 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002298 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002299 shadow_frame.SetVRegFloat(vregA,
2300 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002301 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002302 inst = inst->Next_1xx();
2303 break;
2304 }
2305 case Instruction::ADD_DOUBLE_2ADDR: {
2306 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002307 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002308 shadow_frame.SetVRegDouble(vregA,
2309 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002310 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002311 inst = inst->Next_1xx();
2312 break;
2313 }
2314 case Instruction::SUB_DOUBLE_2ADDR: {
2315 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002316 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002317 shadow_frame.SetVRegDouble(vregA,
2318 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002319 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002320 inst = inst->Next_1xx();
2321 break;
2322 }
2323 case Instruction::MUL_DOUBLE_2ADDR: {
2324 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002325 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002326 shadow_frame.SetVRegDouble(vregA,
2327 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002328 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002329 inst = inst->Next_1xx();
2330 break;
2331 }
2332 case Instruction::DIV_DOUBLE_2ADDR: {
2333 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002334 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002335 shadow_frame.SetVRegDouble(vregA,
2336 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002337 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002338 inst = inst->Next_1xx();
2339 break;
2340 }
2341 case Instruction::REM_DOUBLE_2ADDR: {
2342 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002343 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002344 shadow_frame.SetVRegDouble(vregA,
2345 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002346 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002347 inst = inst->Next_1xx();
2348 break;
2349 }
2350 case Instruction::ADD_INT_LIT16:
2351 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002352 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002353 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2354 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002355 inst = inst->Next_2xx();
2356 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002357 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002358 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002359 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002360 SafeSub(inst->VRegC_22s(),
2361 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002362 inst = inst->Next_2xx();
2363 break;
2364 case Instruction::MUL_INT_LIT16:
2365 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002366 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002367 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2368 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002369 inst = inst->Next_2xx();
2370 break;
2371 case Instruction::DIV_INT_LIT16: {
2372 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002373 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002374 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2375 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002376 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2377 break;
2378 }
2379 case Instruction::REM_INT_LIT16: {
2380 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002381 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002382 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2383 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002384 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2385 break;
2386 }
2387 case Instruction::AND_INT_LIT16:
2388 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002389 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2390 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002391 inst->VRegC_22s());
2392 inst = inst->Next_2xx();
2393 break;
2394 case Instruction::OR_INT_LIT16:
2395 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002396 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2397 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002398 inst->VRegC_22s());
2399 inst = inst->Next_2xx();
2400 break;
2401 case Instruction::XOR_INT_LIT16:
2402 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002403 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2404 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002405 inst->VRegC_22s());
2406 inst = inst->Next_2xx();
2407 break;
2408 case Instruction::ADD_INT_LIT8:
2409 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002410 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002411 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002412 inst = inst->Next_2xx();
2413 break;
2414 case Instruction::RSUB_INT_LIT8:
2415 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002416 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002417 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002418 inst = inst->Next_2xx();
2419 break;
2420 case Instruction::MUL_INT_LIT8:
2421 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002422 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002423 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002424 inst = inst->Next_2xx();
2425 break;
2426 case Instruction::DIV_INT_LIT8: {
2427 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002428 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002429 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2430 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2431 break;
2432 }
2433 case Instruction::REM_INT_LIT8: {
2434 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002435 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002436 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2437 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2438 break;
2439 }
2440 case Instruction::AND_INT_LIT8:
2441 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002442 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002443 shadow_frame.GetVReg(inst->VRegB_22b()) &
2444 inst->VRegC_22b());
2445 inst = inst->Next_2xx();
2446 break;
2447 case Instruction::OR_INT_LIT8:
2448 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002449 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002450 shadow_frame.GetVReg(inst->VRegB_22b()) |
2451 inst->VRegC_22b());
2452 inst = inst->Next_2xx();
2453 break;
2454 case Instruction::XOR_INT_LIT8:
2455 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002456 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002457 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2458 inst->VRegC_22b());
2459 inst = inst->Next_2xx();
2460 break;
2461 case Instruction::SHL_INT_LIT8:
2462 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002463 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002464 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2465 (inst->VRegC_22b() & 0x1f));
2466 inst = inst->Next_2xx();
2467 break;
2468 case Instruction::SHR_INT_LIT8:
2469 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002470 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002471 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2472 (inst->VRegC_22b() & 0x1f));
2473 inst = inst->Next_2xx();
2474 break;
2475 case Instruction::USHR_INT_LIT8:
2476 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002477 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002478 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2479 (inst->VRegC_22b() & 0x1f));
2480 inst = inst->Next_2xx();
2481 break;
2482 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Orion Hodson2e599942017-09-22 16:17:41 +01002483 case Instruction::UNUSED_79 ... Instruction::UNUSED_7A:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002484 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
Ian Rogerse94652f2014-12-02 11:13:19 -08002485 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002486 }
buzbee1452bee2015-03-06 14:43:04 -08002487 } while (!interpret_one_instruction);
2488 // Record where we stopped.
2489 shadow_frame.SetDexPC(inst->GetDexPc(insns));
buzbeed6b48db2016-01-28 15:48:55 -08002490 return result_register;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002491} // NOLINT(readability/fn_size)
2492
2493// Explicit definitions of ExecuteSwitchImpl.
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002494template HOT_ATTR
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002495JValue ExecuteSwitchImpl<true, false>(Thread* self, const CodeItemDataAccessor& accessor,
buzbee1452bee2015-03-06 14:43:04 -08002496 ShadowFrame& shadow_frame, JValue result_register,
2497 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002498template HOT_ATTR
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002499JValue ExecuteSwitchImpl<false, false>(Thread* self, const CodeItemDataAccessor& accessor,
buzbee1452bee2015-03-06 14:43:04 -08002500 ShadowFrame& shadow_frame, JValue result_register,
2501 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002502template
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002503JValue ExecuteSwitchImpl<true, true>(Thread* self, const CodeItemDataAccessor& accessor,
buzbee1452bee2015-03-06 14:43:04 -08002504 ShadowFrame& shadow_frame, JValue result_register,
2505 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002506template
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002507JValue ExecuteSwitchImpl<false, true>(Thread* self, const CodeItemDataAccessor& accessor,
buzbee1452bee2015-03-06 14:43:04 -08002508 ShadowFrame& shadow_frame, JValue result_register,
2509 bool interpret_one_instruction);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002510
2511} // namespace interpreter
2512} // namespace art