blob: b2ea862016bee1c576838591f27b0e7d5fae96f9 [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"
Andreas Gampefd63bbf2018-10-29 12:55:35 -070030#include "mirror/string-alloc-inl.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000031#include "nth_caller_visitor.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070032#include "safe_math.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010033#include "shadow_frame-inl.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000034#include "thread.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020035
36namespace art {
37namespace interpreter {
38
Alex Light0aa7a5a2018-10-10 15:58:14 +000039#define CHECK_FORCE_RETURN() \
David Srbecky30232c42018-10-26 18:56:01 +010040 { \
Alex Light0aa7a5a2018-10-10 15:58:14 +000041 if (UNLIKELY(shadow_frame.GetForcePopFrame())) { \
42 DCHECK(PrevFrameWillRetry(self, shadow_frame)) \
43 << "Pop frame forced without previous frame ready to retry instruction!"; \
44 DCHECK(Runtime::Current()->AreNonStandardExitsEnabled()); \
45 if (UNLIKELY(NeedsMethodExitEvent(instrumentation))) { \
46 SendMethodExitEvents(self, \
47 instrumentation, \
48 shadow_frame, \
49 shadow_frame.GetThisObject(accessor.InsSize()), \
50 shadow_frame.GetMethod(), \
51 inst->GetDexPc(insns), \
52 JValue()); \
53 } \
54 ctx->result = JValue(); /* Handled in caller. */ \
55 return; \
56 } \
David Srbecky30232c42018-10-26 18:56:01 +010057 } \
58 do {} while (false)
Alex Light0aa7a5a2018-10-10 15:58:14 +000059
Alex Lightb7edcda2017-04-27 13:20:31 -070060#define HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instr) \
David Srbecky30232c42018-10-26 18:56:01 +010061 { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020062 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070063 self->AllowThreadSuspension(); \
Alex Light0aa7a5a2018-10-10 15:58:14 +000064 CHECK_FORCE_RETURN(); \
Alex Light9fb1ab12017-09-05 09:32:49 -070065 if (!MoveToExceptionHandler(self, shadow_frame, instr)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070066 /* Structured locking is to be enforced for abnormal termination, too. */ \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070067 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame); \
buzbee1452bee2015-03-06 14:43:04 -080068 if (interpret_one_instruction) { \
buzbee93e94f22016-04-07 13:52:48 -070069 /* Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -070070 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee1452bee2015-03-06 14:43:04 -080071 } \
David Srbecky946bb092018-03-09 17:23:01 +000072 ctx->result = JValue(); /* Handled in caller. */ \
73 return; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020074 } else { \
Alex Light0aa7a5a2018-10-10 15:58:14 +000075 CHECK_FORCE_RETURN(); \
Alex Light9fb1ab12017-09-05 09:32:49 -070076 int32_t displacement = \
77 static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020078 inst = inst->RelativeAt(displacement); \
David Srbecky30232c42018-10-26 18:56:01 +010079 break; /* Stop executing this opcode and continue in the exception handler. */ \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020080 } \
David Srbecky30232c42018-10-26 18:56:01 +010081 } \
82 do {} while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020083
Alex Lightb7edcda2017-04-27 13:20:31 -070084#define HANDLE_PENDING_EXCEPTION() HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instrumentation)
85
Alex Light0aa7a5a2018-10-10 15:58:14 +000086#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, _next_function) \
David Srbecky30232c42018-10-26 18:56:01 +010087 { \
Alex Light0aa7a5a2018-10-10 15:58:14 +000088 if (UNLIKELY(shadow_frame.GetForceRetryInstruction())) { \
89 /* Don't need to do anything except clear the flag and exception. We leave the */ \
90 /* instruction the same so it will be re-executed on the next go-around. */ \
91 DCHECK(inst->IsInvoke()); \
92 shadow_frame.SetForceRetryInstruction(false); \
93 if (UNLIKELY(_is_exception_pending)) { \
94 DCHECK(self->IsExceptionPending()); \
95 if (kIsDebugBuild) { \
96 LOG(WARNING) << "Suppressing exception for instruction-retry: " \
97 << self->GetException()->Dump(); \
98 } \
99 self->ClearException(); \
100 } \
101 } else if (UNLIKELY(_is_exception_pending)) { \
102 /* Should have succeeded. */ \
103 DCHECK(!shadow_frame.GetForceRetryInstruction()); \
104 HANDLE_PENDING_EXCEPTION(); \
105 } else { \
106 inst = inst->_next_function(); \
107 } \
David Srbecky30232c42018-10-26 18:56:01 +0100108 } \
109 do {} while (false)
Alex Light0aa7a5a2018-10-10 15:58:14 +0000110
111#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(_is_exception_pending) \
112 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, Next_4xx)
113#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(_is_exception_pending) \
114 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, Next_3xx)
115
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200116#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
David Srbecky30232c42018-10-26 18:56:01 +0100117 { \
Alex Light0aa7a5a2018-10-10 15:58:14 +0000118 /* Should only be on invoke instructions. */ \
119 DCHECK(!shadow_frame.GetForceRetryInstruction()); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200120 if (UNLIKELY(_is_exception_pending)) { \
121 HANDLE_PENDING_EXCEPTION(); \
122 } else { \
123 inst = inst->_next_function(); \
124 } \
David Srbecky30232c42018-10-26 18:56:01 +0100125 } \
126 do {} while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200127
Andreas Gampe03ec9302015-08-27 17:41:47 -0700128#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -0700129 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -0700130 HANDLE_PENDING_EXCEPTION(); \
131 }
132
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200133// Code to run before each dex instruction.
Alex Light0aa7a5a2018-10-10 15:58:14 +0000134#define PREAMBLE_SAVE(save_ref) \
Alex Lightfc905672017-06-27 17:53:15 -0700135 { \
Alex Light0aa7a5a2018-10-10 15:58:14 +0000136 /* We need to put this before & after the instrumentation to avoid having to put in a */ \
137 /* post-script macro. */ \
138 CHECK_FORCE_RETURN(); \
139 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
140 if (UNLIKELY(!DoDexPcMoveEvent(self, \
141 accessor, \
142 shadow_frame, \
143 dex_pc, \
144 instrumentation, \
145 save_ref))) { \
146 HANDLE_PENDING_EXCEPTION(); \
147 break; \
148 } \
149 CHECK_FORCE_RETURN(); \
Sebastien Hertz8379b222014-02-24 17:38:15 +0100150 } \
Alex Lightfc905672017-06-27 17:53:15 -0700151 } \
152 do {} while (false)
153
154#define PREAMBLE() PREAMBLE_SAVE(nullptr)
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200155
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000156#define BRANCH_INSTRUMENTATION(offset) \
David Srbecky30232c42018-10-26 18:56:01 +0100157 { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100158 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
Alex Lightcc917d92018-02-22 13:28:28 -0800159 instrumentation->Branch(self, shadow_frame.GetMethod(), dex_pc, offset); \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100160 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000161 JValue result; \
Alex Lightcc917d92018-02-22 13:28:28 -0800162 if (jit::Jit::MaybeDoOnStackReplacement(self, \
163 shadow_frame.GetMethod(), \
164 dex_pc, \
165 offset, \
166 &result)) { \
buzbee93e94f22016-04-07 13:52:48 -0700167 if (interpret_one_instruction) { \
168 /* OSR has completed execution of the method. Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -0700169 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee93e94f22016-04-07 13:52:48 -0700170 } \
David Srbecky946bb092018-03-09 17:23:01 +0000171 ctx->result = result; \
172 return; \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000173 } \
David Srbecky30232c42018-10-26 18:56:01 +0100174 } \
175 do {} while (false)
Nicolas Geoffray3108daf2015-11-24 16:32:33 +0000176
Bill Buzbee1d011d92016-04-04 16:59:29 +0000177#define HOTNESS_UPDATE() \
David Srbecky30232c42018-10-26 18:56:01 +0100178 { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100179 if (jit != nullptr) { \
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700180 jit->AddSamples(self, shadow_frame.GetMethod(), 1, /*with_backedges=*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +0000181 } \
David Srbecky30232c42018-10-26 18:56:01 +0100182 } \
183 do {} while (false)
Bill Buzbee1d011d92016-04-04 16:59:29 +0000184
Alex Light848574c2017-09-25 16:59:39 -0700185#define HANDLE_ASYNC_EXCEPTION() \
186 if (UNLIKELY(self->ObserveAsyncException())) { \
187 HANDLE_PENDING_EXCEPTION(); \
Alex Light848574c2017-09-25 16:59:39 -0700188 } \
189 do {} while (false)
190
Andreas Gampef4f76372016-12-13 14:43:58 -0800191#define HANDLE_BACKWARD_BRANCH(offset) \
David Srbecky30232c42018-10-26 18:56:01 +0100192 { \
Andreas Gampef4f76372016-12-13 14:43:58 -0800193 if (IsBackwardBranch(offset)) { \
194 HOTNESS_UPDATE(); \
195 /* Record new dex pc early to have consistent suspend point at loop header. */ \
196 shadow_frame.SetDexPC(inst->GetDexPc(insns)); \
197 self->AllowThreadSuspension(); \
198 } \
David Srbecky30232c42018-10-26 18:56:01 +0100199 } \
200 do {} while (false)
Andreas Gampef4f76372016-12-13 14:43:58 -0800201
Alex Lightfc905672017-06-27 17:53:15 -0700202// Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
203// the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
204// to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
205// jvmti-agents while handling breakpoint or single step events. We had to move this into its own
206// function because it was making ExecuteSwitchImpl have too large a stack.
Alex Light2989a4a2017-06-29 09:44:57 -0700207NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800208 const CodeItemDataAccessor& accessor,
Alex Light2989a4a2017-06-29 09:44:57 -0700209 const ShadowFrame& shadow_frame,
210 uint32_t dex_pc,
211 const instrumentation::Instrumentation* instrumentation,
212 JValue* save_ref)
Alex Lightfc905672017-06-27 17:53:15 -0700213 REQUIRES_SHARED(Locks::mutator_lock_) {
214 DCHECK(instrumentation->HasDexPcListeners());
215 StackHandleScope<2> hs(self);
216 Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
217 mirror::Object* null_obj = nullptr;
218 HandleWrapper<mirror::Object> h(
219 hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
220 self->ClearException();
221 instrumentation->DexPcMovedEvent(self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800222 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lightfc905672017-06-27 17:53:15 -0700223 shadow_frame.GetMethod(),
224 dex_pc);
225 if (UNLIKELY(self->IsExceptionPending())) {
226 // We got a new exception in the dex-pc-moved event. We just let this exception replace the old
227 // one.
228 // TODO It would be good to add the old exception to the suppressed exceptions of the new one if
229 // possible.
230 return false;
231 } else {
232 if (UNLIKELY(!thr.IsNull())) {
233 self->SetException(thr.Get());
234 }
235 return true;
236 }
237}
238
Alex Lighte814f9d2017-07-31 16:14:39 -0700239static bool NeedsMethodExitEvent(const instrumentation::Instrumentation* ins)
240 REQUIRES_SHARED(Locks::mutator_lock_) {
241 return ins->HasMethodExitListeners() || ins->HasWatchedFramePopListeners();
242}
243
244// Sends the normal method exit event. Returns true if the events succeeded and false if there is a
245// pending exception.
246NO_INLINE static bool SendMethodExitEvents(Thread* self,
247 const instrumentation::Instrumentation* instrumentation,
248 const ShadowFrame& frame,
249 ObjPtr<mirror::Object> thiz,
250 ArtMethod* method,
251 uint32_t dex_pc,
252 const JValue& result)
253 REQUIRES_SHARED(Locks::mutator_lock_) {
254 bool had_event = false;
Alex Light0aa7a5a2018-10-10 15:58:14 +0000255 // We don't send method-exit if it's a pop-frame. We still send frame_popped though.
256 if (UNLIKELY(instrumentation->HasMethodExitListeners() && !frame.GetForcePopFrame())) {
Alex Lighte814f9d2017-07-31 16:14:39 -0700257 had_event = true;
258 instrumentation->MethodExitEvent(self, thiz.Ptr(), method, dex_pc, result);
259 }
260 if (UNLIKELY(frame.NeedsNotifyPop() && instrumentation->HasWatchedFramePopListeners())) {
261 had_event = true;
262 instrumentation->WatchedFramePopped(self, frame);
263 }
264 if (UNLIKELY(had_event)) {
265 return !self->IsExceptionPending();
266 } else {
267 return true;
268 }
269}
270
Alex Light6f22e062018-10-05 15:05:12 -0700271// TODO On ASAN builds this function gets a huge stack frame. Since normally we run in the mterp
272// this shouldn't cause any problems for stack overflow detection. Remove this once b/117341496 is
273// fixed.
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100274template<bool do_access_check, bool transaction_active>
Alex Light6f22e062018-10-05 15:05:12 -0700275ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
David Srbecky946bb092018-03-09 17:23:01 +0000276 Thread* self = ctx->self;
277 const CodeItemDataAccessor& accessor = ctx->accessor;
278 ShadowFrame& shadow_frame = ctx->shadow_frame;
279 JValue result_register = ctx->result_register;
280 bool interpret_one_instruction = ctx->interpret_one_instruction;
Igor Murashkinc449e8b2015-06-10 15:56:42 -0700281 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200282 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
283 LOG(FATAL) << "Invalid shadow frame for interpreter use";
David Srbecky946bb092018-03-09 17:23:01 +0000284 ctx->result = JValue();
285 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200286 }
287 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200288
289 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700290 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800291 const uint16_t* const insns = accessor.Insns();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200292 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200293 uint16_t inst_data;
Bill Buzbee1d011d92016-04-04 16:59:29 +0000294 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700295
Alex Light0aa7a5a2018-10-10 15:58:14 +0000296 DCHECK(!shadow_frame.GetForceRetryInstruction())
297 << "Entered interpreter from invoke without retry instruction being handled!";
298
buzbee1452bee2015-03-06 14:43:04 -0800299 do {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200300 dex_pc = inst->GetDexPc(insns);
301 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800302 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200303 inst_data = inst->Fetch16(0);
304 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200305 case Instruction::NOP:
306 PREAMBLE();
307 inst = inst->Next_1xx();
308 break;
309 case Instruction::MOVE:
310 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200311 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
312 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200313 inst = inst->Next_1xx();
314 break;
315 case Instruction::MOVE_FROM16:
316 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200317 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200318 shadow_frame.GetVReg(inst->VRegB_22x()));
319 inst = inst->Next_2xx();
320 break;
321 case Instruction::MOVE_16:
322 PREAMBLE();
323 shadow_frame.SetVReg(inst->VRegA_32x(),
324 shadow_frame.GetVReg(inst->VRegB_32x()));
325 inst = inst->Next_3xx();
326 break;
327 case Instruction::MOVE_WIDE:
328 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200329 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
330 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200331 inst = inst->Next_1xx();
332 break;
333 case Instruction::MOVE_WIDE_FROM16:
334 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200335 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200336 shadow_frame.GetVRegLong(inst->VRegB_22x()));
337 inst = inst->Next_2xx();
338 break;
339 case Instruction::MOVE_WIDE_16:
340 PREAMBLE();
341 shadow_frame.SetVRegLong(inst->VRegA_32x(),
342 shadow_frame.GetVRegLong(inst->VRegB_32x()));
343 inst = inst->Next_3xx();
344 break;
345 case Instruction::MOVE_OBJECT:
346 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200347 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
348 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200349 inst = inst->Next_1xx();
350 break;
351 case Instruction::MOVE_OBJECT_FROM16:
352 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200353 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200354 shadow_frame.GetVRegReference(inst->VRegB_22x()));
355 inst = inst->Next_2xx();
356 break;
357 case Instruction::MOVE_OBJECT_16:
358 PREAMBLE();
359 shadow_frame.SetVRegReference(inst->VRegA_32x(),
360 shadow_frame.GetVRegReference(inst->VRegB_32x()));
361 inst = inst->Next_3xx();
362 break;
363 case Instruction::MOVE_RESULT:
364 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200365 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200366 inst = inst->Next_1xx();
367 break;
368 case Instruction::MOVE_RESULT_WIDE:
369 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200370 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200371 inst = inst->Next_1xx();
372 break;
373 case Instruction::MOVE_RESULT_OBJECT:
Alex Lightfc905672017-06-27 17:53:15 -0700374 PREAMBLE_SAVE(&result_register);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200375 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200376 inst = inst->Next_1xx();
377 break;
378 case Instruction::MOVE_EXCEPTION: {
379 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700380 ObjPtr<mirror::Throwable> exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100381 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100382 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200383 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200384 inst = inst->Next_1xx();
385 break;
386 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700387 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200388 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200389 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700390 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700391 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700392 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
393 !SendMethodExitEvents(self,
394 instrumentation,
395 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800396 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700397 shadow_frame.GetMethod(),
398 inst->GetDexPc(insns),
399 result))) {
400 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200401 }
buzbee1452bee2015-03-06 14:43:04 -0800402 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700403 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700404 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800405 }
David Srbecky946bb092018-03-09 17:23:01 +0000406 ctx->result = result;
407 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200408 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700409 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200410 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700411 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200412 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700413 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700414 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700415 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
416 !SendMethodExitEvents(self,
417 instrumentation,
418 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800419 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700420 shadow_frame.GetMethod(),
421 inst->GetDexPc(insns),
422 result))) {
423 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200424 }
buzbee1452bee2015-03-06 14:43:04 -0800425 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700426 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700427 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800428 }
David Srbecky946bb092018-03-09 17:23:01 +0000429 ctx->result = result;
430 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200431 }
432 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200433 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200434 JValue result;
435 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200436 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700437 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700438 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700439 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
440 !SendMethodExitEvents(self,
441 instrumentation,
442 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800443 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700444 shadow_frame.GetMethod(),
445 inst->GetDexPc(insns),
446 result))) {
447 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200448 }
buzbee1452bee2015-03-06 14:43:04 -0800449 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700450 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700451 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800452 }
David Srbecky946bb092018-03-09 17:23:01 +0000453 ctx->result = result;
454 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200455 }
456 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200457 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200458 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200459 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700460 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700461 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700462 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
463 !SendMethodExitEvents(self,
464 instrumentation,
465 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800466 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700467 shadow_frame.GetMethod(),
468 inst->GetDexPc(insns),
469 result))) {
470 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200471 }
buzbee1452bee2015-03-06 14:43:04 -0800472 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700473 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700474 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800475 }
David Srbecky946bb092018-03-09 17:23:01 +0000476 ctx->result = result;
477 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200478 }
479 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200480 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200481 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700482 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700483 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700484 const size_t ref_idx = inst->VRegA_11x(inst_data);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700485 ObjPtr<mirror::Object> obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700486 if (do_assignability_check && obj_result != nullptr) {
Alex Lightcc917d92018-02-22 13:28:28 -0800487 ObjPtr<mirror::Class> return_type = shadow_frame.GetMethod()->ResolveReturnType();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700488 // Re-load since it might have moved.
489 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700490 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700491 // Return the pending exception.
492 HANDLE_PENDING_EXCEPTION();
493 }
494 if (!obj_result->VerifierInstanceOf(return_type)) {
495 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700496 std::string temp1, temp2;
Orion Hodsonfef06642016-11-25 16:07:11 +0000497 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700498 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700499 obj_result->GetClass()->GetDescriptor(&temp1),
500 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700501 HANDLE_PENDING_EXCEPTION();
502 }
503 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700504 result.SetL(obj_result);
Alex Lighte814f9d2017-07-31 16:14:39 -0700505 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
506 !SendMethodExitEvents(self,
507 instrumentation,
508 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800509 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700510 shadow_frame.GetMethod(),
511 inst->GetDexPc(insns),
512 result))) {
513 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200514 }
Alex Lighte814f9d2017-07-31 16:14:39 -0700515 // Re-load since it might have moved during the MethodExitEvent.
516 result.SetL(shadow_frame.GetVRegReference(ref_idx));
buzbee1452bee2015-03-06 14:43:04 -0800517 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700518 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700519 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800520 }
David Srbecky946bb092018-03-09 17:23:01 +0000521 ctx->result = result;
522 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200523 }
524 case Instruction::CONST_4: {
525 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200526 uint4_t dst = inst->VRegA_11n(inst_data);
527 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200528 shadow_frame.SetVReg(dst, val);
529 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700530 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200531 }
532 inst = inst->Next_1xx();
533 break;
534 }
535 case Instruction::CONST_16: {
536 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200537 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200538 int16_t val = inst->VRegB_21s();
539 shadow_frame.SetVReg(dst, val);
540 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700541 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200542 }
543 inst = inst->Next_2xx();
544 break;
545 }
546 case Instruction::CONST: {
547 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200548 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200549 int32_t val = inst->VRegB_31i();
550 shadow_frame.SetVReg(dst, val);
551 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700552 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200553 }
554 inst = inst->Next_3xx();
555 break;
556 }
557 case Instruction::CONST_HIGH16: {
558 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200559 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200560 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
561 shadow_frame.SetVReg(dst, val);
562 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700563 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200564 }
565 inst = inst->Next_2xx();
566 break;
567 }
568 case Instruction::CONST_WIDE_16:
569 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200570 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200571 inst = inst->Next_2xx();
572 break;
573 case Instruction::CONST_WIDE_32:
574 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200575 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200576 inst = inst->Next_3xx();
577 break;
578 case Instruction::CONST_WIDE:
579 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200580 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200581 inst = inst->Next_51l();
582 break;
583 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200584 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200585 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200586 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
587 inst = inst->Next_2xx();
588 break;
589 case Instruction::CONST_STRING: {
590 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800591 ObjPtr<mirror::String> s = ResolveString(self,
592 shadow_frame,
593 dex::StringIndex(inst->VRegB_21c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700594 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200595 HANDLE_PENDING_EXCEPTION();
596 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100597 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200598 inst = inst->Next_2xx();
599 }
600 break;
601 }
602 case Instruction::CONST_STRING_JUMBO: {
603 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800604 ObjPtr<mirror::String> s = ResolveString(self,
605 shadow_frame,
606 dex::StringIndex(inst->VRegB_31c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700607 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200608 HANDLE_PENDING_EXCEPTION();
609 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100610 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200611 inst = inst->Next_3xx();
612 }
613 break;
614 }
615 case Instruction::CONST_CLASS: {
616 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800617 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700618 shadow_frame.GetMethod(),
619 self,
620 false,
621 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700622 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200623 HANDLE_PENDING_EXCEPTION();
624 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100625 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200626 inst = inst->Next_2xx();
627 }
628 break;
629 }
Orion Hodson2e599942017-09-22 16:17:41 +0100630 case Instruction::CONST_METHOD_HANDLE: {
631 PREAMBLE();
Orion Hodsone7732be2017-10-11 14:35:20 +0100632 ClassLinker* cl = Runtime::Current()->GetClassLinker();
Alex Lightcc917d92018-02-22 13:28:28 -0800633 ObjPtr<mirror::MethodHandle> mh = cl->ResolveMethodHandle(self,
634 inst->VRegB_21c(),
635 shadow_frame.GetMethod());
Orion Hodson2e599942017-09-22 16:17:41 +0100636 if (UNLIKELY(mh == nullptr)) {
637 HANDLE_PENDING_EXCEPTION();
638 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100639 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mh);
Orion Hodson2e599942017-09-22 16:17:41 +0100640 inst = inst->Next_2xx();
641 }
642 break;
643 }
644 case Instruction::CONST_METHOD_TYPE: {
645 PREAMBLE();
Orion Hodsone7732be2017-10-11 14:35:20 +0100646 ClassLinker* cl = Runtime::Current()->GetClassLinker();
Alex Lightcc917d92018-02-22 13:28:28 -0800647 ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(self,
Orion Hodson06d10a72018-05-14 08:53:38 +0100648 dex::ProtoIndex(inst->VRegB_21c()),
Alex Lightcc917d92018-02-22 13:28:28 -0800649 shadow_frame.GetMethod());
Orion Hodson2e599942017-09-22 16:17:41 +0100650 if (UNLIKELY(mt == nullptr)) {
651 HANDLE_PENDING_EXCEPTION();
652 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100653 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mt);
Orion Hodson2e599942017-09-22 16:17:41 +0100654 inst = inst->Next_2xx();
655 }
656 break;
657 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200658 case Instruction::MONITOR_ENTER: {
659 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700660 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700661 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700662 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000663 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200664 HANDLE_PENDING_EXCEPTION();
665 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700666 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200667 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
668 }
669 break;
670 }
671 case Instruction::MONITOR_EXIT: {
672 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700673 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700674 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700675 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000676 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200677 HANDLE_PENDING_EXCEPTION();
678 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700679 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200680 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
681 }
682 break;
683 }
684 case Instruction::CHECK_CAST: {
685 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800686 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700687 shadow_frame.GetMethod(),
688 self,
689 false,
690 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700691 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200692 HANDLE_PENDING_EXCEPTION();
693 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700694 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700695 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200696 ThrowClassCastException(c, obj->GetClass());
697 HANDLE_PENDING_EXCEPTION();
698 } else {
699 inst = inst->Next_2xx();
700 }
701 }
702 break;
703 }
704 case Instruction::INSTANCE_OF: {
705 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800706 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegC_22c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700707 shadow_frame.GetMethod(),
708 self,
709 false,
710 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700711 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200712 HANDLE_PENDING_EXCEPTION();
713 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700714 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700715 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
716 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200717 inst = inst->Next_2xx();
718 }
719 break;
720 }
721 case Instruction::ARRAY_LENGTH: {
722 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700723 ObjPtr<mirror::Object> array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700724 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000725 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200726 HANDLE_PENDING_EXCEPTION();
727 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200728 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200729 inst = inst->Next_1xx();
730 }
731 break;
732 }
733 case Instruction::NEW_INSTANCE: {
734 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700735 ObjPtr<mirror::Object> obj = nullptr;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800736 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700737 shadow_frame.GetMethod(),
738 self,
739 false,
740 do_access_check);
Jeff Hao848f70a2014-01-15 13:49:50 -0800741 if (LIKELY(c != nullptr)) {
742 if (UNLIKELY(c->IsStringClass())) {
743 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700744 obj = mirror::String::AllocEmptyString<true>(self, allocator_type);
Jeff Hao848f70a2014-01-15 13:49:50 -0800745 } else {
Nicolas Geoffray0d3998b2017-01-12 15:35:12 +0000746 obj = AllocObjectFromCode<true>(
747 c.Ptr(),
Andreas Gampea5b09a62016-11-17 15:21:22 -0800748 self,
749 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Jeff Hao848f70a2014-01-15 13:49:50 -0800750 }
751 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700752 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200753 HANDLE_PENDING_EXCEPTION();
754 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200755 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700756 // Don't allow finalizable objects to be allocated during a transaction since these can't
757 // be finalized without a started runtime.
758 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200759 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
David Sehr709b0702016-10-13 09:12:37 -0700760 obj->PrettyTypeOf().c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700761 HANDLE_PENDING_EXCEPTION();
762 break;
763 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100764 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200765 inst = inst->Next_2xx();
766 }
767 break;
768 }
769 case Instruction::NEW_ARRAY: {
770 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200771 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartieref41db72016-10-25 15:08:01 -0700772 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800773 dex::TypeIndex(inst->VRegC_22c()),
774 length,
775 shadow_frame.GetMethod(),
776 self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800777 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700778 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200779 HANDLE_PENDING_EXCEPTION();
780 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100781 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200782 inst = inst->Next_2xx();
783 }
784 break;
785 }
786 case Instruction::FILLED_NEW_ARRAY: {
787 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100788 bool success =
789 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
790 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200791 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
792 break;
793 }
794 case Instruction::FILLED_NEW_ARRAY_RANGE: {
795 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100796 bool success =
797 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
798 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200799 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
800 break;
801 }
802 case Instruction::FILL_ARRAY_DATA: {
803 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200804 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
805 const Instruction::ArrayDataPayload* payload =
806 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700807 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700808 bool success = FillArrayData(obj, payload);
809 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200810 HANDLE_PENDING_EXCEPTION();
811 break;
812 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100813 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700814 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100815 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200816 inst = inst->Next_3xx();
817 break;
818 }
819 case Instruction::THROW: {
820 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700821 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700822 ObjPtr<mirror::Object> exception =
823 shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700824 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000825 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700826 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
827 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700828 std::string temp;
Orion Hodsonfef06642016-11-25 16:07:11 +0000829 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700830 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700831 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200832 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000833 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200834 }
835 HANDLE_PENDING_EXCEPTION();
836 break;
837 }
838 case Instruction::GOTO: {
839 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700840 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200841 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000842 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200843 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800844 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200845 break;
846 }
847 case Instruction::GOTO_16: {
848 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700849 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200850 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000851 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200852 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800853 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200854 break;
855 }
856 case Instruction::GOTO_32: {
857 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700858 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200859 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000860 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +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::PACKED_SWITCH: {
866 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200867 int32_t offset = DoPackedSwitch(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 }
873 case Instruction::SPARSE_SWITCH: {
874 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200875 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000876 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200877 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800878 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200879 break;
880 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700881
Ian Rogers647b1a82014-10-10 11:02:11 -0700882#pragma clang diagnostic push
883#pragma clang diagnostic ignored "-Wfloat-equal"
Ian Rogers647b1a82014-10-10 11:02:11 -0700884
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200885 case Instruction::CMPL_FLOAT: {
886 PREAMBLE();
887 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
888 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
889 int32_t result;
890 if (val1 > val2) {
891 result = 1;
892 } else if (val1 == val2) {
893 result = 0;
894 } else {
895 result = -1;
896 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200897 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200898 inst = inst->Next_2xx();
899 break;
900 }
901 case Instruction::CMPG_FLOAT: {
902 PREAMBLE();
903 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
904 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
905 int32_t result;
906 if (val1 < val2) {
907 result = -1;
908 } else if (val1 == val2) {
909 result = 0;
910 } else {
911 result = 1;
912 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200913 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200914 inst = inst->Next_2xx();
915 break;
916 }
917 case Instruction::CMPL_DOUBLE: {
918 PREAMBLE();
919 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
920 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
921 int32_t result;
922 if (val1 > val2) {
923 result = 1;
924 } else if (val1 == val2) {
925 result = 0;
926 } else {
927 result = -1;
928 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200929 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200930 inst = inst->Next_2xx();
931 break;
932 }
933
934 case Instruction::CMPG_DOUBLE: {
935 PREAMBLE();
936 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
937 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
938 int32_t result;
939 if (val1 < val2) {
940 result = -1;
941 } else if (val1 == val2) {
942 result = 0;
943 } else {
944 result = 1;
945 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200946 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200947 inst = inst->Next_2xx();
948 break;
949 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700950
Ian Rogers647b1a82014-10-10 11:02:11 -0700951#pragma clang diagnostic pop
Ian Rogers647b1a82014-10-10 11:02:11 -0700952
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200953 case Instruction::CMP_LONG: {
954 PREAMBLE();
955 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
956 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
957 int32_t result;
958 if (val1 > val2) {
959 result = 1;
960 } else if (val1 == val2) {
961 result = 0;
962 } else {
963 result = -1;
964 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200965 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200966 inst = inst->Next_2xx();
967 break;
968 }
969 case Instruction::IF_EQ: {
970 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700971 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
972 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200973 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000974 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200975 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800976 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200977 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800978 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200979 inst = inst->Next_2xx();
980 }
981 break;
982 }
983 case Instruction::IF_NE: {
984 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700985 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
986 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200987 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000988 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200989 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800990 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200991 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800992 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200993 inst = inst->Next_2xx();
994 }
995 break;
996 }
997 case Instruction::IF_LT: {
998 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700999 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
1000 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001001 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001002 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001003 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001004 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001005 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001006 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001007 inst = inst->Next_2xx();
1008 }
1009 break;
1010 }
1011 case Instruction::IF_GE: {
1012 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001013 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
1014 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001015 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001016 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001017 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001018 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001019 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001020 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001021 inst = inst->Next_2xx();
1022 }
1023 break;
1024 }
1025 case Instruction::IF_GT: {
1026 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001027 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
1028 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001029 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001030 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001031 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001032 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001033 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001034 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001035 inst = inst->Next_2xx();
1036 }
1037 break;
1038 }
1039 case Instruction::IF_LE: {
1040 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001041 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
1042 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001043 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001044 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001045 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001046 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001047 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001048 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001049 inst = inst->Next_2xx();
1050 }
1051 break;
1052 }
1053 case Instruction::IF_EQZ: {
1054 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001055 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001056 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001057 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001058 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001059 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001060 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001061 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001062 inst = inst->Next_2xx();
1063 }
1064 break;
1065 }
1066 case Instruction::IF_NEZ: {
1067 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001068 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001069 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001070 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001071 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001072 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001073 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001074 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001075 inst = inst->Next_2xx();
1076 }
1077 break;
1078 }
1079 case Instruction::IF_LTZ: {
1080 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001081 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001082 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001083 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001084 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001085 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001086 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001087 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001088 inst = inst->Next_2xx();
1089 }
1090 break;
1091 }
1092 case Instruction::IF_GEZ: {
1093 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001094 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001095 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001096 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001097 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001098 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001099 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001100 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001101 inst = inst->Next_2xx();
1102 }
1103 break;
1104 }
1105 case Instruction::IF_GTZ: {
1106 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001107 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001108 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001109 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001110 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001111 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001112 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001113 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001114 inst = inst->Next_2xx();
1115 }
1116 break;
1117 }
1118 case Instruction::IF_LEZ: {
1119 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001120 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001121 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001122 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001123 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001124 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001125 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001126 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001127 inst = inst->Next_2xx();
1128 }
1129 break;
1130 }
1131 case Instruction::AGET_BOOLEAN: {
1132 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001133 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001134 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001135 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001136 HANDLE_PENDING_EXCEPTION();
1137 break;
1138 }
1139 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001140 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001141 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001142 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001143 inst = inst->Next_2xx();
1144 } else {
1145 HANDLE_PENDING_EXCEPTION();
1146 }
1147 break;
1148 }
1149 case Instruction::AGET_BYTE: {
1150 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001151 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001152 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001153 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001154 HANDLE_PENDING_EXCEPTION();
1155 break;
1156 }
1157 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001158 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001159 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001160 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001161 inst = inst->Next_2xx();
1162 } else {
1163 HANDLE_PENDING_EXCEPTION();
1164 }
1165 break;
1166 }
1167 case Instruction::AGET_CHAR: {
1168 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001169 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001170 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001171 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001172 HANDLE_PENDING_EXCEPTION();
1173 break;
1174 }
1175 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001176 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001177 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001178 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001179 inst = inst->Next_2xx();
1180 } else {
1181 HANDLE_PENDING_EXCEPTION();
1182 }
1183 break;
1184 }
1185 case Instruction::AGET_SHORT: {
1186 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001187 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001188 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001189 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001190 HANDLE_PENDING_EXCEPTION();
1191 break;
1192 }
1193 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001194 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001195 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001196 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001197 inst = inst->Next_2xx();
1198 } else {
1199 HANDLE_PENDING_EXCEPTION();
1200 }
1201 break;
1202 }
1203 case Instruction::AGET: {
1204 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001205 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001206 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001207 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001208 HANDLE_PENDING_EXCEPTION();
1209 break;
1210 }
1211 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001212 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001213 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001214 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001215 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001216 inst = inst->Next_2xx();
1217 } else {
1218 HANDLE_PENDING_EXCEPTION();
1219 }
1220 break;
1221 }
1222 case Instruction::AGET_WIDE: {
1223 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001224 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001225 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001226 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001227 HANDLE_PENDING_EXCEPTION();
1228 break;
1229 }
1230 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001231 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001232 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001233 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001234 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001235 inst = inst->Next_2xx();
1236 } else {
1237 HANDLE_PENDING_EXCEPTION();
1238 }
1239 break;
1240 }
1241 case Instruction::AGET_OBJECT: {
1242 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001243 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001244 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001245 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001246 HANDLE_PENDING_EXCEPTION();
1247 break;
1248 }
1249 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001250 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001251 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001252 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001253 inst = inst->Next_2xx();
1254 } else {
1255 HANDLE_PENDING_EXCEPTION();
1256 }
1257 break;
1258 }
1259 case Instruction::APUT_BOOLEAN: {
1260 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001261 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001262 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001263 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001264 HANDLE_PENDING_EXCEPTION();
1265 break;
1266 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001267 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001268 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001269 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001270 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001271 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001272 inst = inst->Next_2xx();
1273 } else {
1274 HANDLE_PENDING_EXCEPTION();
1275 }
1276 break;
1277 }
1278 case Instruction::APUT_BYTE: {
1279 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001280 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001281 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001282 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001283 HANDLE_PENDING_EXCEPTION();
1284 break;
1285 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001286 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001287 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001288 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001289 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001290 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001291 inst = inst->Next_2xx();
1292 } else {
1293 HANDLE_PENDING_EXCEPTION();
1294 }
1295 break;
1296 }
1297 case Instruction::APUT_CHAR: {
1298 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001299 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001300 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001301 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001302 HANDLE_PENDING_EXCEPTION();
1303 break;
1304 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001305 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001306 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001307 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001308 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001309 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001310 inst = inst->Next_2xx();
1311 } else {
1312 HANDLE_PENDING_EXCEPTION();
1313 }
1314 break;
1315 }
1316 case Instruction::APUT_SHORT: {
1317 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001318 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001319 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001320 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001321 HANDLE_PENDING_EXCEPTION();
1322 break;
1323 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001324 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001325 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001326 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001327 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001328 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001329 inst = inst->Next_2xx();
1330 } else {
1331 HANDLE_PENDING_EXCEPTION();
1332 }
1333 break;
1334 }
1335 case Instruction::APUT: {
1336 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001337 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001338 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001339 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001340 HANDLE_PENDING_EXCEPTION();
1341 break;
1342 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001343 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001344 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001345 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001346 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001347 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001348 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001349 inst = inst->Next_2xx();
1350 } else {
1351 HANDLE_PENDING_EXCEPTION();
1352 }
1353 break;
1354 }
1355 case Instruction::APUT_WIDE: {
1356 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001357 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001358 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001359 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001360 HANDLE_PENDING_EXCEPTION();
1361 break;
1362 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001363 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001364 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001365 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001366 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001367 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001368 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001369 inst = inst->Next_2xx();
1370 } else {
1371 HANDLE_PENDING_EXCEPTION();
1372 }
1373 break;
1374 }
1375 case Instruction::APUT_OBJECT: {
1376 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001377 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001378 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001379 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001380 HANDLE_PENDING_EXCEPTION();
1381 break;
1382 }
1383 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001384 ObjPtr<mirror::Object> val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
1385 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001386 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001387 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001388 inst = inst->Next_2xx();
1389 } else {
1390 HANDLE_PENDING_EXCEPTION();
1391 }
1392 break;
1393 }
1394 case Instruction::IGET_BOOLEAN: {
1395 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001396 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1397 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001398 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1399 break;
1400 }
1401 case Instruction::IGET_BYTE: {
1402 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001403 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1404 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001405 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1406 break;
1407 }
1408 case Instruction::IGET_CHAR: {
1409 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001410 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1411 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001412 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1413 break;
1414 }
1415 case Instruction::IGET_SHORT: {
1416 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001417 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1418 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001419 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1420 break;
1421 }
1422 case Instruction::IGET: {
1423 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001424 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1425 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001426 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1427 break;
1428 }
1429 case Instruction::IGET_WIDE: {
1430 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001431 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1432 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001433 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1434 break;
1435 }
1436 case Instruction::IGET_OBJECT: {
1437 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001438 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1439 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001440 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1441 break;
1442 }
1443 case Instruction::IGET_QUICK: {
1444 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001445 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001446 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1447 break;
1448 }
1449 case Instruction::IGET_WIDE_QUICK: {
1450 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001451 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001452 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1453 break;
1454 }
1455 case Instruction::IGET_OBJECT_QUICK: {
1456 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001457 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001458 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1459 break;
1460 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001461 case Instruction::IGET_BOOLEAN_QUICK: {
1462 PREAMBLE();
1463 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1464 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1465 break;
1466 }
1467 case Instruction::IGET_BYTE_QUICK: {
1468 PREAMBLE();
1469 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1470 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1471 break;
1472 }
1473 case Instruction::IGET_CHAR_QUICK: {
1474 PREAMBLE();
1475 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1476 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1477 break;
1478 }
1479 case Instruction::IGET_SHORT_QUICK: {
1480 PREAMBLE();
1481 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1482 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1483 break;
1484 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001485 case Instruction::SGET_BOOLEAN: {
1486 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001487 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check,
1488 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001489 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1490 break;
1491 }
1492 case Instruction::SGET_BYTE: {
1493 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001494 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check,
1495 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001496 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1497 break;
1498 }
1499 case Instruction::SGET_CHAR: {
1500 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001501 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check,
1502 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001503 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1504 break;
1505 }
1506 case Instruction::SGET_SHORT: {
1507 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001508 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check,
1509 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001510 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1511 break;
1512 }
1513 case Instruction::SGET: {
1514 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001515 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check,
1516 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001517 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1518 break;
1519 }
1520 case Instruction::SGET_WIDE: {
1521 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001522 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check,
1523 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001524 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1525 break;
1526 }
1527 case Instruction::SGET_OBJECT: {
1528 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001529 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check,
1530 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001531 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1532 break;
1533 }
1534 case Instruction::IPUT_BOOLEAN: {
1535 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001536 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1537 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001538 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1539 break;
1540 }
1541 case Instruction::IPUT_BYTE: {
1542 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001543 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1544 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001545 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1546 break;
1547 }
1548 case Instruction::IPUT_CHAR: {
1549 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001550 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1551 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001552 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1553 break;
1554 }
1555 case Instruction::IPUT_SHORT: {
1556 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001557 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1558 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001559 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1560 break;
1561 }
1562 case Instruction::IPUT: {
1563 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001564 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1565 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001566 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1567 break;
1568 }
1569 case Instruction::IPUT_WIDE: {
1570 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001571 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1572 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001573 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1574 break;
1575 }
1576 case Instruction::IPUT_OBJECT: {
1577 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001578 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1579 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001580 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1581 break;
1582 }
1583 case Instruction::IPUT_QUICK: {
1584 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001585 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1586 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001587 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1588 break;
1589 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001590 case Instruction::IPUT_BOOLEAN_QUICK: {
1591 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001592 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1593 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001594 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1595 break;
1596 }
1597 case Instruction::IPUT_BYTE_QUICK: {
1598 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001599 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1600 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001601 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1602 break;
1603 }
1604 case Instruction::IPUT_CHAR_QUICK: {
1605 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001606 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1607 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001608 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1609 break;
1610 }
1611 case Instruction::IPUT_SHORT_QUICK: {
1612 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001613 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1614 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001615 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1616 break;
1617 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001618 case Instruction::IPUT_WIDE_QUICK: {
1619 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001620 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1621 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001622 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1623 break;
1624 }
1625 case Instruction::IPUT_OBJECT_QUICK: {
1626 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001627 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1628 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001629 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1630 break;
1631 }
1632 case Instruction::SPUT_BOOLEAN: {
1633 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001634 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1635 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001636 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1637 break;
1638 }
1639 case Instruction::SPUT_BYTE: {
1640 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001641 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1642 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001643 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1644 break;
1645 }
1646 case Instruction::SPUT_CHAR: {
1647 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001648 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1649 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001650 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1651 break;
1652 }
1653 case Instruction::SPUT_SHORT: {
1654 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001655 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1656 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001657 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1658 break;
1659 }
1660 case Instruction::SPUT: {
1661 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001662 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1663 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001664 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1665 break;
1666 }
1667 case Instruction::SPUT_WIDE: {
1668 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001669 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1670 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001671 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1672 break;
1673 }
1674 case Instruction::SPUT_OBJECT: {
1675 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001676 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1677 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001678 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1679 break;
1680 }
1681 case Instruction::INVOKE_VIRTUAL: {
1682 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001683 bool success = DoInvoke<kVirtual, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001684 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001685 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001686 break;
1687 }
1688 case Instruction::INVOKE_VIRTUAL_RANGE: {
1689 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001690 bool success = DoInvoke<kVirtual, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001691 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001692 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001693 break;
1694 }
1695 case Instruction::INVOKE_SUPER: {
1696 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001697 bool success = DoInvoke<kSuper, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001698 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001699 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001700 break;
1701 }
1702 case Instruction::INVOKE_SUPER_RANGE: {
1703 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001704 bool success = DoInvoke<kSuper, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001705 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001706 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001707 break;
1708 }
1709 case Instruction::INVOKE_DIRECT: {
1710 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001711 bool success = DoInvoke<kDirect, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001712 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001713 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001714 break;
1715 }
1716 case Instruction::INVOKE_DIRECT_RANGE: {
1717 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001718 bool success = DoInvoke<kDirect, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001719 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001720 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001721 break;
1722 }
1723 case Instruction::INVOKE_INTERFACE: {
1724 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001725 bool success = DoInvoke<kInterface, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001726 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001727 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001728 break;
1729 }
1730 case Instruction::INVOKE_INTERFACE_RANGE: {
1731 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001732 bool success = DoInvoke<kInterface, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001733 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001734 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001735 break;
1736 }
1737 case Instruction::INVOKE_STATIC: {
1738 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001739 bool success = DoInvoke<kStatic, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001740 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001741 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001742 break;
1743 }
1744 case Instruction::INVOKE_STATIC_RANGE: {
1745 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001746 bool success = DoInvoke<kStatic, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001747 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001748 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001749 break;
1750 }
1751 case Instruction::INVOKE_VIRTUAL_QUICK: {
1752 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001753 bool success = DoInvokeVirtualQuick<false>(
1754 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001755 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001756 break;
1757 }
1758 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1759 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001760 bool success = DoInvokeVirtualQuick<true>(
1761 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001762 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001763 break;
1764 }
Narayan Kamath9823e782016-08-03 12:46:58 +01001765 case Instruction::INVOKE_POLYMORPHIC: {
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= */ false>(
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;
1772 }
1773 case Instruction::INVOKE_POLYMORPHIC_RANGE: {
1774 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001775 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001776 bool success = DoInvokePolymorphic</* is_range= */ true>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001777 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001778 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
Narayan Kamath9823e782016-08-03 12:46:58 +01001779 break;
Narayan Kamath9823e782016-08-03 12:46:58 +01001780 }
Orion Hodsonc069a302017-01-18 09:23:12 +00001781 case Instruction::INVOKE_CUSTOM: {
1782 PREAMBLE();
1783 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001784 bool success = DoInvokeCustom</* is_range= */ false>(
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 }
1789 case Instruction::INVOKE_CUSTOM_RANGE: {
1790 PREAMBLE();
1791 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001792 bool success = DoInvokeCustom</* is_range= */ true>(
Orion Hodsonc069a302017-01-18 09:23:12 +00001793 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001794 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Orion Hodsonc069a302017-01-18 09:23:12 +00001795 break;
1796 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001797 case Instruction::NEG_INT:
1798 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001799 shadow_frame.SetVReg(
1800 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001801 inst = inst->Next_1xx();
1802 break;
1803 case Instruction::NOT_INT:
1804 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001805 shadow_frame.SetVReg(
1806 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001807 inst = inst->Next_1xx();
1808 break;
1809 case Instruction::NEG_LONG:
1810 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001811 shadow_frame.SetVRegLong(
1812 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001813 inst = inst->Next_1xx();
1814 break;
1815 case Instruction::NOT_LONG:
1816 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001817 shadow_frame.SetVRegLong(
1818 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001819 inst = inst->Next_1xx();
1820 break;
1821 case Instruction::NEG_FLOAT:
1822 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001823 shadow_frame.SetVRegFloat(
1824 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001825 inst = inst->Next_1xx();
1826 break;
1827 case Instruction::NEG_DOUBLE:
1828 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001829 shadow_frame.SetVRegDouble(
1830 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001831 inst = inst->Next_1xx();
1832 break;
1833 case Instruction::INT_TO_LONG:
1834 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001835 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1836 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001837 inst = inst->Next_1xx();
1838 break;
1839 case Instruction::INT_TO_FLOAT:
1840 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001841 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1842 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001843 inst = inst->Next_1xx();
1844 break;
1845 case Instruction::INT_TO_DOUBLE:
1846 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001847 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1848 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001849 inst = inst->Next_1xx();
1850 break;
1851 case Instruction::LONG_TO_INT:
1852 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001853 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1854 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001855 inst = inst->Next_1xx();
1856 break;
1857 case Instruction::LONG_TO_FLOAT:
1858 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001859 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1860 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001861 inst = inst->Next_1xx();
1862 break;
1863 case Instruction::LONG_TO_DOUBLE:
1864 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001865 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1866 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001867 inst = inst->Next_1xx();
1868 break;
1869 case Instruction::FLOAT_TO_INT: {
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 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001873 shadow_frame.SetVReg(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_LONG: {
1878 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001879 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001880 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001881 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001882 inst = inst->Next_1xx();
1883 break;
1884 }
1885 case Instruction::FLOAT_TO_DOUBLE:
1886 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001887 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1888 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001889 inst = inst->Next_1xx();
1890 break;
1891 case Instruction::DOUBLE_TO_INT: {
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 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001895 shadow_frame.SetVReg(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_LONG: {
1900 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001901 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001902 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001903 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001904 inst = inst->Next_1xx();
1905 break;
1906 }
1907 case Instruction::DOUBLE_TO_FLOAT:
1908 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001909 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1910 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001911 inst = inst->Next_1xx();
1912 break;
1913 case Instruction::INT_TO_BYTE:
1914 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001915 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1916 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001917 inst = inst->Next_1xx();
1918 break;
1919 case Instruction::INT_TO_CHAR:
1920 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001921 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1922 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001923 inst = inst->Next_1xx();
1924 break;
1925 case Instruction::INT_TO_SHORT:
1926 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001927 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1928 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001929 inst = inst->Next_1xx();
1930 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001931 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001932 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 SafeAdd(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;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001938 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001939 case Instruction::SUB_INT:
1940 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001941 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001942 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1943 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001944 inst = inst->Next_2xx();
1945 break;
1946 case Instruction::MUL_INT:
1947 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001948 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001949 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1950 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001951 inst = inst->Next_2xx();
1952 break;
1953 case Instruction::DIV_INT: {
1954 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001955 bool success = DoIntDivide(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::REM_INT: {
1962 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001963 bool success = DoIntRemainder(shadow_frame, 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()));
1966 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1967 break;
1968 }
1969 case Instruction::SHL_INT:
1970 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001971 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001972 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1973 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1974 inst = inst->Next_2xx();
1975 break;
1976 case Instruction::SHR_INT:
1977 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001978 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001979 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1980 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1981 inst = inst->Next_2xx();
1982 break;
1983 case Instruction::USHR_INT:
1984 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001985 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001986 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1987 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1988 inst = inst->Next_2xx();
1989 break;
1990 case Instruction::AND_INT:
1991 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001992 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001993 shadow_frame.GetVReg(inst->VRegB_23x()) &
1994 shadow_frame.GetVReg(inst->VRegC_23x()));
1995 inst = inst->Next_2xx();
1996 break;
1997 case Instruction::OR_INT:
1998 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001999 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002000 shadow_frame.GetVReg(inst->VRegB_23x()) |
2001 shadow_frame.GetVReg(inst->VRegC_23x()));
2002 inst = inst->Next_2xx();
2003 break;
2004 case Instruction::XOR_INT:
2005 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002006 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002007 shadow_frame.GetVReg(inst->VRegB_23x()) ^
2008 shadow_frame.GetVReg(inst->VRegC_23x()));
2009 inst = inst->Next_2xx();
2010 break;
2011 case Instruction::ADD_LONG:
2012 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002013 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002014 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
2015 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002016 inst = inst->Next_2xx();
2017 break;
2018 case Instruction::SUB_LONG:
2019 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002020 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002021 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
2022 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002023 inst = inst->Next_2xx();
2024 break;
2025 case Instruction::MUL_LONG:
2026 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002027 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002028 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
2029 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002030 inst = inst->Next_2xx();
2031 break;
2032 case Instruction::DIV_LONG:
2033 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002034 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002035 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002036 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002037 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
2038 break;
2039 case Instruction::REM_LONG:
2040 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002041 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002042 shadow_frame.GetVRegLong(inst->VRegB_23x()),
2043 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2044 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
2045 break;
2046 case Instruction::AND_LONG:
2047 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002048 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002049 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
2050 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2051 inst = inst->Next_2xx();
2052 break;
2053 case Instruction::OR_LONG:
2054 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002055 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002056 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
2057 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2058 inst = inst->Next_2xx();
2059 break;
2060 case Instruction::XOR_LONG:
2061 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002062 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002063 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
2064 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2065 inst = inst->Next_2xx();
2066 break;
2067 case Instruction::SHL_LONG:
2068 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002069 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002070 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
2071 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2072 inst = inst->Next_2xx();
2073 break;
2074 case Instruction::SHR_LONG:
2075 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002076 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002077 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
2078 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2079 inst = inst->Next_2xx();
2080 break;
2081 case Instruction::USHR_LONG:
2082 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002083 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002084 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
2085 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2086 inst = inst->Next_2xx();
2087 break;
2088 case Instruction::ADD_FLOAT:
2089 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002090 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002091 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
2092 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2093 inst = inst->Next_2xx();
2094 break;
2095 case Instruction::SUB_FLOAT:
2096 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002097 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002098 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
2099 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2100 inst = inst->Next_2xx();
2101 break;
2102 case Instruction::MUL_FLOAT:
2103 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002104 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002105 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
2106 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2107 inst = inst->Next_2xx();
2108 break;
2109 case Instruction::DIV_FLOAT:
2110 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002111 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002112 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
2113 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2114 inst = inst->Next_2xx();
2115 break;
2116 case Instruction::REM_FLOAT:
2117 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002118 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002119 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
2120 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
2121 inst = inst->Next_2xx();
2122 break;
2123 case Instruction::ADD_DOUBLE:
2124 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002125 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002126 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
2127 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2128 inst = inst->Next_2xx();
2129 break;
2130 case Instruction::SUB_DOUBLE:
2131 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002132 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002133 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
2134 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2135 inst = inst->Next_2xx();
2136 break;
2137 case Instruction::MUL_DOUBLE:
2138 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002139 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002140 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
2141 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2142 inst = inst->Next_2xx();
2143 break;
2144 case Instruction::DIV_DOUBLE:
2145 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002146 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002147 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2148 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2149 inst = inst->Next_2xx();
2150 break;
2151 case Instruction::REM_DOUBLE:
2152 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002153 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002154 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2155 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2156 inst = inst->Next_2xx();
2157 break;
2158 case Instruction::ADD_INT_2ADDR: {
2159 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002160 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07002161 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
2162 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002163 inst = inst->Next_1xx();
2164 break;
2165 }
2166 case Instruction::SUB_INT_2ADDR: {
2167 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002168 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002169 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002170 SafeSub(shadow_frame.GetVReg(vregA),
2171 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002172 inst = inst->Next_1xx();
2173 break;
2174 }
2175 case Instruction::MUL_INT_2ADDR: {
2176 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002177 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002178 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002179 SafeMul(shadow_frame.GetVReg(vregA),
2180 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002181 inst = inst->Next_1xx();
2182 break;
2183 }
2184 case Instruction::DIV_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 = DoIntDivide(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::REM_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 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002196 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002197 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2198 break;
2199 }
2200 case Instruction::SHL_INT_2ADDR: {
2201 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002202 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002203 shadow_frame.SetVReg(vregA,
2204 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002205 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002206 inst = inst->Next_1xx();
2207 break;
2208 }
2209 case Instruction::SHR_INT_2ADDR: {
2210 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002211 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002212 shadow_frame.SetVReg(vregA,
2213 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002214 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002215 inst = inst->Next_1xx();
2216 break;
2217 }
2218 case Instruction::USHR_INT_2ADDR: {
2219 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002220 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002221 shadow_frame.SetVReg(vregA,
2222 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002223 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002224 inst = inst->Next_1xx();
2225 break;
2226 }
2227 case Instruction::AND_INT_2ADDR: {
2228 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002229 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002230 shadow_frame.SetVReg(vregA,
2231 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002232 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002233 inst = inst->Next_1xx();
2234 break;
2235 }
2236 case Instruction::OR_INT_2ADDR: {
2237 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002238 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002239 shadow_frame.SetVReg(vregA,
2240 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002241 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002242 inst = inst->Next_1xx();
2243 break;
2244 }
2245 case Instruction::XOR_INT_2ADDR: {
2246 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002247 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002248 shadow_frame.SetVReg(vregA,
2249 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002250 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002251 inst = inst->Next_1xx();
2252 break;
2253 }
2254 case Instruction::ADD_LONG_2ADDR: {
2255 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002256 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002257 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002258 SafeAdd(shadow_frame.GetVRegLong(vregA),
2259 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002260 inst = inst->Next_1xx();
2261 break;
2262 }
2263 case Instruction::SUB_LONG_2ADDR: {
2264 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002265 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002266 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002267 SafeSub(shadow_frame.GetVRegLong(vregA),
2268 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002269 inst = inst->Next_1xx();
2270 break;
2271 }
2272 case Instruction::MUL_LONG_2ADDR: {
2273 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002274 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002275 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002276 SafeMul(shadow_frame.GetVRegLong(vregA),
2277 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002278 inst = inst->Next_1xx();
2279 break;
2280 }
2281 case Instruction::DIV_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 DoLongDivide(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::REM_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 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002293 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002294 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2295 break;
2296 }
2297 case Instruction::AND_LONG_2ADDR: {
2298 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002299 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002300 shadow_frame.SetVRegLong(vregA,
2301 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002302 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002303 inst = inst->Next_1xx();
2304 break;
2305 }
2306 case Instruction::OR_LONG_2ADDR: {
2307 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002308 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002309 shadow_frame.SetVRegLong(vregA,
2310 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002311 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002312 inst = inst->Next_1xx();
2313 break;
2314 }
2315 case Instruction::XOR_LONG_2ADDR: {
2316 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002317 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002318 shadow_frame.SetVRegLong(vregA,
2319 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002320 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002321 inst = inst->Next_1xx();
2322 break;
2323 }
2324 case Instruction::SHL_LONG_2ADDR: {
2325 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002326 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002327 shadow_frame.SetVRegLong(vregA,
2328 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002329 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002330 inst = inst->Next_1xx();
2331 break;
2332 }
2333 case Instruction::SHR_LONG_2ADDR: {
2334 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002335 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002336 shadow_frame.SetVRegLong(vregA,
2337 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002338 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002339 inst = inst->Next_1xx();
2340 break;
2341 }
2342 case Instruction::USHR_LONG_2ADDR: {
2343 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002344 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002345 shadow_frame.SetVRegLong(vregA,
2346 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002347 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002348 inst = inst->Next_1xx();
2349 break;
2350 }
2351 case Instruction::ADD_FLOAT_2ADDR: {
2352 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002353 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002354 shadow_frame.SetVRegFloat(vregA,
2355 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002356 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002357 inst = inst->Next_1xx();
2358 break;
2359 }
2360 case Instruction::SUB_FLOAT_2ADDR: {
2361 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002362 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002363 shadow_frame.SetVRegFloat(vregA,
2364 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002365 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002366 inst = inst->Next_1xx();
2367 break;
2368 }
2369 case Instruction::MUL_FLOAT_2ADDR: {
2370 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002371 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002372 shadow_frame.SetVRegFloat(vregA,
2373 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002374 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002375 inst = inst->Next_1xx();
2376 break;
2377 }
2378 case Instruction::DIV_FLOAT_2ADDR: {
2379 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002380 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002381 shadow_frame.SetVRegFloat(vregA,
2382 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002383 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002384 inst = inst->Next_1xx();
2385 break;
2386 }
2387 case Instruction::REM_FLOAT_2ADDR: {
2388 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002389 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002390 shadow_frame.SetVRegFloat(vregA,
2391 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002392 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002393 inst = inst->Next_1xx();
2394 break;
2395 }
2396 case Instruction::ADD_DOUBLE_2ADDR: {
2397 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002398 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002399 shadow_frame.SetVRegDouble(vregA,
2400 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002401 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002402 inst = inst->Next_1xx();
2403 break;
2404 }
2405 case Instruction::SUB_DOUBLE_2ADDR: {
2406 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002407 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002408 shadow_frame.SetVRegDouble(vregA,
2409 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002410 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002411 inst = inst->Next_1xx();
2412 break;
2413 }
2414 case Instruction::MUL_DOUBLE_2ADDR: {
2415 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002416 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002417 shadow_frame.SetVRegDouble(vregA,
2418 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002419 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002420 inst = inst->Next_1xx();
2421 break;
2422 }
2423 case Instruction::DIV_DOUBLE_2ADDR: {
2424 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002425 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002426 shadow_frame.SetVRegDouble(vregA,
2427 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002428 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002429 inst = inst->Next_1xx();
2430 break;
2431 }
2432 case Instruction::REM_DOUBLE_2ADDR: {
2433 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002434 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002435 shadow_frame.SetVRegDouble(vregA,
2436 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002437 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002438 inst = inst->Next_1xx();
2439 break;
2440 }
2441 case Instruction::ADD_INT_LIT16:
2442 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002443 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002444 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2445 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002446 inst = inst->Next_2xx();
2447 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002448 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002449 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002450 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002451 SafeSub(inst->VRegC_22s(),
2452 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002453 inst = inst->Next_2xx();
2454 break;
2455 case Instruction::MUL_INT_LIT16:
2456 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002457 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002458 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2459 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002460 inst = inst->Next_2xx();
2461 break;
2462 case Instruction::DIV_INT_LIT16: {
2463 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002464 bool success = DoIntDivide(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::REM_INT_LIT16: {
2471 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002472 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002473 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2474 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002475 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2476 break;
2477 }
2478 case Instruction::AND_INT_LIT16:
2479 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002480 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2481 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002482 inst->VRegC_22s());
2483 inst = inst->Next_2xx();
2484 break;
2485 case Instruction::OR_INT_LIT16:
2486 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002487 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2488 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002489 inst->VRegC_22s());
2490 inst = inst->Next_2xx();
2491 break;
2492 case Instruction::XOR_INT_LIT16:
2493 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002494 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2495 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002496 inst->VRegC_22s());
2497 inst = inst->Next_2xx();
2498 break;
2499 case Instruction::ADD_INT_LIT8:
2500 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002501 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002502 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002503 inst = inst->Next_2xx();
2504 break;
2505 case Instruction::RSUB_INT_LIT8:
2506 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002507 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002508 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002509 inst = inst->Next_2xx();
2510 break;
2511 case Instruction::MUL_INT_LIT8:
2512 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002513 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002514 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002515 inst = inst->Next_2xx();
2516 break;
2517 case Instruction::DIV_INT_LIT8: {
2518 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002519 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002520 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2521 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2522 break;
2523 }
2524 case Instruction::REM_INT_LIT8: {
2525 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002526 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002527 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2528 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2529 break;
2530 }
2531 case Instruction::AND_INT_LIT8:
2532 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002533 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002534 shadow_frame.GetVReg(inst->VRegB_22b()) &
2535 inst->VRegC_22b());
2536 inst = inst->Next_2xx();
2537 break;
2538 case Instruction::OR_INT_LIT8:
2539 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002540 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002541 shadow_frame.GetVReg(inst->VRegB_22b()) |
2542 inst->VRegC_22b());
2543 inst = inst->Next_2xx();
2544 break;
2545 case Instruction::XOR_INT_LIT8:
2546 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002547 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002548 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2549 inst->VRegC_22b());
2550 inst = inst->Next_2xx();
2551 break;
2552 case Instruction::SHL_INT_LIT8:
2553 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002554 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002555 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2556 (inst->VRegC_22b() & 0x1f));
2557 inst = inst->Next_2xx();
2558 break;
2559 case Instruction::SHR_INT_LIT8:
2560 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002561 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002562 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2563 (inst->VRegC_22b() & 0x1f));
2564 inst = inst->Next_2xx();
2565 break;
2566 case Instruction::USHR_INT_LIT8:
2567 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002568 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002569 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2570 (inst->VRegC_22b() & 0x1f));
2571 inst = inst->Next_2xx();
2572 break;
2573 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Orion Hodson2e599942017-09-22 16:17:41 +01002574 case Instruction::UNUSED_79 ... Instruction::UNUSED_7A:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002575 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
Ian Rogerse94652f2014-12-02 11:13:19 -08002576 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002577 }
buzbee1452bee2015-03-06 14:43:04 -08002578 } while (!interpret_one_instruction);
2579 // Record where we stopped.
2580 shadow_frame.SetDexPC(inst->GetDexPc(insns));
David Srbecky946bb092018-03-09 17:23:01 +00002581 ctx->result = result_register;
2582 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002583} // NOLINT(readability/fn_size)
2584
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002585} // namespace interpreter
2586} // namespace art
David Srbecky2ee09ff2018-10-24 13:24:22 +01002587
2588#endif // ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_