blob: 6f9cad848d2a591f4fd72c6cda82e63b5a733352 [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 Sehr9e734c72018-01-04 17:56:19 -080020#include "dex/dex_file_types.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070021#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020022#include "interpreter_common.h"
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000023#include "jit/jit.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070024#include "jvalue-inl.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070025#include "safe_math.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020026
27namespace art {
28namespace interpreter {
29
Alex Lightb7edcda2017-04-27 13:20:31 -070030#define HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instr) \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020031 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020032 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070033 self->AllowThreadSuspension(); \
Alex Light9fb1ab12017-09-05 09:32:49 -070034 if (!MoveToExceptionHandler(self, shadow_frame, instr)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070035 /* Structured locking is to be enforced for abnormal termination, too. */ \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070036 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame); \
buzbee1452bee2015-03-06 14:43:04 -080037 if (interpret_one_instruction) { \
buzbee93e94f22016-04-07 13:52:48 -070038 /* Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -070039 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee1452bee2015-03-06 14:43:04 -080040 } \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020041 return JValue(); /* Handled in caller. */ \
42 } else { \
Alex Light9fb1ab12017-09-05 09:32:49 -070043 int32_t displacement = \
44 static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020045 inst = inst->RelativeAt(displacement); \
46 } \
47 } while (false)
48
Alex Lightb7edcda2017-04-27 13:20:31 -070049#define HANDLE_PENDING_EXCEPTION() HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instrumentation)
50
Sebastien Hertz8ece0502013-08-07 11:26:41 +020051#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
52 do { \
53 if (UNLIKELY(_is_exception_pending)) { \
54 HANDLE_PENDING_EXCEPTION(); \
55 } else { \
56 inst = inst->_next_function(); \
57 } \
58 } while (false)
59
Andreas Gampe03ec9302015-08-27 17:41:47 -070060#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070061 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070062 HANDLE_PENDING_EXCEPTION(); \
63 }
64
Sebastien Hertz8ece0502013-08-07 11:26:41 +020065// Code to run before each dex instruction.
Alex Lightfc905672017-06-27 17:53:15 -070066#define PREAMBLE_SAVE(save_ref) \
67 { \
68 if (UNLIKELY(instrumentation->HasDexPcListeners()) && \
69 UNLIKELY(!DoDexPcMoveEvent(self, \
Mathieu Chartier808c7a52017-12-15 11:19:33 -080070 accessor, \
Alex Lightfc905672017-06-27 17:53:15 -070071 shadow_frame, \
72 dex_pc, \
73 instrumentation, \
74 save_ref))) { \
75 HANDLE_PENDING_EXCEPTION(); \
76 break; \
Sebastien Hertz8379b222014-02-24 17:38:15 +010077 } \
Alex Lightfc905672017-06-27 17:53:15 -070078 } \
79 do {} while (false)
80
81#define PREAMBLE() PREAMBLE_SAVE(nullptr)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020082
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000083#define BRANCH_INSTRUMENTATION(offset) \
84 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +010085 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
86 instrumentation->Branch(self, method, dex_pc, offset); \
87 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000088 JValue result; \
89 if (jit::Jit::MaybeDoOnStackReplacement(self, method, dex_pc, offset, &result)) { \
buzbee93e94f22016-04-07 13:52:48 -070090 if (interpret_one_instruction) { \
91 /* OSR has completed execution of the method. Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -070092 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee93e94f22016-04-07 13:52:48 -070093 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000094 return result; \
95 } \
Nicolas Geoffray3108daf2015-11-24 16:32:33 +000096 } while (false)
97
Bill Buzbee1d011d92016-04-04 16:59:29 +000098#define HOTNESS_UPDATE() \
99 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100100 if (jit != nullptr) { \
Nicolas Geoffray71cd50f2016-04-14 15:00:33 +0100101 jit->AddSamples(self, method, 1, /*with_backedges*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +0000102 } \
103 } while (false)
104
Alex Light848574c2017-09-25 16:59:39 -0700105#define HANDLE_ASYNC_EXCEPTION() \
106 if (UNLIKELY(self->ObserveAsyncException())) { \
107 HANDLE_PENDING_EXCEPTION(); \
108 break; \
109 } \
110 do {} while (false)
111
Andreas Gampef4f76372016-12-13 14:43:58 -0800112#define HANDLE_BACKWARD_BRANCH(offset) \
113 do { \
114 if (IsBackwardBranch(offset)) { \
115 HOTNESS_UPDATE(); \
116 /* Record new dex pc early to have consistent suspend point at loop header. */ \
117 shadow_frame.SetDexPC(inst->GetDexPc(insns)); \
118 self->AllowThreadSuspension(); \
119 } \
120 } while (false)
121
Alex Lightfc905672017-06-27 17:53:15 -0700122// Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
123// the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
124// to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
125// jvmti-agents while handling breakpoint or single step events. We had to move this into its own
126// function because it was making ExecuteSwitchImpl have too large a stack.
Alex Light2989a4a2017-06-29 09:44:57 -0700127NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800128 const CodeItemDataAccessor& accessor,
Alex Light2989a4a2017-06-29 09:44:57 -0700129 const ShadowFrame& shadow_frame,
130 uint32_t dex_pc,
131 const instrumentation::Instrumentation* instrumentation,
132 JValue* save_ref)
Alex Lightfc905672017-06-27 17:53:15 -0700133 REQUIRES_SHARED(Locks::mutator_lock_) {
134 DCHECK(instrumentation->HasDexPcListeners());
135 StackHandleScope<2> hs(self);
136 Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
137 mirror::Object* null_obj = nullptr;
138 HandleWrapper<mirror::Object> h(
139 hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
140 self->ClearException();
141 instrumentation->DexPcMovedEvent(self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800142 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lightfc905672017-06-27 17:53:15 -0700143 shadow_frame.GetMethod(),
144 dex_pc);
145 if (UNLIKELY(self->IsExceptionPending())) {
146 // We got a new exception in the dex-pc-moved event. We just let this exception replace the old
147 // one.
148 // TODO It would be good to add the old exception to the suppressed exceptions of the new one if
149 // possible.
150 return false;
151 } else {
152 if (UNLIKELY(!thr.IsNull())) {
153 self->SetException(thr.Get());
154 }
155 return true;
156 }
157}
158
Alex Lighte814f9d2017-07-31 16:14:39 -0700159static bool NeedsMethodExitEvent(const instrumentation::Instrumentation* ins)
160 REQUIRES_SHARED(Locks::mutator_lock_) {
161 return ins->HasMethodExitListeners() || ins->HasWatchedFramePopListeners();
162}
163
164// Sends the normal method exit event. Returns true if the events succeeded and false if there is a
165// pending exception.
166NO_INLINE static bool SendMethodExitEvents(Thread* self,
167 const instrumentation::Instrumentation* instrumentation,
168 const ShadowFrame& frame,
169 ObjPtr<mirror::Object> thiz,
170 ArtMethod* method,
171 uint32_t dex_pc,
172 const JValue& result)
173 REQUIRES_SHARED(Locks::mutator_lock_) {
174 bool had_event = false;
175 if (UNLIKELY(instrumentation->HasMethodExitListeners())) {
176 had_event = true;
177 instrumentation->MethodExitEvent(self, thiz.Ptr(), method, dex_pc, result);
178 }
179 if (UNLIKELY(frame.NeedsNotifyPop() && instrumentation->HasWatchedFramePopListeners())) {
180 had_event = true;
181 instrumentation->WatchedFramePopped(self, frame);
182 }
183 if (UNLIKELY(had_event)) {
184 return !self->IsExceptionPending();
185 } else {
186 return true;
187 }
188}
189
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100190template<bool do_access_check, bool transaction_active>
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800191JValue ExecuteSwitchImpl(Thread* self, const CodeItemDataAccessor& accessor,
buzbee1452bee2015-03-06 14:43:04 -0800192 ShadowFrame& shadow_frame, JValue result_register,
193 bool interpret_one_instruction) {
Igor Murashkinc449e8b2015-06-10 15:56:42 -0700194 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200195 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
196 LOG(FATAL) << "Invalid shadow frame for interpreter use";
197 return JValue();
198 }
199 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200200
201 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700202 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800203 ArtMethod* method = shadow_frame.GetMethod();
204 const uint16_t* const insns = accessor.Insns();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200205 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200206 uint16_t inst_data;
Bill Buzbee1d011d92016-04-04 16:59:29 +0000207 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700208
buzbee1452bee2015-03-06 14:43:04 -0800209 do {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200210 dex_pc = inst->GetDexPc(insns);
211 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800212 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200213 inst_data = inst->Fetch16(0);
214 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200215 case Instruction::NOP:
216 PREAMBLE();
217 inst = inst->Next_1xx();
218 break;
219 case Instruction::MOVE:
220 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200221 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
222 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200223 inst = inst->Next_1xx();
224 break;
225 case Instruction::MOVE_FROM16:
226 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200227 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200228 shadow_frame.GetVReg(inst->VRegB_22x()));
229 inst = inst->Next_2xx();
230 break;
231 case Instruction::MOVE_16:
232 PREAMBLE();
233 shadow_frame.SetVReg(inst->VRegA_32x(),
234 shadow_frame.GetVReg(inst->VRegB_32x()));
235 inst = inst->Next_3xx();
236 break;
237 case Instruction::MOVE_WIDE:
238 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200239 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
240 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200241 inst = inst->Next_1xx();
242 break;
243 case Instruction::MOVE_WIDE_FROM16:
244 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200245 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200246 shadow_frame.GetVRegLong(inst->VRegB_22x()));
247 inst = inst->Next_2xx();
248 break;
249 case Instruction::MOVE_WIDE_16:
250 PREAMBLE();
251 shadow_frame.SetVRegLong(inst->VRegA_32x(),
252 shadow_frame.GetVRegLong(inst->VRegB_32x()));
253 inst = inst->Next_3xx();
254 break;
255 case Instruction::MOVE_OBJECT:
256 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200257 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
258 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200259 inst = inst->Next_1xx();
260 break;
261 case Instruction::MOVE_OBJECT_FROM16:
262 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200263 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200264 shadow_frame.GetVRegReference(inst->VRegB_22x()));
265 inst = inst->Next_2xx();
266 break;
267 case Instruction::MOVE_OBJECT_16:
268 PREAMBLE();
269 shadow_frame.SetVRegReference(inst->VRegA_32x(),
270 shadow_frame.GetVRegReference(inst->VRegB_32x()));
271 inst = inst->Next_3xx();
272 break;
273 case Instruction::MOVE_RESULT:
274 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200275 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200276 inst = inst->Next_1xx();
277 break;
278 case Instruction::MOVE_RESULT_WIDE:
279 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200280 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200281 inst = inst->Next_1xx();
282 break;
283 case Instruction::MOVE_RESULT_OBJECT:
Alex Lightfc905672017-06-27 17:53:15 -0700284 PREAMBLE_SAVE(&result_register);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200285 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200286 inst = inst->Next_1xx();
287 break;
288 case Instruction::MOVE_EXCEPTION: {
289 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700290 ObjPtr<mirror::Throwable> exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100291 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Mathieu Chartieref41db72016-10-25 15:08:01 -0700292 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception.Ptr());
Sebastien Hertz5c004902014-05-21 10:07:42 +0200293 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200294 inst = inst->Next_1xx();
295 break;
296 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700297 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200298 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200299 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700300 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700301 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700302 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
303 !SendMethodExitEvents(self,
304 instrumentation,
305 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800306 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700307 shadow_frame.GetMethod(),
308 inst->GetDexPc(insns),
309 result))) {
310 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200311 }
buzbee1452bee2015-03-06 14:43:04 -0800312 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700313 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700314 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800315 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200316 return result;
317 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700318 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200319 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700320 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200321 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700322 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700323 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700324 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
325 !SendMethodExitEvents(self,
326 instrumentation,
327 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800328 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700329 shadow_frame.GetMethod(),
330 inst->GetDexPc(insns),
331 result))) {
332 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200333 }
buzbee1452bee2015-03-06 14:43:04 -0800334 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700335 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700336 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800337 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200338 return result;
339 }
340 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200341 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200342 JValue result;
343 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200344 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700345 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700346 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700347 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
348 !SendMethodExitEvents(self,
349 instrumentation,
350 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800351 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700352 shadow_frame.GetMethod(),
353 inst->GetDexPc(insns),
354 result))) {
355 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200356 }
buzbee1452bee2015-03-06 14:43:04 -0800357 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700358 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700359 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800360 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200361 return result;
362 }
363 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200364 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200365 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200366 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700367 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700368 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700369 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
370 !SendMethodExitEvents(self,
371 instrumentation,
372 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800373 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700374 shadow_frame.GetMethod(),
375 inst->GetDexPc(insns),
376 result))) {
377 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200378 }
buzbee1452bee2015-03-06 14:43:04 -0800379 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700380 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700381 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800382 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200383 return result;
384 }
385 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200386 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200387 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700388 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700389 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700390 const size_t ref_idx = inst->VRegA_11x(inst_data);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700391 ObjPtr<mirror::Object> obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700392 if (do_assignability_check && obj_result != nullptr) {
Vladimir Markob45528c2017-07-27 14:14:28 +0100393 ObjPtr<mirror::Class> return_type = method->ResolveReturnType();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700394 // Re-load since it might have moved.
395 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700396 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700397 // Return the pending exception.
398 HANDLE_PENDING_EXCEPTION();
399 }
400 if (!obj_result->VerifierInstanceOf(return_type)) {
401 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700402 std::string temp1, temp2;
Orion Hodsonfef06642016-11-25 16:07:11 +0000403 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700404 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700405 obj_result->GetClass()->GetDescriptor(&temp1),
406 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700407 HANDLE_PENDING_EXCEPTION();
408 }
409 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700410 result.SetL(obj_result);
Alex Lighte814f9d2017-07-31 16:14:39 -0700411 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
412 !SendMethodExitEvents(self,
413 instrumentation,
414 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800415 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700416 shadow_frame.GetMethod(),
417 inst->GetDexPc(insns),
418 result))) {
419 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200420 }
Alex Lighte814f9d2017-07-31 16:14:39 -0700421 // Re-load since it might have moved during the MethodExitEvent.
422 result.SetL(shadow_frame.GetVRegReference(ref_idx));
buzbee1452bee2015-03-06 14:43:04 -0800423 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700424 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700425 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800426 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200427 return result;
428 }
429 case Instruction::CONST_4: {
430 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200431 uint4_t dst = inst->VRegA_11n(inst_data);
432 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200433 shadow_frame.SetVReg(dst, val);
434 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700435 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200436 }
437 inst = inst->Next_1xx();
438 break;
439 }
440 case Instruction::CONST_16: {
441 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200442 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200443 int16_t val = inst->VRegB_21s();
444 shadow_frame.SetVReg(dst, val);
445 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700446 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200447 }
448 inst = inst->Next_2xx();
449 break;
450 }
451 case Instruction::CONST: {
452 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200453 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200454 int32_t val = inst->VRegB_31i();
455 shadow_frame.SetVReg(dst, val);
456 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700457 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200458 }
459 inst = inst->Next_3xx();
460 break;
461 }
462 case Instruction::CONST_HIGH16: {
463 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200464 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200465 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
466 shadow_frame.SetVReg(dst, val);
467 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700468 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200469 }
470 inst = inst->Next_2xx();
471 break;
472 }
473 case Instruction::CONST_WIDE_16:
474 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200475 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200476 inst = inst->Next_2xx();
477 break;
478 case Instruction::CONST_WIDE_32:
479 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200480 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200481 inst = inst->Next_3xx();
482 break;
483 case Instruction::CONST_WIDE:
484 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200485 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200486 inst = inst->Next_51l();
487 break;
488 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200489 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200490 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200491 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
492 inst = inst->Next_2xx();
493 break;
494 case Instruction::CONST_STRING: {
495 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800496 ObjPtr<mirror::String> s = ResolveString(self,
497 shadow_frame,
498 dex::StringIndex(inst->VRegB_21c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700499 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200500 HANDLE_PENDING_EXCEPTION();
501 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700502 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200503 inst = inst->Next_2xx();
504 }
505 break;
506 }
507 case Instruction::CONST_STRING_JUMBO: {
508 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800509 ObjPtr<mirror::String> s = ResolveString(self,
510 shadow_frame,
511 dex::StringIndex(inst->VRegB_31c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700512 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200513 HANDLE_PENDING_EXCEPTION();
514 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700515 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200516 inst = inst->Next_3xx();
517 }
518 break;
519 }
520 case Instruction::CONST_CLASS: {
521 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800522 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700523 shadow_frame.GetMethod(),
524 self,
525 false,
526 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700527 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200528 HANDLE_PENDING_EXCEPTION();
529 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700530 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200531 inst = inst->Next_2xx();
532 }
533 break;
534 }
Orion Hodson2e599942017-09-22 16:17:41 +0100535 case Instruction::CONST_METHOD_HANDLE: {
536 PREAMBLE();
Orion Hodsone7732be2017-10-11 14:35:20 +0100537 ClassLinker* cl = Runtime::Current()->GetClassLinker();
538 ObjPtr<mirror::MethodHandle> mh = cl->ResolveMethodHandle(self, inst->VRegB_21c(), method);
Orion Hodson2e599942017-09-22 16:17:41 +0100539 if (UNLIKELY(mh == nullptr)) {
540 HANDLE_PENDING_EXCEPTION();
541 } else {
542 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mh.Ptr());
543 inst = inst->Next_2xx();
544 }
545 break;
546 }
547 case Instruction::CONST_METHOD_TYPE: {
548 PREAMBLE();
Orion Hodsone7732be2017-10-11 14:35:20 +0100549 ClassLinker* cl = Runtime::Current()->GetClassLinker();
550 ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(self, inst->VRegB_21c(), method);
Orion Hodson2e599942017-09-22 16:17:41 +0100551 if (UNLIKELY(mt == nullptr)) {
552 HANDLE_PENDING_EXCEPTION();
553 } else {
554 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mt.Ptr());
555 inst = inst->Next_2xx();
556 }
557 break;
558 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200559 case Instruction::MONITOR_ENTER: {
560 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700561 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700562 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700563 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000564 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200565 HANDLE_PENDING_EXCEPTION();
566 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700567 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200568 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
569 }
570 break;
571 }
572 case Instruction::MONITOR_EXIT: {
573 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700574 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700575 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700576 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000577 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200578 HANDLE_PENDING_EXCEPTION();
579 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700580 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200581 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
582 }
583 break;
584 }
585 case Instruction::CHECK_CAST: {
586 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800587 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700588 shadow_frame.GetMethod(),
589 self,
590 false,
591 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700592 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200593 HANDLE_PENDING_EXCEPTION();
594 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700595 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700596 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200597 ThrowClassCastException(c, obj->GetClass());
598 HANDLE_PENDING_EXCEPTION();
599 } else {
600 inst = inst->Next_2xx();
601 }
602 }
603 break;
604 }
605 case Instruction::INSTANCE_OF: {
606 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800607 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegC_22c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700608 shadow_frame.GetMethod(),
609 self,
610 false,
611 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700612 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200613 HANDLE_PENDING_EXCEPTION();
614 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700615 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700616 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
617 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200618 inst = inst->Next_2xx();
619 }
620 break;
621 }
622 case Instruction::ARRAY_LENGTH: {
623 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700624 ObjPtr<mirror::Object> array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700625 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000626 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200627 HANDLE_PENDING_EXCEPTION();
628 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200629 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200630 inst = inst->Next_1xx();
631 }
632 break;
633 }
634 case Instruction::NEW_INSTANCE: {
635 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700636 ObjPtr<mirror::Object> obj = nullptr;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800637 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700638 shadow_frame.GetMethod(),
639 self,
640 false,
641 do_access_check);
Jeff Hao848f70a2014-01-15 13:49:50 -0800642 if (LIKELY(c != nullptr)) {
643 if (UNLIKELY(c->IsStringClass())) {
644 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700645 obj = mirror::String::AllocEmptyString<true>(self, allocator_type);
Jeff Hao848f70a2014-01-15 13:49:50 -0800646 } else {
Nicolas Geoffray0d3998b2017-01-12 15:35:12 +0000647 obj = AllocObjectFromCode<true>(
648 c.Ptr(),
Andreas Gampea5b09a62016-11-17 15:21:22 -0800649 self,
650 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Jeff Hao848f70a2014-01-15 13:49:50 -0800651 }
652 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700653 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200654 HANDLE_PENDING_EXCEPTION();
655 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200656 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700657 // Don't allow finalizable objects to be allocated during a transaction since these can't
658 // be finalized without a started runtime.
659 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200660 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
David Sehr709b0702016-10-13 09:12:37 -0700661 obj->PrettyTypeOf().c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700662 HANDLE_PENDING_EXCEPTION();
663 break;
664 }
Mathieu Chartieref41db72016-10-25 15:08:01 -0700665 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200666 inst = inst->Next_2xx();
667 }
668 break;
669 }
670 case Instruction::NEW_ARRAY: {
671 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200672 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartieref41db72016-10-25 15:08:01 -0700673 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800674 dex::TypeIndex(inst->VRegC_22c()),
675 length,
676 shadow_frame.GetMethod(),
677 self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800678 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700679 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200680 HANDLE_PENDING_EXCEPTION();
681 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700682 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj.Ptr());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200683 inst = inst->Next_2xx();
684 }
685 break;
686 }
687 case Instruction::FILLED_NEW_ARRAY: {
688 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100689 bool success =
690 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
691 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200692 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
693 break;
694 }
695 case Instruction::FILLED_NEW_ARRAY_RANGE: {
696 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100697 bool success =
698 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
699 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200700 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
701 break;
702 }
703 case Instruction::FILL_ARRAY_DATA: {
704 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200705 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
706 const Instruction::ArrayDataPayload* payload =
707 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700708 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700709 bool success = FillArrayData(obj, payload);
710 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200711 HANDLE_PENDING_EXCEPTION();
712 break;
713 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100714 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700715 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100716 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200717 inst = inst->Next_3xx();
718 break;
719 }
720 case Instruction::THROW: {
721 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700722 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700723 ObjPtr<mirror::Object> exception =
724 shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700725 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000726 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700727 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
728 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700729 std::string temp;
Orion Hodsonfef06642016-11-25 16:07:11 +0000730 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700731 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700732 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200733 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000734 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200735 }
736 HANDLE_PENDING_EXCEPTION();
737 break;
738 }
739 case Instruction::GOTO: {
740 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700741 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200742 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000743 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200744 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800745 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200746 break;
747 }
748 case Instruction::GOTO_16: {
749 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700750 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200751 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000752 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200753 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800754 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200755 break;
756 }
757 case Instruction::GOTO_32: {
758 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700759 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200760 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000761 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200762 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800763 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200764 break;
765 }
766 case Instruction::PACKED_SWITCH: {
767 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200768 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000769 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +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::SPARSE_SWITCH: {
775 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200776 int32_t offset = DoSparseSwitch(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 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700782
Ian Rogers647b1a82014-10-10 11:02:11 -0700783#pragma clang diagnostic push
784#pragma clang diagnostic ignored "-Wfloat-equal"
Ian Rogers647b1a82014-10-10 11:02:11 -0700785
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200786 case Instruction::CMPL_FLOAT: {
787 PREAMBLE();
788 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
789 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
790 int32_t result;
791 if (val1 > val2) {
792 result = 1;
793 } else if (val1 == val2) {
794 result = 0;
795 } else {
796 result = -1;
797 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200798 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200799 inst = inst->Next_2xx();
800 break;
801 }
802 case Instruction::CMPG_FLOAT: {
803 PREAMBLE();
804 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
805 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
806 int32_t result;
807 if (val1 < val2) {
808 result = -1;
809 } else if (val1 == val2) {
810 result = 0;
811 } else {
812 result = 1;
813 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200814 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200815 inst = inst->Next_2xx();
816 break;
817 }
818 case Instruction::CMPL_DOUBLE: {
819 PREAMBLE();
820 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
821 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
822 int32_t result;
823 if (val1 > val2) {
824 result = 1;
825 } else if (val1 == val2) {
826 result = 0;
827 } else {
828 result = -1;
829 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200830 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200831 inst = inst->Next_2xx();
832 break;
833 }
834
835 case Instruction::CMPG_DOUBLE: {
836 PREAMBLE();
837 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
838 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
839 int32_t result;
840 if (val1 < val2) {
841 result = -1;
842 } else if (val1 == val2) {
843 result = 0;
844 } else {
845 result = 1;
846 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200847 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200848 inst = inst->Next_2xx();
849 break;
850 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700851
Ian Rogers647b1a82014-10-10 11:02:11 -0700852#pragma clang diagnostic pop
Ian Rogers647b1a82014-10-10 11:02:11 -0700853
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200854 case Instruction::CMP_LONG: {
855 PREAMBLE();
856 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
857 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
858 int32_t result;
859 if (val1 > val2) {
860 result = 1;
861 } else if (val1 == val2) {
862 result = 0;
863 } else {
864 result = -1;
865 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200866 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200867 inst = inst->Next_2xx();
868 break;
869 }
870 case Instruction::IF_EQ: {
871 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700872 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
873 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200874 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000875 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200876 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800877 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200878 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800879 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200880 inst = inst->Next_2xx();
881 }
882 break;
883 }
884 case Instruction::IF_NE: {
885 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700886 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
887 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200888 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000889 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200890 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800891 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200892 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800893 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200894 inst = inst->Next_2xx();
895 }
896 break;
897 }
898 case Instruction::IF_LT: {
899 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700900 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
901 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200902 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000903 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200904 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800905 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200906 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800907 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200908 inst = inst->Next_2xx();
909 }
910 break;
911 }
912 case Instruction::IF_GE: {
913 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700914 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
915 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200916 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000917 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200918 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800919 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200920 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800921 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200922 inst = inst->Next_2xx();
923 }
924 break;
925 }
926 case Instruction::IF_GT: {
927 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700928 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
929 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200930 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000931 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200932 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800933 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200934 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800935 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200936 inst = inst->Next_2xx();
937 }
938 break;
939 }
940 case Instruction::IF_LE: {
941 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700942 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
943 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200944 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000945 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200946 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800947 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200948 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800949 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200950 inst = inst->Next_2xx();
951 }
952 break;
953 }
954 case Instruction::IF_EQZ: {
955 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200956 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200957 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000958 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200959 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800960 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200961 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800962 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200963 inst = inst->Next_2xx();
964 }
965 break;
966 }
967 case Instruction::IF_NEZ: {
968 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200969 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200970 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000971 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200972 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800973 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200974 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800975 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200976 inst = inst->Next_2xx();
977 }
978 break;
979 }
980 case Instruction::IF_LTZ: {
981 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200982 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200983 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000984 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200985 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800986 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200987 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800988 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200989 inst = inst->Next_2xx();
990 }
991 break;
992 }
993 case Instruction::IF_GEZ: {
994 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200995 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200996 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000997 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200998 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800999 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001000 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001001 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001002 inst = inst->Next_2xx();
1003 }
1004 break;
1005 }
1006 case Instruction::IF_GTZ: {
1007 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001008 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001009 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001010 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001011 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001012 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001013 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001014 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001015 inst = inst->Next_2xx();
1016 }
1017 break;
1018 }
1019 case Instruction::IF_LEZ: {
1020 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001021 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001022 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001023 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001024 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001025 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001026 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001027 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001028 inst = inst->Next_2xx();
1029 }
1030 break;
1031 }
1032 case Instruction::AGET_BOOLEAN: {
1033 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001034 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001035 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001036 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001037 HANDLE_PENDING_EXCEPTION();
1038 break;
1039 }
1040 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001041 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001042 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001043 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001044 inst = inst->Next_2xx();
1045 } else {
1046 HANDLE_PENDING_EXCEPTION();
1047 }
1048 break;
1049 }
1050 case Instruction::AGET_BYTE: {
1051 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001052 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001053 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001054 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001055 HANDLE_PENDING_EXCEPTION();
1056 break;
1057 }
1058 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001059 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001060 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001061 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001062 inst = inst->Next_2xx();
1063 } else {
1064 HANDLE_PENDING_EXCEPTION();
1065 }
1066 break;
1067 }
1068 case Instruction::AGET_CHAR: {
1069 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001070 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001071 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001072 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001073 HANDLE_PENDING_EXCEPTION();
1074 break;
1075 }
1076 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001077 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001078 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001079 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001080 inst = inst->Next_2xx();
1081 } else {
1082 HANDLE_PENDING_EXCEPTION();
1083 }
1084 break;
1085 }
1086 case Instruction::AGET_SHORT: {
1087 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001088 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001089 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001090 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001091 HANDLE_PENDING_EXCEPTION();
1092 break;
1093 }
1094 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001095 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001096 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001097 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001098 inst = inst->Next_2xx();
1099 } else {
1100 HANDLE_PENDING_EXCEPTION();
1101 }
1102 break;
1103 }
1104 case Instruction::AGET: {
1105 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001106 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001107 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001108 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001109 HANDLE_PENDING_EXCEPTION();
1110 break;
1111 }
1112 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001113 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001114 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001115 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001116 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001117 inst = inst->Next_2xx();
1118 } else {
1119 HANDLE_PENDING_EXCEPTION();
1120 }
1121 break;
1122 }
1123 case Instruction::AGET_WIDE: {
1124 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001125 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001126 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001127 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001128 HANDLE_PENDING_EXCEPTION();
1129 break;
1130 }
1131 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001132 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001133 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001134 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001135 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001136 inst = inst->Next_2xx();
1137 } else {
1138 HANDLE_PENDING_EXCEPTION();
1139 }
1140 break;
1141 }
1142 case Instruction::AGET_OBJECT: {
1143 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001144 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001145 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001146 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001147 HANDLE_PENDING_EXCEPTION();
1148 break;
1149 }
1150 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001151 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001152 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001153 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001154 inst = inst->Next_2xx();
1155 } else {
1156 HANDLE_PENDING_EXCEPTION();
1157 }
1158 break;
1159 }
1160 case Instruction::APUT_BOOLEAN: {
1161 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001162 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001163 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001164 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001165 HANDLE_PENDING_EXCEPTION();
1166 break;
1167 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001168 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001169 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001170 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001171 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001172 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001173 inst = inst->Next_2xx();
1174 } else {
1175 HANDLE_PENDING_EXCEPTION();
1176 }
1177 break;
1178 }
1179 case Instruction::APUT_BYTE: {
1180 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001181 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001182 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001183 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001184 HANDLE_PENDING_EXCEPTION();
1185 break;
1186 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001187 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001188 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001189 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001190 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001191 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001192 inst = inst->Next_2xx();
1193 } else {
1194 HANDLE_PENDING_EXCEPTION();
1195 }
1196 break;
1197 }
1198 case Instruction::APUT_CHAR: {
1199 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001200 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001201 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001202 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001203 HANDLE_PENDING_EXCEPTION();
1204 break;
1205 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001206 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001207 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001208 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001209 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001210 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001211 inst = inst->Next_2xx();
1212 } else {
1213 HANDLE_PENDING_EXCEPTION();
1214 }
1215 break;
1216 }
1217 case Instruction::APUT_SHORT: {
1218 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001219 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001220 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001221 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001222 HANDLE_PENDING_EXCEPTION();
1223 break;
1224 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001225 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001226 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001227 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001228 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001229 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001230 inst = inst->Next_2xx();
1231 } else {
1232 HANDLE_PENDING_EXCEPTION();
1233 }
1234 break;
1235 }
1236 case Instruction::APUT: {
1237 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001238 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001239 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001240 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001241 HANDLE_PENDING_EXCEPTION();
1242 break;
1243 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001244 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001245 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001246 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001247 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001248 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001249 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001250 inst = inst->Next_2xx();
1251 } else {
1252 HANDLE_PENDING_EXCEPTION();
1253 }
1254 break;
1255 }
1256 case Instruction::APUT_WIDE: {
1257 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001258 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001259 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001260 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001261 HANDLE_PENDING_EXCEPTION();
1262 break;
1263 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001264 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001265 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001266 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001267 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001268 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001269 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001270 inst = inst->Next_2xx();
1271 } else {
1272 HANDLE_PENDING_EXCEPTION();
1273 }
1274 break;
1275 }
1276 case Instruction::APUT_OBJECT: {
1277 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001278 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001279 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001280 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001281 HANDLE_PENDING_EXCEPTION();
1282 break;
1283 }
1284 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001285 ObjPtr<mirror::Object> val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
1286 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001287 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001288 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001289 inst = inst->Next_2xx();
1290 } else {
1291 HANDLE_PENDING_EXCEPTION();
1292 }
1293 break;
1294 }
1295 case Instruction::IGET_BOOLEAN: {
1296 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001297 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1298 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001299 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1300 break;
1301 }
1302 case Instruction::IGET_BYTE: {
1303 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001304 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1305 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001306 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1307 break;
1308 }
1309 case Instruction::IGET_CHAR: {
1310 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001311 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1312 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001313 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1314 break;
1315 }
1316 case Instruction::IGET_SHORT: {
1317 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001318 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1319 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001320 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1321 break;
1322 }
1323 case Instruction::IGET: {
1324 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001325 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1326 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001327 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1328 break;
1329 }
1330 case Instruction::IGET_WIDE: {
1331 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001332 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1333 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001334 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1335 break;
1336 }
1337 case Instruction::IGET_OBJECT: {
1338 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001339 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1340 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001341 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1342 break;
1343 }
1344 case Instruction::IGET_QUICK: {
1345 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001346 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001347 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1348 break;
1349 }
1350 case Instruction::IGET_WIDE_QUICK: {
1351 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001352 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001353 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1354 break;
1355 }
1356 case Instruction::IGET_OBJECT_QUICK: {
1357 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001358 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001359 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1360 break;
1361 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001362 case Instruction::IGET_BOOLEAN_QUICK: {
1363 PREAMBLE();
1364 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1365 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1366 break;
1367 }
1368 case Instruction::IGET_BYTE_QUICK: {
1369 PREAMBLE();
1370 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1371 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1372 break;
1373 }
1374 case Instruction::IGET_CHAR_QUICK: {
1375 PREAMBLE();
1376 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1377 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1378 break;
1379 }
1380 case Instruction::IGET_SHORT_QUICK: {
1381 PREAMBLE();
1382 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1383 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1384 break;
1385 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001386 case Instruction::SGET_BOOLEAN: {
1387 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001388 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check,
1389 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001390 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1391 break;
1392 }
1393 case Instruction::SGET_BYTE: {
1394 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001395 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check,
1396 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001397 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1398 break;
1399 }
1400 case Instruction::SGET_CHAR: {
1401 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001402 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check,
1403 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001404 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1405 break;
1406 }
1407 case Instruction::SGET_SHORT: {
1408 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001409 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check,
1410 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001411 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1412 break;
1413 }
1414 case Instruction::SGET: {
1415 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001416 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check,
1417 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001418 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1419 break;
1420 }
1421 case Instruction::SGET_WIDE: {
1422 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001423 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check,
1424 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001425 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1426 break;
1427 }
1428 case Instruction::SGET_OBJECT: {
1429 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001430 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check,
1431 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001432 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1433 break;
1434 }
1435 case Instruction::IPUT_BOOLEAN: {
1436 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001437 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1438 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001439 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1440 break;
1441 }
1442 case Instruction::IPUT_BYTE: {
1443 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001444 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1445 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001446 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1447 break;
1448 }
1449 case Instruction::IPUT_CHAR: {
1450 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001451 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1452 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001453 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1454 break;
1455 }
1456 case Instruction::IPUT_SHORT: {
1457 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001458 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1459 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001460 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1461 break;
1462 }
1463 case Instruction::IPUT: {
1464 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001465 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1466 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001467 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1468 break;
1469 }
1470 case Instruction::IPUT_WIDE: {
1471 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001472 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1473 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001474 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1475 break;
1476 }
1477 case Instruction::IPUT_OBJECT: {
1478 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001479 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1480 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001481 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1482 break;
1483 }
1484 case Instruction::IPUT_QUICK: {
1485 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001486 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1487 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001488 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1489 break;
1490 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001491 case Instruction::IPUT_BOOLEAN_QUICK: {
1492 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001493 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1494 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001495 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1496 break;
1497 }
1498 case Instruction::IPUT_BYTE_QUICK: {
1499 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001500 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1501 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001502 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1503 break;
1504 }
1505 case Instruction::IPUT_CHAR_QUICK: {
1506 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001507 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1508 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001509 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1510 break;
1511 }
1512 case Instruction::IPUT_SHORT_QUICK: {
1513 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001514 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1515 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001516 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1517 break;
1518 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001519 case Instruction::IPUT_WIDE_QUICK: {
1520 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001521 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1522 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001523 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1524 break;
1525 }
1526 case Instruction::IPUT_OBJECT_QUICK: {
1527 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001528 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1529 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001530 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1531 break;
1532 }
1533 case Instruction::SPUT_BOOLEAN: {
1534 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001535 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1536 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001537 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1538 break;
1539 }
1540 case Instruction::SPUT_BYTE: {
1541 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001542 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1543 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001544 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1545 break;
1546 }
1547 case Instruction::SPUT_CHAR: {
1548 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001549 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1550 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001551 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1552 break;
1553 }
1554 case Instruction::SPUT_SHORT: {
1555 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001556 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1557 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001558 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1559 break;
1560 }
1561 case Instruction::SPUT: {
1562 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001563 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1564 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001565 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1566 break;
1567 }
1568 case Instruction::SPUT_WIDE: {
1569 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001570 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1571 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001572 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1573 break;
1574 }
1575 case Instruction::SPUT_OBJECT: {
1576 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001577 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1578 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001579 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1580 break;
1581 }
1582 case Instruction::INVOKE_VIRTUAL: {
1583 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001584 bool success = DoInvoke<kVirtual, false, do_access_check>(
1585 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001586 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1587 break;
1588 }
1589 case Instruction::INVOKE_VIRTUAL_RANGE: {
1590 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001591 bool success = DoInvoke<kVirtual, true, do_access_check>(
1592 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001593 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1594 break;
1595 }
1596 case Instruction::INVOKE_SUPER: {
1597 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001598 bool success = DoInvoke<kSuper, false, do_access_check>(
1599 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001600 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1601 break;
1602 }
1603 case Instruction::INVOKE_SUPER_RANGE: {
1604 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001605 bool success = DoInvoke<kSuper, true, do_access_check>(
1606 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001607 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1608 break;
1609 }
1610 case Instruction::INVOKE_DIRECT: {
1611 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001612 bool success = DoInvoke<kDirect, false, do_access_check>(
1613 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001614 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1615 break;
1616 }
1617 case Instruction::INVOKE_DIRECT_RANGE: {
1618 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001619 bool success = DoInvoke<kDirect, true, do_access_check>(
1620 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001621 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1622 break;
1623 }
1624 case Instruction::INVOKE_INTERFACE: {
1625 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001626 bool success = DoInvoke<kInterface, false, do_access_check>(
1627 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001628 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1629 break;
1630 }
1631 case Instruction::INVOKE_INTERFACE_RANGE: {
1632 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001633 bool success = DoInvoke<kInterface, true, do_access_check>(
1634 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001635 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1636 break;
1637 }
1638 case Instruction::INVOKE_STATIC: {
1639 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001640 bool success = DoInvoke<kStatic, false, do_access_check>(
1641 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001642 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1643 break;
1644 }
1645 case Instruction::INVOKE_STATIC_RANGE: {
1646 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001647 bool success = DoInvoke<kStatic, true, do_access_check>(
1648 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001649 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1650 break;
1651 }
1652 case Instruction::INVOKE_VIRTUAL_QUICK: {
1653 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001654 bool success = DoInvokeVirtualQuick<false>(
1655 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001656 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1657 break;
1658 }
1659 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1660 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001661 bool success = DoInvokeVirtualQuick<true>(
1662 self, shadow_frame, inst, inst_data, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001663 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1664 break;
1665 }
Narayan Kamath9823e782016-08-03 12:46:58 +01001666 case Instruction::INVOKE_POLYMORPHIC: {
1667 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001668 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Orion Hodsonc069a302017-01-18 09:23:12 +00001669 bool success = DoInvokePolymorphic<false /* is_range */>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001670 self, shadow_frame, inst, inst_data, &result_register);
1671 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_4xx);
1672 break;
1673 }
1674 case Instruction::INVOKE_POLYMORPHIC_RANGE: {
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<true /* 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;
Narayan Kamath9823e782016-08-03 12:46:58 +01001681 }
Orion Hodsonc069a302017-01-18 09:23:12 +00001682 case Instruction::INVOKE_CUSTOM: {
1683 PREAMBLE();
1684 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1685 bool success = DoInvokeCustom<false /* is_range */>(
1686 self, shadow_frame, inst, inst_data, &result_register);
1687 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1688 break;
1689 }
1690 case Instruction::INVOKE_CUSTOM_RANGE: {
1691 PREAMBLE();
1692 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1693 bool success = DoInvokeCustom<true /* is_range */>(
1694 self, shadow_frame, inst, inst_data, &result_register);
1695 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
1696 break;
1697 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001698 case Instruction::NEG_INT:
1699 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001700 shadow_frame.SetVReg(
1701 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001702 inst = inst->Next_1xx();
1703 break;
1704 case Instruction::NOT_INT:
1705 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001706 shadow_frame.SetVReg(
1707 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001708 inst = inst->Next_1xx();
1709 break;
1710 case Instruction::NEG_LONG:
1711 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001712 shadow_frame.SetVRegLong(
1713 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001714 inst = inst->Next_1xx();
1715 break;
1716 case Instruction::NOT_LONG:
1717 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001718 shadow_frame.SetVRegLong(
1719 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001720 inst = inst->Next_1xx();
1721 break;
1722 case Instruction::NEG_FLOAT:
1723 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001724 shadow_frame.SetVRegFloat(
1725 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001726 inst = inst->Next_1xx();
1727 break;
1728 case Instruction::NEG_DOUBLE:
1729 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001730 shadow_frame.SetVRegDouble(
1731 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001732 inst = inst->Next_1xx();
1733 break;
1734 case Instruction::INT_TO_LONG:
1735 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001736 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1737 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001738 inst = inst->Next_1xx();
1739 break;
1740 case Instruction::INT_TO_FLOAT:
1741 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001742 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1743 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001744 inst = inst->Next_1xx();
1745 break;
1746 case Instruction::INT_TO_DOUBLE:
1747 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001748 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1749 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001750 inst = inst->Next_1xx();
1751 break;
1752 case Instruction::LONG_TO_INT:
1753 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001754 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1755 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001756 inst = inst->Next_1xx();
1757 break;
1758 case Instruction::LONG_TO_FLOAT:
1759 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001760 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1761 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001762 inst = inst->Next_1xx();
1763 break;
1764 case Instruction::LONG_TO_DOUBLE:
1765 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001766 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1767 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001768 inst = inst->Next_1xx();
1769 break;
1770 case Instruction::FLOAT_TO_INT: {
1771 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001772 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001773 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001774 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001775 inst = inst->Next_1xx();
1776 break;
1777 }
1778 case Instruction::FLOAT_TO_LONG: {
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 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001782 shadow_frame.SetVRegLong(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_DOUBLE:
1787 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001788 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1789 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001790 inst = inst->Next_1xx();
1791 break;
1792 case Instruction::DOUBLE_TO_INT: {
1793 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001794 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001795 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001796 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001797 inst = inst->Next_1xx();
1798 break;
1799 }
1800 case Instruction::DOUBLE_TO_LONG: {
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 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001804 shadow_frame.SetVRegLong(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_FLOAT:
1809 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001810 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1811 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001812 inst = inst->Next_1xx();
1813 break;
1814 case Instruction::INT_TO_BYTE:
1815 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001816 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1817 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001818 inst = inst->Next_1xx();
1819 break;
1820 case Instruction::INT_TO_CHAR:
1821 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001822 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1823 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001824 inst = inst->Next_1xx();
1825 break;
1826 case Instruction::INT_TO_SHORT:
1827 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001828 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1829 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001830 inst = inst->Next_1xx();
1831 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001832 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001833 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001834 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001835 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1836 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001837 inst = inst->Next_2xx();
1838 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001839 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001840 case Instruction::SUB_INT:
1841 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 SafeSub(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;
1847 case Instruction::MUL_INT:
1848 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001849 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001850 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1851 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001852 inst = inst->Next_2xx();
1853 break;
1854 case Instruction::DIV_INT: {
1855 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001856 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001857 shadow_frame.GetVReg(inst->VRegB_23x()),
1858 shadow_frame.GetVReg(inst->VRegC_23x()));
1859 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1860 break;
1861 }
1862 case Instruction::REM_INT: {
1863 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001864 bool success = DoIntRemainder(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::SHL_INT:
1871 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001872 shadow_frame.SetVReg(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()) & 0x1f));
1875 inst = inst->Next_2xx();
1876 break;
1877 case Instruction::SHR_INT:
1878 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001879 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001880 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1881 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1882 inst = inst->Next_2xx();
1883 break;
1884 case Instruction::USHR_INT:
1885 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001886 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001887 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1888 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1889 inst = inst->Next_2xx();
1890 break;
1891 case Instruction::AND_INT:
1892 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001893 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001894 shadow_frame.GetVReg(inst->VRegB_23x()) &
1895 shadow_frame.GetVReg(inst->VRegC_23x()));
1896 inst = inst->Next_2xx();
1897 break;
1898 case Instruction::OR_INT:
1899 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001900 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001901 shadow_frame.GetVReg(inst->VRegB_23x()) |
1902 shadow_frame.GetVReg(inst->VRegC_23x()));
1903 inst = inst->Next_2xx();
1904 break;
1905 case Instruction::XOR_INT:
1906 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001907 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001908 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1909 shadow_frame.GetVReg(inst->VRegC_23x()));
1910 inst = inst->Next_2xx();
1911 break;
1912 case Instruction::ADD_LONG:
1913 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001914 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001915 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1916 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001917 inst = inst->Next_2xx();
1918 break;
1919 case Instruction::SUB_LONG:
1920 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001921 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001922 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1923 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001924 inst = inst->Next_2xx();
1925 break;
1926 case Instruction::MUL_LONG:
1927 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001928 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001929 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
1930 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001931 inst = inst->Next_2xx();
1932 break;
1933 case Instruction::DIV_LONG:
1934 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001935 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001936 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001937 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001938 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1939 break;
1940 case Instruction::REM_LONG:
1941 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001942 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001943 shadow_frame.GetVRegLong(inst->VRegB_23x()),
1944 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1945 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
1946 break;
1947 case Instruction::AND_LONG:
1948 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001949 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001950 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
1951 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1952 inst = inst->Next_2xx();
1953 break;
1954 case Instruction::OR_LONG:
1955 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001956 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001957 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
1958 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1959 inst = inst->Next_2xx();
1960 break;
1961 case Instruction::XOR_LONG:
1962 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001963 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001964 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
1965 shadow_frame.GetVRegLong(inst->VRegC_23x()));
1966 inst = inst->Next_2xx();
1967 break;
1968 case Instruction::SHL_LONG:
1969 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001970 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001971 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
1972 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1973 inst = inst->Next_2xx();
1974 break;
1975 case Instruction::SHR_LONG:
1976 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001977 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001978 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
1979 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1980 inst = inst->Next_2xx();
1981 break;
1982 case Instruction::USHR_LONG:
1983 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001984 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001985 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
1986 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
1987 inst = inst->Next_2xx();
1988 break;
1989 case Instruction::ADD_FLOAT:
1990 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001991 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001992 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
1993 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
1994 inst = inst->Next_2xx();
1995 break;
1996 case Instruction::SUB_FLOAT:
1997 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001998 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001999 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
2000 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2001 inst = inst->Next_2xx();
2002 break;
2003 case Instruction::MUL_FLOAT:
2004 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002005 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002006 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
2007 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2008 inst = inst->Next_2xx();
2009 break;
2010 case Instruction::DIV_FLOAT:
2011 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002012 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002013 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
2014 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2015 inst = inst->Next_2xx();
2016 break;
2017 case Instruction::REM_FLOAT:
2018 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002019 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002020 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
2021 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
2022 inst = inst->Next_2xx();
2023 break;
2024 case Instruction::ADD_DOUBLE:
2025 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002026 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002027 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
2028 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2029 inst = inst->Next_2xx();
2030 break;
2031 case Instruction::SUB_DOUBLE:
2032 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002033 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002034 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
2035 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2036 inst = inst->Next_2xx();
2037 break;
2038 case Instruction::MUL_DOUBLE:
2039 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002040 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002041 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
2042 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2043 inst = inst->Next_2xx();
2044 break;
2045 case Instruction::DIV_DOUBLE:
2046 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002047 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002048 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2049 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2050 inst = inst->Next_2xx();
2051 break;
2052 case Instruction::REM_DOUBLE:
2053 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002054 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002055 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2056 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2057 inst = inst->Next_2xx();
2058 break;
2059 case Instruction::ADD_INT_2ADDR: {
2060 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002061 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07002062 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
2063 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002064 inst = inst->Next_1xx();
2065 break;
2066 }
2067 case Instruction::SUB_INT_2ADDR: {
2068 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002069 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002070 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002071 SafeSub(shadow_frame.GetVReg(vregA),
2072 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002073 inst = inst->Next_1xx();
2074 break;
2075 }
2076 case Instruction::MUL_INT_2ADDR: {
2077 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002078 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002079 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002080 SafeMul(shadow_frame.GetVReg(vregA),
2081 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002082 inst = inst->Next_1xx();
2083 break;
2084 }
2085 case Instruction::DIV_INT_2ADDR: {
2086 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002087 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002088 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002089 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002090 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2091 break;
2092 }
2093 case Instruction::REM_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 = DoIntRemainder(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::SHL_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 shadow_frame.SetVReg(vregA,
2105 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002106 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002107 inst = inst->Next_1xx();
2108 break;
2109 }
2110 case Instruction::SHR_INT_2ADDR: {
2111 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002112 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002113 shadow_frame.SetVReg(vregA,
2114 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002115 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002116 inst = inst->Next_1xx();
2117 break;
2118 }
2119 case Instruction::USHR_INT_2ADDR: {
2120 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002121 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002122 shadow_frame.SetVReg(vregA,
2123 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002124 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002125 inst = inst->Next_1xx();
2126 break;
2127 }
2128 case Instruction::AND_INT_2ADDR: {
2129 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002130 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002131 shadow_frame.SetVReg(vregA,
2132 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002133 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002134 inst = inst->Next_1xx();
2135 break;
2136 }
2137 case Instruction::OR_INT_2ADDR: {
2138 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002139 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002140 shadow_frame.SetVReg(vregA,
2141 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002142 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002143 inst = inst->Next_1xx();
2144 break;
2145 }
2146 case Instruction::XOR_INT_2ADDR: {
2147 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002148 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002149 shadow_frame.SetVReg(vregA,
2150 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002151 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002152 inst = inst->Next_1xx();
2153 break;
2154 }
2155 case Instruction::ADD_LONG_2ADDR: {
2156 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002157 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002158 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002159 SafeAdd(shadow_frame.GetVRegLong(vregA),
2160 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002161 inst = inst->Next_1xx();
2162 break;
2163 }
2164 case Instruction::SUB_LONG_2ADDR: {
2165 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002166 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002167 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002168 SafeSub(shadow_frame.GetVRegLong(vregA),
2169 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002170 inst = inst->Next_1xx();
2171 break;
2172 }
2173 case Instruction::MUL_LONG_2ADDR: {
2174 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002175 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002176 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002177 SafeMul(shadow_frame.GetVRegLong(vregA),
2178 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002179 inst = inst->Next_1xx();
2180 break;
2181 }
2182 case Instruction::DIV_LONG_2ADDR: {
2183 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002184 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002185 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002186 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002187 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2188 break;
2189 }
2190 case Instruction::REM_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 DoLongRemainder(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::AND_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 shadow_frame.SetVRegLong(vregA,
2202 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002203 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002204 inst = inst->Next_1xx();
2205 break;
2206 }
2207 case Instruction::OR_LONG_2ADDR: {
2208 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002209 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002210 shadow_frame.SetVRegLong(vregA,
2211 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002212 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002213 inst = inst->Next_1xx();
2214 break;
2215 }
2216 case Instruction::XOR_LONG_2ADDR: {
2217 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002218 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002219 shadow_frame.SetVRegLong(vregA,
2220 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002221 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002222 inst = inst->Next_1xx();
2223 break;
2224 }
2225 case Instruction::SHL_LONG_2ADDR: {
2226 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002227 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002228 shadow_frame.SetVRegLong(vregA,
2229 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002230 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002231 inst = inst->Next_1xx();
2232 break;
2233 }
2234 case Instruction::SHR_LONG_2ADDR: {
2235 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002236 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002237 shadow_frame.SetVRegLong(vregA,
2238 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002239 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002240 inst = inst->Next_1xx();
2241 break;
2242 }
2243 case Instruction::USHR_LONG_2ADDR: {
2244 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002245 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002246 shadow_frame.SetVRegLong(vregA,
2247 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002248 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002249 inst = inst->Next_1xx();
2250 break;
2251 }
2252 case Instruction::ADD_FLOAT_2ADDR: {
2253 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002254 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002255 shadow_frame.SetVRegFloat(vregA,
2256 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002257 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002258 inst = inst->Next_1xx();
2259 break;
2260 }
2261 case Instruction::SUB_FLOAT_2ADDR: {
2262 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002263 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002264 shadow_frame.SetVRegFloat(vregA,
2265 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002266 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002267 inst = inst->Next_1xx();
2268 break;
2269 }
2270 case Instruction::MUL_FLOAT_2ADDR: {
2271 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002272 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002273 shadow_frame.SetVRegFloat(vregA,
2274 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002275 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002276 inst = inst->Next_1xx();
2277 break;
2278 }
2279 case Instruction::DIV_FLOAT_2ADDR: {
2280 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002281 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002282 shadow_frame.SetVRegFloat(vregA,
2283 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002284 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002285 inst = inst->Next_1xx();
2286 break;
2287 }
2288 case Instruction::REM_FLOAT_2ADDR: {
2289 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002290 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002291 shadow_frame.SetVRegFloat(vregA,
2292 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002293 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002294 inst = inst->Next_1xx();
2295 break;
2296 }
2297 case Instruction::ADD_DOUBLE_2ADDR: {
2298 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002299 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002300 shadow_frame.SetVRegDouble(vregA,
2301 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002302 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002303 inst = inst->Next_1xx();
2304 break;
2305 }
2306 case Instruction::SUB_DOUBLE_2ADDR: {
2307 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002308 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002309 shadow_frame.SetVRegDouble(vregA,
2310 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002311 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002312 inst = inst->Next_1xx();
2313 break;
2314 }
2315 case Instruction::MUL_DOUBLE_2ADDR: {
2316 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002317 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002318 shadow_frame.SetVRegDouble(vregA,
2319 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002320 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002321 inst = inst->Next_1xx();
2322 break;
2323 }
2324 case Instruction::DIV_DOUBLE_2ADDR: {
2325 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002326 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002327 shadow_frame.SetVRegDouble(vregA,
2328 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002329 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002330 inst = inst->Next_1xx();
2331 break;
2332 }
2333 case Instruction::REM_DOUBLE_2ADDR: {
2334 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002335 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002336 shadow_frame.SetVRegDouble(vregA,
2337 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002338 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002339 inst = inst->Next_1xx();
2340 break;
2341 }
2342 case Instruction::ADD_INT_LIT16:
2343 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002344 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002345 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2346 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002347 inst = inst->Next_2xx();
2348 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002349 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002350 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002351 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002352 SafeSub(inst->VRegC_22s(),
2353 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002354 inst = inst->Next_2xx();
2355 break;
2356 case Instruction::MUL_INT_LIT16:
2357 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002358 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002359 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2360 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002361 inst = inst->Next_2xx();
2362 break;
2363 case Instruction::DIV_INT_LIT16: {
2364 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002365 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002366 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2367 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002368 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2369 break;
2370 }
2371 case Instruction::REM_INT_LIT16: {
2372 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002373 bool success = DoIntRemainder(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::AND_INT_LIT16:
2380 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002381 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2382 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002383 inst->VRegC_22s());
2384 inst = inst->Next_2xx();
2385 break;
2386 case Instruction::OR_INT_LIT16:
2387 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002388 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2389 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002390 inst->VRegC_22s());
2391 inst = inst->Next_2xx();
2392 break;
2393 case Instruction::XOR_INT_LIT16:
2394 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002395 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2396 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002397 inst->VRegC_22s());
2398 inst = inst->Next_2xx();
2399 break;
2400 case Instruction::ADD_INT_LIT8:
2401 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002402 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002403 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002404 inst = inst->Next_2xx();
2405 break;
2406 case Instruction::RSUB_INT_LIT8:
2407 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002408 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002409 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002410 inst = inst->Next_2xx();
2411 break;
2412 case Instruction::MUL_INT_LIT8:
2413 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002414 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002415 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002416 inst = inst->Next_2xx();
2417 break;
2418 case Instruction::DIV_INT_LIT8: {
2419 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002420 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002421 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2422 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2423 break;
2424 }
2425 case Instruction::REM_INT_LIT8: {
2426 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002427 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002428 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2429 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2430 break;
2431 }
2432 case Instruction::AND_INT_LIT8:
2433 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002434 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002435 shadow_frame.GetVReg(inst->VRegB_22b()) &
2436 inst->VRegC_22b());
2437 inst = inst->Next_2xx();
2438 break;
2439 case Instruction::OR_INT_LIT8:
2440 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002441 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002442 shadow_frame.GetVReg(inst->VRegB_22b()) |
2443 inst->VRegC_22b());
2444 inst = inst->Next_2xx();
2445 break;
2446 case Instruction::XOR_INT_LIT8:
2447 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002448 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002449 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2450 inst->VRegC_22b());
2451 inst = inst->Next_2xx();
2452 break;
2453 case Instruction::SHL_INT_LIT8:
2454 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002455 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002456 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2457 (inst->VRegC_22b() & 0x1f));
2458 inst = inst->Next_2xx();
2459 break;
2460 case Instruction::SHR_INT_LIT8:
2461 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002462 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002463 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2464 (inst->VRegC_22b() & 0x1f));
2465 inst = inst->Next_2xx();
2466 break;
2467 case Instruction::USHR_INT_LIT8:
2468 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002469 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002470 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2471 (inst->VRegC_22b() & 0x1f));
2472 inst = inst->Next_2xx();
2473 break;
2474 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Orion Hodson2e599942017-09-22 16:17:41 +01002475 case Instruction::UNUSED_79 ... Instruction::UNUSED_7A:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002476 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
Ian Rogerse94652f2014-12-02 11:13:19 -08002477 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002478 }
buzbee1452bee2015-03-06 14:43:04 -08002479 } while (!interpret_one_instruction);
2480 // Record where we stopped.
2481 shadow_frame.SetDexPC(inst->GetDexPc(insns));
buzbeed6b48db2016-01-28 15:48:55 -08002482 return result_register;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002483} // NOLINT(readability/fn_size)
2484
2485// Explicit definitions of ExecuteSwitchImpl.
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002486template HOT_ATTR
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002487JValue ExecuteSwitchImpl<true, false>(Thread* self, const CodeItemDataAccessor& accessor,
buzbee1452bee2015-03-06 14:43:04 -08002488 ShadowFrame& shadow_frame, JValue result_register,
2489 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002490template HOT_ATTR
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002491JValue ExecuteSwitchImpl<false, false>(Thread* self, const CodeItemDataAccessor& accessor,
buzbee1452bee2015-03-06 14:43:04 -08002492 ShadowFrame& shadow_frame, JValue result_register,
2493 bool interpret_one_instruction);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002494template
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002495JValue ExecuteSwitchImpl<true, true>(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
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002499JValue ExecuteSwitchImpl<false, true>(Thread* self, const CodeItemDataAccessor& accessor,
buzbee1452bee2015-03-06 14:43:04 -08002500 ShadowFrame& shadow_frame, JValue result_register,
2501 bool interpret_one_instruction);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002502
2503} // namespace interpreter
2504} // namespace art