blob: 4774d6994eb10e21a79a8cea7c6fb5aca47d78bc [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
David Srbecky2ee09ff2018-10-24 13:24:22 +010017#ifndef ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
18#define ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
19
Andreas Gampe5e26eb12016-08-22 17:54:17 -070020#include "interpreter_switch_impl.h"
21
Andreas Gampe542451c2016-07-26 09:02:02 -070022#include "base/enums.h"
Alex Light6f22e062018-10-05 15:05:12 -070023#include "base/memory_tool.h"
David Sehrc431b9d2018-03-02 12:01:51 -080024#include "base/quasi_atomic.h"
David Sehr9e734c72018-01-04 17:56:19 -080025#include "dex/dex_file_types.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070026#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020027#include "interpreter_common.h"
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000028#include "jit/jit.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070029#include "jvalue-inl.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000030#include "nth_caller_visitor.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070031#include "safe_math.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010032#include "shadow_frame-inl.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000033#include "thread.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020034
35namespace art {
36namespace interpreter {
37
Alex Light0aa7a5a2018-10-10 15:58:14 +000038#define CHECK_FORCE_RETURN() \
39 do { \
40 if (UNLIKELY(shadow_frame.GetForcePopFrame())) { \
41 DCHECK(PrevFrameWillRetry(self, shadow_frame)) \
42 << "Pop frame forced without previous frame ready to retry instruction!"; \
43 DCHECK(Runtime::Current()->AreNonStandardExitsEnabled()); \
44 if (UNLIKELY(NeedsMethodExitEvent(instrumentation))) { \
45 SendMethodExitEvents(self, \
46 instrumentation, \
47 shadow_frame, \
48 shadow_frame.GetThisObject(accessor.InsSize()), \
49 shadow_frame.GetMethod(), \
50 inst->GetDexPc(insns), \
51 JValue()); \
52 } \
53 ctx->result = JValue(); /* Handled in caller. */ \
54 return; \
55 } \
56 } while (false)
57
Alex Lightb7edcda2017-04-27 13:20:31 -070058#define HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instr) \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020059 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020060 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070061 self->AllowThreadSuspension(); \
Alex Light0aa7a5a2018-10-10 15:58:14 +000062 CHECK_FORCE_RETURN(); \
Alex Light9fb1ab12017-09-05 09:32:49 -070063 if (!MoveToExceptionHandler(self, shadow_frame, instr)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070064 /* Structured locking is to be enforced for abnormal termination, too. */ \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070065 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame); \
buzbee1452bee2015-03-06 14:43:04 -080066 if (interpret_one_instruction) { \
buzbee93e94f22016-04-07 13:52:48 -070067 /* Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -070068 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee1452bee2015-03-06 14:43:04 -080069 } \
David Srbecky946bb092018-03-09 17:23:01 +000070 ctx->result = JValue(); /* Handled in caller. */ \
71 return; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020072 } else { \
Alex Light0aa7a5a2018-10-10 15:58:14 +000073 CHECK_FORCE_RETURN(); \
Alex Light9fb1ab12017-09-05 09:32:49 -070074 int32_t displacement = \
75 static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020076 inst = inst->RelativeAt(displacement); \
77 } \
78 } while (false)
79
Alex Lightb7edcda2017-04-27 13:20:31 -070080#define HANDLE_PENDING_EXCEPTION() HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instrumentation)
81
Alex Light0aa7a5a2018-10-10 15:58:14 +000082#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, _next_function) \
83 do { \
84 if (UNLIKELY(shadow_frame.GetForceRetryInstruction())) { \
85 /* Don't need to do anything except clear the flag and exception. We leave the */ \
86 /* instruction the same so it will be re-executed on the next go-around. */ \
87 DCHECK(inst->IsInvoke()); \
88 shadow_frame.SetForceRetryInstruction(false); \
89 if (UNLIKELY(_is_exception_pending)) { \
90 DCHECK(self->IsExceptionPending()); \
91 if (kIsDebugBuild) { \
92 LOG(WARNING) << "Suppressing exception for instruction-retry: " \
93 << self->GetException()->Dump(); \
94 } \
95 self->ClearException(); \
96 } \
97 } else if (UNLIKELY(_is_exception_pending)) { \
98 /* Should have succeeded. */ \
99 DCHECK(!shadow_frame.GetForceRetryInstruction()); \
100 HANDLE_PENDING_EXCEPTION(); \
101 } else { \
102 inst = inst->_next_function(); \
103 } \
104 } while (false)
105
106#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(_is_exception_pending) \
107 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, Next_4xx)
108#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(_is_exception_pending) \
109 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, Next_3xx)
110
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200111#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
112 do { \
Alex Light0aa7a5a2018-10-10 15:58:14 +0000113 /* Should only be on invoke instructions. */ \
114 DCHECK(!shadow_frame.GetForceRetryInstruction()); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200115 if (UNLIKELY(_is_exception_pending)) { \
116 HANDLE_PENDING_EXCEPTION(); \
117 } else { \
118 inst = inst->_next_function(); \
119 } \
120 } while (false)
121
Andreas Gampe03ec9302015-08-27 17:41:47 -0700122#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -0700123 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -0700124 HANDLE_PENDING_EXCEPTION(); \
125 }
126
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200127// Code to run before each dex instruction.
Alex Light0aa7a5a2018-10-10 15:58:14 +0000128#define PREAMBLE_SAVE(save_ref) \
Alex Lightfc905672017-06-27 17:53:15 -0700129 { \
Alex Light0aa7a5a2018-10-10 15:58:14 +0000130 /* We need to put this before & after the instrumentation to avoid having to put in a */ \
131 /* post-script macro. */ \
132 CHECK_FORCE_RETURN(); \
133 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
134 if (UNLIKELY(!DoDexPcMoveEvent(self, \
135 accessor, \
136 shadow_frame, \
137 dex_pc, \
138 instrumentation, \
139 save_ref))) { \
140 HANDLE_PENDING_EXCEPTION(); \
141 break; \
142 } \
143 CHECK_FORCE_RETURN(); \
Sebastien Hertz8379b222014-02-24 17:38:15 +0100144 } \
Alex Lightfc905672017-06-27 17:53:15 -0700145 } \
146 do {} while (false)
147
148#define PREAMBLE() PREAMBLE_SAVE(nullptr)
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200149
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000150#define BRANCH_INSTRUMENTATION(offset) \
151 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100152 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
Alex Lightcc917d92018-02-22 13:28:28 -0800153 instrumentation->Branch(self, shadow_frame.GetMethod(), dex_pc, offset); \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100154 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000155 JValue result; \
Alex Lightcc917d92018-02-22 13:28:28 -0800156 if (jit::Jit::MaybeDoOnStackReplacement(self, \
157 shadow_frame.GetMethod(), \
158 dex_pc, \
159 offset, \
160 &result)) { \
buzbee93e94f22016-04-07 13:52:48 -0700161 if (interpret_one_instruction) { \
162 /* OSR has completed execution of the method. Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -0700163 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee93e94f22016-04-07 13:52:48 -0700164 } \
David Srbecky946bb092018-03-09 17:23:01 +0000165 ctx->result = result; \
166 return; \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000167 } \
Nicolas Geoffray3108daf2015-11-24 16:32:33 +0000168 } while (false)
169
Bill Buzbee1d011d92016-04-04 16:59:29 +0000170#define HOTNESS_UPDATE() \
171 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100172 if (jit != nullptr) { \
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700173 jit->AddSamples(self, shadow_frame.GetMethod(), 1, /*with_backedges=*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +0000174 } \
175 } while (false)
176
Alex Light848574c2017-09-25 16:59:39 -0700177#define HANDLE_ASYNC_EXCEPTION() \
178 if (UNLIKELY(self->ObserveAsyncException())) { \
179 HANDLE_PENDING_EXCEPTION(); \
180 break; \
181 } \
182 do {} while (false)
183
Andreas Gampef4f76372016-12-13 14:43:58 -0800184#define HANDLE_BACKWARD_BRANCH(offset) \
185 do { \
186 if (IsBackwardBranch(offset)) { \
187 HOTNESS_UPDATE(); \
188 /* Record new dex pc early to have consistent suspend point at loop header. */ \
189 shadow_frame.SetDexPC(inst->GetDexPc(insns)); \
190 self->AllowThreadSuspension(); \
191 } \
192 } while (false)
193
Alex Lightfc905672017-06-27 17:53:15 -0700194// Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
195// the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
196// to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
197// jvmti-agents while handling breakpoint or single step events. We had to move this into its own
198// function because it was making ExecuteSwitchImpl have too large a stack.
Alex Light2989a4a2017-06-29 09:44:57 -0700199NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800200 const CodeItemDataAccessor& accessor,
Alex Light2989a4a2017-06-29 09:44:57 -0700201 const ShadowFrame& shadow_frame,
202 uint32_t dex_pc,
203 const instrumentation::Instrumentation* instrumentation,
204 JValue* save_ref)
Alex Lightfc905672017-06-27 17:53:15 -0700205 REQUIRES_SHARED(Locks::mutator_lock_) {
206 DCHECK(instrumentation->HasDexPcListeners());
207 StackHandleScope<2> hs(self);
208 Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
209 mirror::Object* null_obj = nullptr;
210 HandleWrapper<mirror::Object> h(
211 hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
212 self->ClearException();
213 instrumentation->DexPcMovedEvent(self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800214 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lightfc905672017-06-27 17:53:15 -0700215 shadow_frame.GetMethod(),
216 dex_pc);
217 if (UNLIKELY(self->IsExceptionPending())) {
218 // We got a new exception in the dex-pc-moved event. We just let this exception replace the old
219 // one.
220 // TODO It would be good to add the old exception to the suppressed exceptions of the new one if
221 // possible.
222 return false;
223 } else {
224 if (UNLIKELY(!thr.IsNull())) {
225 self->SetException(thr.Get());
226 }
227 return true;
228 }
229}
230
Alex Lighte814f9d2017-07-31 16:14:39 -0700231static bool NeedsMethodExitEvent(const instrumentation::Instrumentation* ins)
232 REQUIRES_SHARED(Locks::mutator_lock_) {
233 return ins->HasMethodExitListeners() || ins->HasWatchedFramePopListeners();
234}
235
236// Sends the normal method exit event. Returns true if the events succeeded and false if there is a
237// pending exception.
238NO_INLINE static bool SendMethodExitEvents(Thread* self,
239 const instrumentation::Instrumentation* instrumentation,
240 const ShadowFrame& frame,
241 ObjPtr<mirror::Object> thiz,
242 ArtMethod* method,
243 uint32_t dex_pc,
244 const JValue& result)
245 REQUIRES_SHARED(Locks::mutator_lock_) {
246 bool had_event = false;
Alex Light0aa7a5a2018-10-10 15:58:14 +0000247 // We don't send method-exit if it's a pop-frame. We still send frame_popped though.
248 if (UNLIKELY(instrumentation->HasMethodExitListeners() && !frame.GetForcePopFrame())) {
Alex Lighte814f9d2017-07-31 16:14:39 -0700249 had_event = true;
250 instrumentation->MethodExitEvent(self, thiz.Ptr(), method, dex_pc, result);
251 }
252 if (UNLIKELY(frame.NeedsNotifyPop() && instrumentation->HasWatchedFramePopListeners())) {
253 had_event = true;
254 instrumentation->WatchedFramePopped(self, frame);
255 }
256 if (UNLIKELY(had_event)) {
257 return !self->IsExceptionPending();
258 } else {
259 return true;
260 }
261}
262
Alex Light6f22e062018-10-05 15:05:12 -0700263// TODO On ASAN builds this function gets a huge stack frame. Since normally we run in the mterp
264// this shouldn't cause any problems for stack overflow detection. Remove this once b/117341496 is
265// fixed.
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100266template<bool do_access_check, bool transaction_active>
Alex Light6f22e062018-10-05 15:05:12 -0700267ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
David Srbecky946bb092018-03-09 17:23:01 +0000268 Thread* self = ctx->self;
269 const CodeItemDataAccessor& accessor = ctx->accessor;
270 ShadowFrame& shadow_frame = ctx->shadow_frame;
271 JValue result_register = ctx->result_register;
272 bool interpret_one_instruction = ctx->interpret_one_instruction;
Igor Murashkinc449e8b2015-06-10 15:56:42 -0700273 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200274 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
275 LOG(FATAL) << "Invalid shadow frame for interpreter use";
David Srbecky946bb092018-03-09 17:23:01 +0000276 ctx->result = JValue();
277 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200278 }
279 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200280
281 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700282 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800283 const uint16_t* const insns = accessor.Insns();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200284 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200285 uint16_t inst_data;
Bill Buzbee1d011d92016-04-04 16:59:29 +0000286 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700287
Alex Light0aa7a5a2018-10-10 15:58:14 +0000288 DCHECK(!shadow_frame.GetForceRetryInstruction())
289 << "Entered interpreter from invoke without retry instruction being handled!";
290
buzbee1452bee2015-03-06 14:43:04 -0800291 do {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200292 dex_pc = inst->GetDexPc(insns);
293 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800294 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200295 inst_data = inst->Fetch16(0);
296 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200297 case Instruction::NOP:
298 PREAMBLE();
299 inst = inst->Next_1xx();
300 break;
301 case Instruction::MOVE:
302 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200303 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
304 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200305 inst = inst->Next_1xx();
306 break;
307 case Instruction::MOVE_FROM16:
308 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200309 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200310 shadow_frame.GetVReg(inst->VRegB_22x()));
311 inst = inst->Next_2xx();
312 break;
313 case Instruction::MOVE_16:
314 PREAMBLE();
315 shadow_frame.SetVReg(inst->VRegA_32x(),
316 shadow_frame.GetVReg(inst->VRegB_32x()));
317 inst = inst->Next_3xx();
318 break;
319 case Instruction::MOVE_WIDE:
320 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200321 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
322 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200323 inst = inst->Next_1xx();
324 break;
325 case Instruction::MOVE_WIDE_FROM16:
326 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200327 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200328 shadow_frame.GetVRegLong(inst->VRegB_22x()));
329 inst = inst->Next_2xx();
330 break;
331 case Instruction::MOVE_WIDE_16:
332 PREAMBLE();
333 shadow_frame.SetVRegLong(inst->VRegA_32x(),
334 shadow_frame.GetVRegLong(inst->VRegB_32x()));
335 inst = inst->Next_3xx();
336 break;
337 case Instruction::MOVE_OBJECT:
338 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200339 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
340 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200341 inst = inst->Next_1xx();
342 break;
343 case Instruction::MOVE_OBJECT_FROM16:
344 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200345 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200346 shadow_frame.GetVRegReference(inst->VRegB_22x()));
347 inst = inst->Next_2xx();
348 break;
349 case Instruction::MOVE_OBJECT_16:
350 PREAMBLE();
351 shadow_frame.SetVRegReference(inst->VRegA_32x(),
352 shadow_frame.GetVRegReference(inst->VRegB_32x()));
353 inst = inst->Next_3xx();
354 break;
355 case Instruction::MOVE_RESULT:
356 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200357 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200358 inst = inst->Next_1xx();
359 break;
360 case Instruction::MOVE_RESULT_WIDE:
361 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200362 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200363 inst = inst->Next_1xx();
364 break;
365 case Instruction::MOVE_RESULT_OBJECT:
Alex Lightfc905672017-06-27 17:53:15 -0700366 PREAMBLE_SAVE(&result_register);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200367 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200368 inst = inst->Next_1xx();
369 break;
370 case Instruction::MOVE_EXCEPTION: {
371 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700372 ObjPtr<mirror::Throwable> exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100373 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100374 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200375 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200376 inst = inst->Next_1xx();
377 break;
378 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700379 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200380 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200381 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700382 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700383 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700384 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
385 !SendMethodExitEvents(self,
386 instrumentation,
387 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800388 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700389 shadow_frame.GetMethod(),
390 inst->GetDexPc(insns),
391 result))) {
392 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200393 }
buzbee1452bee2015-03-06 14:43:04 -0800394 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700395 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700396 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800397 }
David Srbecky946bb092018-03-09 17:23:01 +0000398 ctx->result = result;
399 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200400 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700401 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200402 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700403 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200404 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700405 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700406 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700407 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
408 !SendMethodExitEvents(self,
409 instrumentation,
410 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800411 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700412 shadow_frame.GetMethod(),
413 inst->GetDexPc(insns),
414 result))) {
415 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200416 }
buzbee1452bee2015-03-06 14:43:04 -0800417 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700418 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700419 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800420 }
David Srbecky946bb092018-03-09 17:23:01 +0000421 ctx->result = result;
422 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200423 }
424 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200425 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200426 JValue result;
427 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200428 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700429 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700430 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700431 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
432 !SendMethodExitEvents(self,
433 instrumentation,
434 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800435 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700436 shadow_frame.GetMethod(),
437 inst->GetDexPc(insns),
438 result))) {
439 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200440 }
buzbee1452bee2015-03-06 14:43:04 -0800441 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700442 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700443 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800444 }
David Srbecky946bb092018-03-09 17:23:01 +0000445 ctx->result = result;
446 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200447 }
448 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200449 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200450 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200451 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700452 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700453 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700454 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
455 !SendMethodExitEvents(self,
456 instrumentation,
457 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800458 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700459 shadow_frame.GetMethod(),
460 inst->GetDexPc(insns),
461 result))) {
462 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200463 }
buzbee1452bee2015-03-06 14:43:04 -0800464 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700465 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700466 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800467 }
David Srbecky946bb092018-03-09 17:23:01 +0000468 ctx->result = result;
469 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200470 }
471 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200472 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200473 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700474 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700475 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700476 const size_t ref_idx = inst->VRegA_11x(inst_data);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700477 ObjPtr<mirror::Object> obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700478 if (do_assignability_check && obj_result != nullptr) {
Alex Lightcc917d92018-02-22 13:28:28 -0800479 ObjPtr<mirror::Class> return_type = shadow_frame.GetMethod()->ResolveReturnType();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700480 // Re-load since it might have moved.
481 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700482 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700483 // Return the pending exception.
484 HANDLE_PENDING_EXCEPTION();
485 }
486 if (!obj_result->VerifierInstanceOf(return_type)) {
487 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700488 std::string temp1, temp2;
Orion Hodsonfef06642016-11-25 16:07:11 +0000489 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700490 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700491 obj_result->GetClass()->GetDescriptor(&temp1),
492 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700493 HANDLE_PENDING_EXCEPTION();
494 }
495 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700496 result.SetL(obj_result);
Alex Lighte814f9d2017-07-31 16:14:39 -0700497 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
498 !SendMethodExitEvents(self,
499 instrumentation,
500 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800501 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700502 shadow_frame.GetMethod(),
503 inst->GetDexPc(insns),
504 result))) {
505 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200506 }
Alex Lighte814f9d2017-07-31 16:14:39 -0700507 // Re-load since it might have moved during the MethodExitEvent.
508 result.SetL(shadow_frame.GetVRegReference(ref_idx));
buzbee1452bee2015-03-06 14:43:04 -0800509 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700510 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700511 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800512 }
David Srbecky946bb092018-03-09 17:23:01 +0000513 ctx->result = result;
514 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200515 }
516 case Instruction::CONST_4: {
517 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200518 uint4_t dst = inst->VRegA_11n(inst_data);
519 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200520 shadow_frame.SetVReg(dst, val);
521 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700522 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200523 }
524 inst = inst->Next_1xx();
525 break;
526 }
527 case Instruction::CONST_16: {
528 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200529 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200530 int16_t val = inst->VRegB_21s();
531 shadow_frame.SetVReg(dst, val);
532 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700533 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200534 }
535 inst = inst->Next_2xx();
536 break;
537 }
538 case Instruction::CONST: {
539 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200540 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200541 int32_t val = inst->VRegB_31i();
542 shadow_frame.SetVReg(dst, val);
543 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700544 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200545 }
546 inst = inst->Next_3xx();
547 break;
548 }
549 case Instruction::CONST_HIGH16: {
550 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200551 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200552 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
553 shadow_frame.SetVReg(dst, val);
554 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700555 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200556 }
557 inst = inst->Next_2xx();
558 break;
559 }
560 case Instruction::CONST_WIDE_16:
561 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200562 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200563 inst = inst->Next_2xx();
564 break;
565 case Instruction::CONST_WIDE_32:
566 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200567 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200568 inst = inst->Next_3xx();
569 break;
570 case Instruction::CONST_WIDE:
571 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200572 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200573 inst = inst->Next_51l();
574 break;
575 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200576 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200577 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200578 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
579 inst = inst->Next_2xx();
580 break;
581 case Instruction::CONST_STRING: {
582 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800583 ObjPtr<mirror::String> s = ResolveString(self,
584 shadow_frame,
585 dex::StringIndex(inst->VRegB_21c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700586 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200587 HANDLE_PENDING_EXCEPTION();
588 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100589 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200590 inst = inst->Next_2xx();
591 }
592 break;
593 }
594 case Instruction::CONST_STRING_JUMBO: {
595 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800596 ObjPtr<mirror::String> s = ResolveString(self,
597 shadow_frame,
598 dex::StringIndex(inst->VRegB_31c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700599 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200600 HANDLE_PENDING_EXCEPTION();
601 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100602 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200603 inst = inst->Next_3xx();
604 }
605 break;
606 }
607 case Instruction::CONST_CLASS: {
608 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800609 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700610 shadow_frame.GetMethod(),
611 self,
612 false,
613 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700614 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200615 HANDLE_PENDING_EXCEPTION();
616 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100617 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200618 inst = inst->Next_2xx();
619 }
620 break;
621 }
Orion Hodson2e599942017-09-22 16:17:41 +0100622 case Instruction::CONST_METHOD_HANDLE: {
623 PREAMBLE();
Orion Hodsone7732be2017-10-11 14:35:20 +0100624 ClassLinker* cl = Runtime::Current()->GetClassLinker();
Alex Lightcc917d92018-02-22 13:28:28 -0800625 ObjPtr<mirror::MethodHandle> mh = cl->ResolveMethodHandle(self,
626 inst->VRegB_21c(),
627 shadow_frame.GetMethod());
Orion Hodson2e599942017-09-22 16:17:41 +0100628 if (UNLIKELY(mh == nullptr)) {
629 HANDLE_PENDING_EXCEPTION();
630 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100631 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mh);
Orion Hodson2e599942017-09-22 16:17:41 +0100632 inst = inst->Next_2xx();
633 }
634 break;
635 }
636 case Instruction::CONST_METHOD_TYPE: {
637 PREAMBLE();
Orion Hodsone7732be2017-10-11 14:35:20 +0100638 ClassLinker* cl = Runtime::Current()->GetClassLinker();
Alex Lightcc917d92018-02-22 13:28:28 -0800639 ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(self,
Orion Hodson06d10a72018-05-14 08:53:38 +0100640 dex::ProtoIndex(inst->VRegB_21c()),
Alex Lightcc917d92018-02-22 13:28:28 -0800641 shadow_frame.GetMethod());
Orion Hodson2e599942017-09-22 16:17:41 +0100642 if (UNLIKELY(mt == nullptr)) {
643 HANDLE_PENDING_EXCEPTION();
644 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100645 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mt);
Orion Hodson2e599942017-09-22 16:17:41 +0100646 inst = inst->Next_2xx();
647 }
648 break;
649 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200650 case Instruction::MONITOR_ENTER: {
651 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700652 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700653 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700654 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000655 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200656 HANDLE_PENDING_EXCEPTION();
657 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700658 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200659 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
660 }
661 break;
662 }
663 case Instruction::MONITOR_EXIT: {
664 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700665 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700666 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700667 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000668 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200669 HANDLE_PENDING_EXCEPTION();
670 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700671 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200672 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
673 }
674 break;
675 }
676 case Instruction::CHECK_CAST: {
677 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800678 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700679 shadow_frame.GetMethod(),
680 self,
681 false,
682 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700683 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200684 HANDLE_PENDING_EXCEPTION();
685 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700686 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700687 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200688 ThrowClassCastException(c, obj->GetClass());
689 HANDLE_PENDING_EXCEPTION();
690 } else {
691 inst = inst->Next_2xx();
692 }
693 }
694 break;
695 }
696 case Instruction::INSTANCE_OF: {
697 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800698 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegC_22c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700699 shadow_frame.GetMethod(),
700 self,
701 false,
702 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700703 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200704 HANDLE_PENDING_EXCEPTION();
705 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700706 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700707 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
708 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200709 inst = inst->Next_2xx();
710 }
711 break;
712 }
713 case Instruction::ARRAY_LENGTH: {
714 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700715 ObjPtr<mirror::Object> array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700716 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000717 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200718 HANDLE_PENDING_EXCEPTION();
719 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200720 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200721 inst = inst->Next_1xx();
722 }
723 break;
724 }
725 case Instruction::NEW_INSTANCE: {
726 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700727 ObjPtr<mirror::Object> obj = nullptr;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800728 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700729 shadow_frame.GetMethod(),
730 self,
731 false,
732 do_access_check);
Jeff Hao848f70a2014-01-15 13:49:50 -0800733 if (LIKELY(c != nullptr)) {
734 if (UNLIKELY(c->IsStringClass())) {
735 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700736 obj = mirror::String::AllocEmptyString<true>(self, allocator_type);
Jeff Hao848f70a2014-01-15 13:49:50 -0800737 } else {
Nicolas Geoffray0d3998b2017-01-12 15:35:12 +0000738 obj = AllocObjectFromCode<true>(
739 c.Ptr(),
Andreas Gampea5b09a62016-11-17 15:21:22 -0800740 self,
741 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Jeff Hao848f70a2014-01-15 13:49:50 -0800742 }
743 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700744 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200745 HANDLE_PENDING_EXCEPTION();
746 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200747 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700748 // Don't allow finalizable objects to be allocated during a transaction since these can't
749 // be finalized without a started runtime.
750 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200751 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
David Sehr709b0702016-10-13 09:12:37 -0700752 obj->PrettyTypeOf().c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700753 HANDLE_PENDING_EXCEPTION();
754 break;
755 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100756 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200757 inst = inst->Next_2xx();
758 }
759 break;
760 }
761 case Instruction::NEW_ARRAY: {
762 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200763 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartieref41db72016-10-25 15:08:01 -0700764 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800765 dex::TypeIndex(inst->VRegC_22c()),
766 length,
767 shadow_frame.GetMethod(),
768 self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800769 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700770 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200771 HANDLE_PENDING_EXCEPTION();
772 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100773 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200774 inst = inst->Next_2xx();
775 }
776 break;
777 }
778 case Instruction::FILLED_NEW_ARRAY: {
779 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100780 bool success =
781 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
782 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200783 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
784 break;
785 }
786 case Instruction::FILLED_NEW_ARRAY_RANGE: {
787 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100788 bool success =
789 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
790 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200791 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
792 break;
793 }
794 case Instruction::FILL_ARRAY_DATA: {
795 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200796 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
797 const Instruction::ArrayDataPayload* payload =
798 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700799 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700800 bool success = FillArrayData(obj, payload);
801 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200802 HANDLE_PENDING_EXCEPTION();
803 break;
804 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100805 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700806 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100807 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200808 inst = inst->Next_3xx();
809 break;
810 }
811 case Instruction::THROW: {
812 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700813 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700814 ObjPtr<mirror::Object> exception =
815 shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700816 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000817 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700818 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
819 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700820 std::string temp;
Orion Hodsonfef06642016-11-25 16:07:11 +0000821 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700822 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700823 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200824 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000825 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200826 }
827 HANDLE_PENDING_EXCEPTION();
828 break;
829 }
830 case Instruction::GOTO: {
831 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700832 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200833 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000834 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200835 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800836 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200837 break;
838 }
839 case Instruction::GOTO_16: {
840 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700841 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200842 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000843 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200844 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800845 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200846 break;
847 }
848 case Instruction::GOTO_32: {
849 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700850 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200851 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000852 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200853 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800854 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200855 break;
856 }
857 case Instruction::PACKED_SWITCH: {
858 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200859 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000860 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200861 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800862 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200863 break;
864 }
865 case Instruction::SPARSE_SWITCH: {
866 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200867 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000868 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200869 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800870 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200871 break;
872 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700873
Ian Rogers647b1a82014-10-10 11:02:11 -0700874#pragma clang diagnostic push
875#pragma clang diagnostic ignored "-Wfloat-equal"
Ian Rogers647b1a82014-10-10 11:02:11 -0700876
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200877 case Instruction::CMPL_FLOAT: {
878 PREAMBLE();
879 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
880 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
881 int32_t result;
882 if (val1 > val2) {
883 result = 1;
884 } else if (val1 == val2) {
885 result = 0;
886 } else {
887 result = -1;
888 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200889 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200890 inst = inst->Next_2xx();
891 break;
892 }
893 case Instruction::CMPG_FLOAT: {
894 PREAMBLE();
895 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
896 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
897 int32_t result;
898 if (val1 < val2) {
899 result = -1;
900 } else if (val1 == val2) {
901 result = 0;
902 } else {
903 result = 1;
904 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200905 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200906 inst = inst->Next_2xx();
907 break;
908 }
909 case Instruction::CMPL_DOUBLE: {
910 PREAMBLE();
911 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
912 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
913 int32_t result;
914 if (val1 > val2) {
915 result = 1;
916 } else if (val1 == val2) {
917 result = 0;
918 } else {
919 result = -1;
920 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200921 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200922 inst = inst->Next_2xx();
923 break;
924 }
925
926 case Instruction::CMPG_DOUBLE: {
927 PREAMBLE();
928 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
929 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
930 int32_t result;
931 if (val1 < val2) {
932 result = -1;
933 } else if (val1 == val2) {
934 result = 0;
935 } else {
936 result = 1;
937 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200938 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200939 inst = inst->Next_2xx();
940 break;
941 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700942
Ian Rogers647b1a82014-10-10 11:02:11 -0700943#pragma clang diagnostic pop
Ian Rogers647b1a82014-10-10 11:02:11 -0700944
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200945 case Instruction::CMP_LONG: {
946 PREAMBLE();
947 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
948 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
949 int32_t result;
950 if (val1 > val2) {
951 result = 1;
952 } else if (val1 == val2) {
953 result = 0;
954 } else {
955 result = -1;
956 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200957 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200958 inst = inst->Next_2xx();
959 break;
960 }
961 case Instruction::IF_EQ: {
962 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700963 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
964 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200965 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000966 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200967 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800968 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200969 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800970 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200971 inst = inst->Next_2xx();
972 }
973 break;
974 }
975 case Instruction::IF_NE: {
976 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700977 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
978 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200979 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000980 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200981 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800982 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200983 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800984 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200985 inst = inst->Next_2xx();
986 }
987 break;
988 }
989 case Instruction::IF_LT: {
990 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700991 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
992 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200993 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000994 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200995 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800996 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200997 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800998 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200999 inst = inst->Next_2xx();
1000 }
1001 break;
1002 }
1003 case Instruction::IF_GE: {
1004 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001005 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
1006 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001007 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001008 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001009 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001010 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001011 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001012 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001013 inst = inst->Next_2xx();
1014 }
1015 break;
1016 }
1017 case Instruction::IF_GT: {
1018 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001019 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
1020 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001021 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001022 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001023 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001024 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001025 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001026 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001027 inst = inst->Next_2xx();
1028 }
1029 break;
1030 }
1031 case Instruction::IF_LE: {
1032 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001033 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
1034 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001035 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001036 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001037 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001038 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001039 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001040 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001041 inst = inst->Next_2xx();
1042 }
1043 break;
1044 }
1045 case Instruction::IF_EQZ: {
1046 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001047 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001048 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001049 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001050 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001051 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001052 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001053 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001054 inst = inst->Next_2xx();
1055 }
1056 break;
1057 }
1058 case Instruction::IF_NEZ: {
1059 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001060 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001061 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001062 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001063 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001064 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001065 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001066 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001067 inst = inst->Next_2xx();
1068 }
1069 break;
1070 }
1071 case Instruction::IF_LTZ: {
1072 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001073 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001074 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001075 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001076 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001077 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001078 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001079 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001080 inst = inst->Next_2xx();
1081 }
1082 break;
1083 }
1084 case Instruction::IF_GEZ: {
1085 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001086 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001087 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001088 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001089 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001090 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001091 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001092 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001093 inst = inst->Next_2xx();
1094 }
1095 break;
1096 }
1097 case Instruction::IF_GTZ: {
1098 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001099 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001100 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001101 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001102 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001103 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001104 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001105 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001106 inst = inst->Next_2xx();
1107 }
1108 break;
1109 }
1110 case Instruction::IF_LEZ: {
1111 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001112 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001113 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001114 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001115 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001116 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001117 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001118 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001119 inst = inst->Next_2xx();
1120 }
1121 break;
1122 }
1123 case Instruction::AGET_BOOLEAN: {
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());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001132 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001133 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001134 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001135 inst = inst->Next_2xx();
1136 } else {
1137 HANDLE_PENDING_EXCEPTION();
1138 }
1139 break;
1140 }
1141 case Instruction::AGET_BYTE: {
1142 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001143 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001144 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001145 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001146 HANDLE_PENDING_EXCEPTION();
1147 break;
1148 }
1149 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001150 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001151 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001152 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001153 inst = inst->Next_2xx();
1154 } else {
1155 HANDLE_PENDING_EXCEPTION();
1156 }
1157 break;
1158 }
1159 case Instruction::AGET_CHAR: {
1160 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001161 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001162 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001163 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001164 HANDLE_PENDING_EXCEPTION();
1165 break;
1166 }
1167 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001168 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001169 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001170 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001171 inst = inst->Next_2xx();
1172 } else {
1173 HANDLE_PENDING_EXCEPTION();
1174 }
1175 break;
1176 }
1177 case Instruction::AGET_SHORT: {
1178 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001179 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001180 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001181 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001182 HANDLE_PENDING_EXCEPTION();
1183 break;
1184 }
1185 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001186 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001187 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001188 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001189 inst = inst->Next_2xx();
1190 } else {
1191 HANDLE_PENDING_EXCEPTION();
1192 }
1193 break;
1194 }
1195 case Instruction::AGET: {
1196 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001197 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001198 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001199 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001200 HANDLE_PENDING_EXCEPTION();
1201 break;
1202 }
1203 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001204 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001205 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001206 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001207 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001208 inst = inst->Next_2xx();
1209 } else {
1210 HANDLE_PENDING_EXCEPTION();
1211 }
1212 break;
1213 }
1214 case Instruction::AGET_WIDE: {
1215 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001216 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001217 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001218 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001219 HANDLE_PENDING_EXCEPTION();
1220 break;
1221 }
1222 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001223 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001224 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001225 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001226 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001227 inst = inst->Next_2xx();
1228 } else {
1229 HANDLE_PENDING_EXCEPTION();
1230 }
1231 break;
1232 }
1233 case Instruction::AGET_OBJECT: {
1234 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001235 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001236 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001237 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001238 HANDLE_PENDING_EXCEPTION();
1239 break;
1240 }
1241 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001242 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001243 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001244 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001245 inst = inst->Next_2xx();
1246 } else {
1247 HANDLE_PENDING_EXCEPTION();
1248 }
1249 break;
1250 }
1251 case Instruction::APUT_BOOLEAN: {
1252 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001253 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001254 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001255 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001256 HANDLE_PENDING_EXCEPTION();
1257 break;
1258 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001259 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001260 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001261 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001262 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001263 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001264 inst = inst->Next_2xx();
1265 } else {
1266 HANDLE_PENDING_EXCEPTION();
1267 }
1268 break;
1269 }
1270 case Instruction::APUT_BYTE: {
1271 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001272 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001273 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001274 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001275 HANDLE_PENDING_EXCEPTION();
1276 break;
1277 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001278 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001279 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001280 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001281 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001282 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001283 inst = inst->Next_2xx();
1284 } else {
1285 HANDLE_PENDING_EXCEPTION();
1286 }
1287 break;
1288 }
1289 case Instruction::APUT_CHAR: {
1290 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001291 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001292 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001293 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001294 HANDLE_PENDING_EXCEPTION();
1295 break;
1296 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001297 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001298 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001299 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001300 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001301 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001302 inst = inst->Next_2xx();
1303 } else {
1304 HANDLE_PENDING_EXCEPTION();
1305 }
1306 break;
1307 }
1308 case Instruction::APUT_SHORT: {
1309 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001310 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001311 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001312 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001313 HANDLE_PENDING_EXCEPTION();
1314 break;
1315 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001316 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001317 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001318 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001319 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001320 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001321 inst = inst->Next_2xx();
1322 } else {
1323 HANDLE_PENDING_EXCEPTION();
1324 }
1325 break;
1326 }
1327 case Instruction::APUT: {
1328 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001329 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001330 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001331 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001332 HANDLE_PENDING_EXCEPTION();
1333 break;
1334 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001335 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001336 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001337 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001338 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001339 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001340 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001341 inst = inst->Next_2xx();
1342 } else {
1343 HANDLE_PENDING_EXCEPTION();
1344 }
1345 break;
1346 }
1347 case Instruction::APUT_WIDE: {
1348 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001349 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001350 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001351 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001352 HANDLE_PENDING_EXCEPTION();
1353 break;
1354 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001355 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001356 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001357 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001358 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001359 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001360 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001361 inst = inst->Next_2xx();
1362 } else {
1363 HANDLE_PENDING_EXCEPTION();
1364 }
1365 break;
1366 }
1367 case Instruction::APUT_OBJECT: {
1368 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001369 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001370 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001371 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001372 HANDLE_PENDING_EXCEPTION();
1373 break;
1374 }
1375 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001376 ObjPtr<mirror::Object> val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
1377 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001378 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001379 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001380 inst = inst->Next_2xx();
1381 } else {
1382 HANDLE_PENDING_EXCEPTION();
1383 }
1384 break;
1385 }
1386 case Instruction::IGET_BOOLEAN: {
1387 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001388 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1389 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::IGET_BYTE: {
1394 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001395 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1396 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::IGET_CHAR: {
1401 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001402 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1403 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::IGET_SHORT: {
1408 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001409 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1410 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::IGET: {
1415 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001416 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1417 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::IGET_WIDE: {
1422 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001423 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1424 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::IGET_OBJECT: {
1429 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001430 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1431 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::IGET_QUICK: {
1436 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001437 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001438 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1439 break;
1440 }
1441 case Instruction::IGET_WIDE_QUICK: {
1442 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001443 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001444 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1445 break;
1446 }
1447 case Instruction::IGET_OBJECT_QUICK: {
1448 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001449 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001450 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1451 break;
1452 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001453 case Instruction::IGET_BOOLEAN_QUICK: {
1454 PREAMBLE();
1455 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1456 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1457 break;
1458 }
1459 case Instruction::IGET_BYTE_QUICK: {
1460 PREAMBLE();
1461 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1462 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1463 break;
1464 }
1465 case Instruction::IGET_CHAR_QUICK: {
1466 PREAMBLE();
1467 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1468 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1469 break;
1470 }
1471 case Instruction::IGET_SHORT_QUICK: {
1472 PREAMBLE();
1473 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1474 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1475 break;
1476 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001477 case Instruction::SGET_BOOLEAN: {
1478 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001479 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, 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::SGET_BYTE: {
1485 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001486 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check,
1487 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001488 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1489 break;
1490 }
1491 case Instruction::SGET_CHAR: {
1492 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001493 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check,
1494 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001495 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1496 break;
1497 }
1498 case Instruction::SGET_SHORT: {
1499 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001500 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check,
1501 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001502 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1503 break;
1504 }
1505 case Instruction::SGET: {
1506 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001507 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check,
1508 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001509 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1510 break;
1511 }
1512 case Instruction::SGET_WIDE: {
1513 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001514 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check,
1515 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001516 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1517 break;
1518 }
1519 case Instruction::SGET_OBJECT: {
1520 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001521 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check,
1522 transaction_active>(self, 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_BOOLEAN: {
1527 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001528 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1529 transaction_active>(self, 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::IPUT_BYTE: {
1534 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001535 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, 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::IPUT_CHAR: {
1541 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001542 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, 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::IPUT_SHORT: {
1548 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001549 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, 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::IPUT: {
1555 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001556 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, 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::IPUT_WIDE: {
1562 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001563 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, 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::IPUT_OBJECT: {
1569 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001570 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, 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::IPUT_QUICK: {
1576 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001577 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1578 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001579 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1580 break;
1581 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001582 case Instruction::IPUT_BOOLEAN_QUICK: {
1583 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001584 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1585 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001586 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1587 break;
1588 }
1589 case Instruction::IPUT_BYTE_QUICK: {
1590 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001591 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1592 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001593 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1594 break;
1595 }
1596 case Instruction::IPUT_CHAR_QUICK: {
1597 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001598 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1599 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001600 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1601 break;
1602 }
1603 case Instruction::IPUT_SHORT_QUICK: {
1604 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001605 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1606 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001607 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1608 break;
1609 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001610 case Instruction::IPUT_WIDE_QUICK: {
1611 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001612 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1613 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001614 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1615 break;
1616 }
1617 case Instruction::IPUT_OBJECT_QUICK: {
1618 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001619 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1620 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001621 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1622 break;
1623 }
1624 case Instruction::SPUT_BOOLEAN: {
1625 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001626 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1627 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001628 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1629 break;
1630 }
1631 case Instruction::SPUT_BYTE: {
1632 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001633 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1634 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001635 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1636 break;
1637 }
1638 case Instruction::SPUT_CHAR: {
1639 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001640 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1641 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001642 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1643 break;
1644 }
1645 case Instruction::SPUT_SHORT: {
1646 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001647 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1648 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001649 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1650 break;
1651 }
1652 case Instruction::SPUT: {
1653 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001654 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1655 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001656 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1657 break;
1658 }
1659 case Instruction::SPUT_WIDE: {
1660 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001661 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1662 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001663 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1664 break;
1665 }
1666 case Instruction::SPUT_OBJECT: {
1667 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001668 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1669 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001670 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1671 break;
1672 }
1673 case Instruction::INVOKE_VIRTUAL: {
1674 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001675 bool success = DoInvoke<kVirtual, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001676 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001677 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001678 break;
1679 }
1680 case Instruction::INVOKE_VIRTUAL_RANGE: {
1681 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001682 bool success = DoInvoke<kVirtual, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001683 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001684 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001685 break;
1686 }
1687 case Instruction::INVOKE_SUPER: {
1688 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001689 bool success = DoInvoke<kSuper, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001690 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001691 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001692 break;
1693 }
1694 case Instruction::INVOKE_SUPER_RANGE: {
1695 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001696 bool success = DoInvoke<kSuper, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001697 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001698 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001699 break;
1700 }
1701 case Instruction::INVOKE_DIRECT: {
1702 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001703 bool success = DoInvoke<kDirect, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001704 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001705 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001706 break;
1707 }
1708 case Instruction::INVOKE_DIRECT_RANGE: {
1709 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001710 bool success = DoInvoke<kDirect, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001711 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001712 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001713 break;
1714 }
1715 case Instruction::INVOKE_INTERFACE: {
1716 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001717 bool success = DoInvoke<kInterface, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001718 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001719 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001720 break;
1721 }
1722 case Instruction::INVOKE_INTERFACE_RANGE: {
1723 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001724 bool success = DoInvoke<kInterface, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001725 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001726 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001727 break;
1728 }
1729 case Instruction::INVOKE_STATIC: {
1730 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001731 bool success = DoInvoke<kStatic, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001732 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001733 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001734 break;
1735 }
1736 case Instruction::INVOKE_STATIC_RANGE: {
1737 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001738 bool success = DoInvoke<kStatic, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001739 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001740 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001741 break;
1742 }
1743 case Instruction::INVOKE_VIRTUAL_QUICK: {
1744 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001745 bool success = DoInvokeVirtualQuick<false>(
1746 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001747 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001748 break;
1749 }
1750 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1751 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001752 bool success = DoInvokeVirtualQuick<true>(
1753 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001754 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001755 break;
1756 }
Narayan Kamath9823e782016-08-03 12:46:58 +01001757 case Instruction::INVOKE_POLYMORPHIC: {
1758 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001759 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001760 bool success = DoInvokePolymorphic</* is_range= */ false>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001761 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001762 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
Narayan Kamath9823e782016-08-03 12:46:58 +01001763 break;
1764 }
1765 case Instruction::INVOKE_POLYMORPHIC_RANGE: {
1766 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001767 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001768 bool success = DoInvokePolymorphic</* is_range= */ true>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001769 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001770 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
Narayan Kamath9823e782016-08-03 12:46:58 +01001771 break;
Narayan Kamath9823e782016-08-03 12:46:58 +01001772 }
Orion Hodsonc069a302017-01-18 09:23:12 +00001773 case Instruction::INVOKE_CUSTOM: {
1774 PREAMBLE();
1775 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001776 bool success = DoInvokeCustom</* is_range= */ false>(
Orion Hodsonc069a302017-01-18 09:23:12 +00001777 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001778 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Orion Hodsonc069a302017-01-18 09:23:12 +00001779 break;
1780 }
1781 case Instruction::INVOKE_CUSTOM_RANGE: {
1782 PREAMBLE();
1783 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001784 bool success = DoInvokeCustom</* is_range= */ true>(
Orion Hodsonc069a302017-01-18 09:23:12 +00001785 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001786 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Orion Hodsonc069a302017-01-18 09:23:12 +00001787 break;
1788 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001789 case Instruction::NEG_INT:
1790 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001791 shadow_frame.SetVReg(
1792 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001793 inst = inst->Next_1xx();
1794 break;
1795 case Instruction::NOT_INT:
1796 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001797 shadow_frame.SetVReg(
1798 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001799 inst = inst->Next_1xx();
1800 break;
1801 case Instruction::NEG_LONG:
1802 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001803 shadow_frame.SetVRegLong(
1804 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001805 inst = inst->Next_1xx();
1806 break;
1807 case Instruction::NOT_LONG:
1808 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001809 shadow_frame.SetVRegLong(
1810 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001811 inst = inst->Next_1xx();
1812 break;
1813 case Instruction::NEG_FLOAT:
1814 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001815 shadow_frame.SetVRegFloat(
1816 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001817 inst = inst->Next_1xx();
1818 break;
1819 case Instruction::NEG_DOUBLE:
1820 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001821 shadow_frame.SetVRegDouble(
1822 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001823 inst = inst->Next_1xx();
1824 break;
1825 case Instruction::INT_TO_LONG:
1826 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001827 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1828 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001829 inst = inst->Next_1xx();
1830 break;
1831 case Instruction::INT_TO_FLOAT:
1832 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001833 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1834 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001835 inst = inst->Next_1xx();
1836 break;
1837 case Instruction::INT_TO_DOUBLE:
1838 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001839 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1840 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001841 inst = inst->Next_1xx();
1842 break;
1843 case Instruction::LONG_TO_INT:
1844 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001845 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1846 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001847 inst = inst->Next_1xx();
1848 break;
1849 case Instruction::LONG_TO_FLOAT:
1850 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001851 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1852 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001853 inst = inst->Next_1xx();
1854 break;
1855 case Instruction::LONG_TO_DOUBLE:
1856 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001857 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1858 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001859 inst = inst->Next_1xx();
1860 break;
1861 case Instruction::FLOAT_TO_INT: {
1862 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001863 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001864 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001865 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001866 inst = inst->Next_1xx();
1867 break;
1868 }
1869 case Instruction::FLOAT_TO_LONG: {
1870 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001871 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001872 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001873 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001874 inst = inst->Next_1xx();
1875 break;
1876 }
1877 case Instruction::FLOAT_TO_DOUBLE:
1878 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001879 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1880 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001881 inst = inst->Next_1xx();
1882 break;
1883 case Instruction::DOUBLE_TO_INT: {
1884 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001885 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001886 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001887 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001888 inst = inst->Next_1xx();
1889 break;
1890 }
1891 case Instruction::DOUBLE_TO_LONG: {
1892 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001893 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001894 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001895 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001896 inst = inst->Next_1xx();
1897 break;
1898 }
1899 case Instruction::DOUBLE_TO_FLOAT:
1900 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001901 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1902 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001903 inst = inst->Next_1xx();
1904 break;
1905 case Instruction::INT_TO_BYTE:
1906 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001907 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1908 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001909 inst = inst->Next_1xx();
1910 break;
1911 case Instruction::INT_TO_CHAR:
1912 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001913 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1914 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001915 inst = inst->Next_1xx();
1916 break;
1917 case Instruction::INT_TO_SHORT:
1918 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001919 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1920 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001921 inst = inst->Next_1xx();
1922 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001923 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001924 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001925 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001926 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1927 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001928 inst = inst->Next_2xx();
1929 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001930 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001931 case Instruction::SUB_INT:
1932 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001933 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001934 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1935 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001936 inst = inst->Next_2xx();
1937 break;
1938 case Instruction::MUL_INT:
1939 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001940 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001941 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1942 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001943 inst = inst->Next_2xx();
1944 break;
1945 case Instruction::DIV_INT: {
1946 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001947 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001948 shadow_frame.GetVReg(inst->VRegB_23x()),
1949 shadow_frame.GetVReg(inst->VRegC_23x()));
1950 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1951 break;
1952 }
1953 case Instruction::REM_INT: {
1954 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001955 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001956 shadow_frame.GetVReg(inst->VRegB_23x()),
1957 shadow_frame.GetVReg(inst->VRegC_23x()));
1958 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1959 break;
1960 }
1961 case Instruction::SHL_INT:
1962 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001963 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001964 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1965 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1966 inst = inst->Next_2xx();
1967 break;
1968 case Instruction::SHR_INT:
1969 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001970 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001971 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1972 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1973 inst = inst->Next_2xx();
1974 break;
1975 case Instruction::USHR_INT:
1976 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001977 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001978 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1979 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1980 inst = inst->Next_2xx();
1981 break;
1982 case Instruction::AND_INT:
1983 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001984 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001985 shadow_frame.GetVReg(inst->VRegB_23x()) &
1986 shadow_frame.GetVReg(inst->VRegC_23x()));
1987 inst = inst->Next_2xx();
1988 break;
1989 case Instruction::OR_INT:
1990 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001991 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001992 shadow_frame.GetVReg(inst->VRegB_23x()) |
1993 shadow_frame.GetVReg(inst->VRegC_23x()));
1994 inst = inst->Next_2xx();
1995 break;
1996 case Instruction::XOR_INT:
1997 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001998 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001999 shadow_frame.GetVReg(inst->VRegB_23x()) ^
2000 shadow_frame.GetVReg(inst->VRegC_23x()));
2001 inst = inst->Next_2xx();
2002 break;
2003 case Instruction::ADD_LONG:
2004 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002005 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002006 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
2007 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002008 inst = inst->Next_2xx();
2009 break;
2010 case Instruction::SUB_LONG:
2011 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002012 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002013 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
2014 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002015 inst = inst->Next_2xx();
2016 break;
2017 case Instruction::MUL_LONG:
2018 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002019 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002020 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
2021 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002022 inst = inst->Next_2xx();
2023 break;
2024 case Instruction::DIV_LONG:
2025 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002026 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002027 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002028 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002029 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
2030 break;
2031 case Instruction::REM_LONG:
2032 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002033 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002034 shadow_frame.GetVRegLong(inst->VRegB_23x()),
2035 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2036 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
2037 break;
2038 case Instruction::AND_LONG:
2039 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002040 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002041 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
2042 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2043 inst = inst->Next_2xx();
2044 break;
2045 case Instruction::OR_LONG:
2046 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002047 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002048 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
2049 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2050 inst = inst->Next_2xx();
2051 break;
2052 case Instruction::XOR_LONG:
2053 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002054 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002055 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
2056 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2057 inst = inst->Next_2xx();
2058 break;
2059 case Instruction::SHL_LONG:
2060 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002061 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002062 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
2063 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2064 inst = inst->Next_2xx();
2065 break;
2066 case Instruction::SHR_LONG:
2067 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002068 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002069 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
2070 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2071 inst = inst->Next_2xx();
2072 break;
2073 case Instruction::USHR_LONG:
2074 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002075 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002076 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
2077 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2078 inst = inst->Next_2xx();
2079 break;
2080 case Instruction::ADD_FLOAT:
2081 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002082 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002083 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
2084 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2085 inst = inst->Next_2xx();
2086 break;
2087 case Instruction::SUB_FLOAT:
2088 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002089 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002090 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
2091 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2092 inst = inst->Next_2xx();
2093 break;
2094 case Instruction::MUL_FLOAT:
2095 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002096 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002097 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
2098 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2099 inst = inst->Next_2xx();
2100 break;
2101 case Instruction::DIV_FLOAT:
2102 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002103 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002104 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
2105 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2106 inst = inst->Next_2xx();
2107 break;
2108 case Instruction::REM_FLOAT:
2109 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002110 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002111 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
2112 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
2113 inst = inst->Next_2xx();
2114 break;
2115 case Instruction::ADD_DOUBLE:
2116 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002117 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002118 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
2119 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2120 inst = inst->Next_2xx();
2121 break;
2122 case Instruction::SUB_DOUBLE:
2123 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002124 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002125 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
2126 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2127 inst = inst->Next_2xx();
2128 break;
2129 case Instruction::MUL_DOUBLE:
2130 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002131 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002132 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
2133 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2134 inst = inst->Next_2xx();
2135 break;
2136 case Instruction::DIV_DOUBLE:
2137 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002138 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002139 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2140 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2141 inst = inst->Next_2xx();
2142 break;
2143 case Instruction::REM_DOUBLE:
2144 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002145 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002146 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2147 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2148 inst = inst->Next_2xx();
2149 break;
2150 case Instruction::ADD_INT_2ADDR: {
2151 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002152 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07002153 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
2154 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002155 inst = inst->Next_1xx();
2156 break;
2157 }
2158 case Instruction::SUB_INT_2ADDR: {
2159 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002160 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002161 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002162 SafeSub(shadow_frame.GetVReg(vregA),
2163 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002164 inst = inst->Next_1xx();
2165 break;
2166 }
2167 case Instruction::MUL_INT_2ADDR: {
2168 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002169 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002170 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002171 SafeMul(shadow_frame.GetVReg(vregA),
2172 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002173 inst = inst->Next_1xx();
2174 break;
2175 }
2176 case Instruction::DIV_INT_2ADDR: {
2177 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002178 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002179 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002180 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002181 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2182 break;
2183 }
2184 case Instruction::REM_INT_2ADDR: {
2185 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002186 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002187 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002188 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002189 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2190 break;
2191 }
2192 case Instruction::SHL_INT_2ADDR: {
2193 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002194 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002195 shadow_frame.SetVReg(vregA,
2196 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002197 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002198 inst = inst->Next_1xx();
2199 break;
2200 }
2201 case Instruction::SHR_INT_2ADDR: {
2202 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002203 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002204 shadow_frame.SetVReg(vregA,
2205 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002206 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002207 inst = inst->Next_1xx();
2208 break;
2209 }
2210 case Instruction::USHR_INT_2ADDR: {
2211 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002212 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002213 shadow_frame.SetVReg(vregA,
2214 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002215 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002216 inst = inst->Next_1xx();
2217 break;
2218 }
2219 case Instruction::AND_INT_2ADDR: {
2220 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002221 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002222 shadow_frame.SetVReg(vregA,
2223 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002224 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002225 inst = inst->Next_1xx();
2226 break;
2227 }
2228 case Instruction::OR_INT_2ADDR: {
2229 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002230 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002231 shadow_frame.SetVReg(vregA,
2232 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002233 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002234 inst = inst->Next_1xx();
2235 break;
2236 }
2237 case Instruction::XOR_INT_2ADDR: {
2238 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002239 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002240 shadow_frame.SetVReg(vregA,
2241 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002242 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002243 inst = inst->Next_1xx();
2244 break;
2245 }
2246 case Instruction::ADD_LONG_2ADDR: {
2247 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002248 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002249 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002250 SafeAdd(shadow_frame.GetVRegLong(vregA),
2251 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002252 inst = inst->Next_1xx();
2253 break;
2254 }
2255 case Instruction::SUB_LONG_2ADDR: {
2256 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002257 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002258 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002259 SafeSub(shadow_frame.GetVRegLong(vregA),
2260 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002261 inst = inst->Next_1xx();
2262 break;
2263 }
2264 case Instruction::MUL_LONG_2ADDR: {
2265 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002266 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002267 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002268 SafeMul(shadow_frame.GetVRegLong(vregA),
2269 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002270 inst = inst->Next_1xx();
2271 break;
2272 }
2273 case Instruction::DIV_LONG_2ADDR: {
2274 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002275 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002276 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002277 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002278 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2279 break;
2280 }
2281 case Instruction::REM_LONG_2ADDR: {
2282 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002283 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002284 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002285 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002286 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2287 break;
2288 }
2289 case Instruction::AND_LONG_2ADDR: {
2290 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002291 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002292 shadow_frame.SetVRegLong(vregA,
2293 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002294 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002295 inst = inst->Next_1xx();
2296 break;
2297 }
2298 case Instruction::OR_LONG_2ADDR: {
2299 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002300 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002301 shadow_frame.SetVRegLong(vregA,
2302 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002303 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002304 inst = inst->Next_1xx();
2305 break;
2306 }
2307 case Instruction::XOR_LONG_2ADDR: {
2308 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002309 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002310 shadow_frame.SetVRegLong(vregA,
2311 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002312 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002313 inst = inst->Next_1xx();
2314 break;
2315 }
2316 case Instruction::SHL_LONG_2ADDR: {
2317 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002318 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002319 shadow_frame.SetVRegLong(vregA,
2320 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002321 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002322 inst = inst->Next_1xx();
2323 break;
2324 }
2325 case Instruction::SHR_LONG_2ADDR: {
2326 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002327 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002328 shadow_frame.SetVRegLong(vregA,
2329 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002330 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002331 inst = inst->Next_1xx();
2332 break;
2333 }
2334 case Instruction::USHR_LONG_2ADDR: {
2335 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002336 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002337 shadow_frame.SetVRegLong(vregA,
2338 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002339 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002340 inst = inst->Next_1xx();
2341 break;
2342 }
2343 case Instruction::ADD_FLOAT_2ADDR: {
2344 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002345 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002346 shadow_frame.SetVRegFloat(vregA,
2347 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002348 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002349 inst = inst->Next_1xx();
2350 break;
2351 }
2352 case Instruction::SUB_FLOAT_2ADDR: {
2353 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002354 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002355 shadow_frame.SetVRegFloat(vregA,
2356 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002357 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002358 inst = inst->Next_1xx();
2359 break;
2360 }
2361 case Instruction::MUL_FLOAT_2ADDR: {
2362 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002363 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002364 shadow_frame.SetVRegFloat(vregA,
2365 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002366 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002367 inst = inst->Next_1xx();
2368 break;
2369 }
2370 case Instruction::DIV_FLOAT_2ADDR: {
2371 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002372 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002373 shadow_frame.SetVRegFloat(vregA,
2374 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002375 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002376 inst = inst->Next_1xx();
2377 break;
2378 }
2379 case Instruction::REM_FLOAT_2ADDR: {
2380 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002381 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002382 shadow_frame.SetVRegFloat(vregA,
2383 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002384 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002385 inst = inst->Next_1xx();
2386 break;
2387 }
2388 case Instruction::ADD_DOUBLE_2ADDR: {
2389 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002390 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002391 shadow_frame.SetVRegDouble(vregA,
2392 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002393 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002394 inst = inst->Next_1xx();
2395 break;
2396 }
2397 case Instruction::SUB_DOUBLE_2ADDR: {
2398 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002399 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002400 shadow_frame.SetVRegDouble(vregA,
2401 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002402 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002403 inst = inst->Next_1xx();
2404 break;
2405 }
2406 case Instruction::MUL_DOUBLE_2ADDR: {
2407 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002408 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002409 shadow_frame.SetVRegDouble(vregA,
2410 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002411 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002412 inst = inst->Next_1xx();
2413 break;
2414 }
2415 case Instruction::DIV_DOUBLE_2ADDR: {
2416 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002417 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002418 shadow_frame.SetVRegDouble(vregA,
2419 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002420 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002421 inst = inst->Next_1xx();
2422 break;
2423 }
2424 case Instruction::REM_DOUBLE_2ADDR: {
2425 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002426 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002427 shadow_frame.SetVRegDouble(vregA,
2428 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002429 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002430 inst = inst->Next_1xx();
2431 break;
2432 }
2433 case Instruction::ADD_INT_LIT16:
2434 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002435 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002436 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2437 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002438 inst = inst->Next_2xx();
2439 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002440 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002441 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002442 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002443 SafeSub(inst->VRegC_22s(),
2444 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002445 inst = inst->Next_2xx();
2446 break;
2447 case Instruction::MUL_INT_LIT16:
2448 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002449 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002450 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2451 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002452 inst = inst->Next_2xx();
2453 break;
2454 case Instruction::DIV_INT_LIT16: {
2455 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002456 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002457 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2458 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002459 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2460 break;
2461 }
2462 case Instruction::REM_INT_LIT16: {
2463 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002464 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002465 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2466 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002467 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2468 break;
2469 }
2470 case Instruction::AND_INT_LIT16:
2471 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002472 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2473 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002474 inst->VRegC_22s());
2475 inst = inst->Next_2xx();
2476 break;
2477 case Instruction::OR_INT_LIT16:
2478 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002479 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2480 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002481 inst->VRegC_22s());
2482 inst = inst->Next_2xx();
2483 break;
2484 case Instruction::XOR_INT_LIT16:
2485 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002486 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2487 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002488 inst->VRegC_22s());
2489 inst = inst->Next_2xx();
2490 break;
2491 case Instruction::ADD_INT_LIT8:
2492 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002493 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002494 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002495 inst = inst->Next_2xx();
2496 break;
2497 case Instruction::RSUB_INT_LIT8:
2498 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002499 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002500 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002501 inst = inst->Next_2xx();
2502 break;
2503 case Instruction::MUL_INT_LIT8:
2504 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002505 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002506 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002507 inst = inst->Next_2xx();
2508 break;
2509 case Instruction::DIV_INT_LIT8: {
2510 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002511 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002512 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2513 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2514 break;
2515 }
2516 case Instruction::REM_INT_LIT8: {
2517 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002518 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002519 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2520 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2521 break;
2522 }
2523 case Instruction::AND_INT_LIT8:
2524 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002525 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002526 shadow_frame.GetVReg(inst->VRegB_22b()) &
2527 inst->VRegC_22b());
2528 inst = inst->Next_2xx();
2529 break;
2530 case Instruction::OR_INT_LIT8:
2531 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002532 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002533 shadow_frame.GetVReg(inst->VRegB_22b()) |
2534 inst->VRegC_22b());
2535 inst = inst->Next_2xx();
2536 break;
2537 case Instruction::XOR_INT_LIT8:
2538 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002539 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002540 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2541 inst->VRegC_22b());
2542 inst = inst->Next_2xx();
2543 break;
2544 case Instruction::SHL_INT_LIT8:
2545 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002546 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002547 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2548 (inst->VRegC_22b() & 0x1f));
2549 inst = inst->Next_2xx();
2550 break;
2551 case Instruction::SHR_INT_LIT8:
2552 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002553 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002554 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2555 (inst->VRegC_22b() & 0x1f));
2556 inst = inst->Next_2xx();
2557 break;
2558 case Instruction::USHR_INT_LIT8:
2559 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002560 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002561 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2562 (inst->VRegC_22b() & 0x1f));
2563 inst = inst->Next_2xx();
2564 break;
2565 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Orion Hodson2e599942017-09-22 16:17:41 +01002566 case Instruction::UNUSED_79 ... Instruction::UNUSED_7A:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002567 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
Ian Rogerse94652f2014-12-02 11:13:19 -08002568 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002569 }
buzbee1452bee2015-03-06 14:43:04 -08002570 } while (!interpret_one_instruction);
2571 // Record where we stopped.
2572 shadow_frame.SetDexPC(inst->GetDexPc(insns));
David Srbecky946bb092018-03-09 17:23:01 +00002573 ctx->result = result_register;
2574 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002575} // NOLINT(readability/fn_size)
2576
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002577} // namespace interpreter
2578} // namespace art
David Srbecky2ee09ff2018-10-24 13:24:22 +01002579
2580#endif // ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_