blob: d9f76eee6e170424e5037b525d66f850d54f95be [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Gampe5e26eb12016-08-22 17:54:17 -070017#include "interpreter_switch_impl.h"
18
Andreas Gampe542451c2016-07-26 09:02:02 -070019#include "base/enums.h"
Alex Light6f22e062018-10-05 15:05:12 -070020#include "base/memory_tool.h"
David Sehrc431b9d2018-03-02 12:01:51 -080021#include "base/quasi_atomic.h"
David Sehr9e734c72018-01-04 17:56:19 -080022#include "dex/dex_file_types.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070023#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020024#include "interpreter_common.h"
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000025#include "jit/jit.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070026#include "jvalue-inl.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000027#include "nth_caller_visitor.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070028#include "safe_math.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010029#include "shadow_frame-inl.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000030#include "thread.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020031
32namespace art {
33namespace interpreter {
34
Alex Light0aa7a5a2018-10-10 15:58:14 +000035#define CHECK_FORCE_RETURN() \
36 do { \
37 if (UNLIKELY(shadow_frame.GetForcePopFrame())) { \
38 DCHECK(PrevFrameWillRetry(self, shadow_frame)) \
39 << "Pop frame forced without previous frame ready to retry instruction!"; \
40 DCHECK(Runtime::Current()->AreNonStandardExitsEnabled()); \
41 if (UNLIKELY(NeedsMethodExitEvent(instrumentation))) { \
42 SendMethodExitEvents(self, \
43 instrumentation, \
44 shadow_frame, \
45 shadow_frame.GetThisObject(accessor.InsSize()), \
46 shadow_frame.GetMethod(), \
47 inst->GetDexPc(insns), \
48 JValue()); \
49 } \
50 ctx->result = JValue(); /* Handled in caller. */ \
51 return; \
52 } \
53 } while (false)
54
Alex Lightb7edcda2017-04-27 13:20:31 -070055#define HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instr) \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020056 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020057 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070058 self->AllowThreadSuspension(); \
Alex Light0aa7a5a2018-10-10 15:58:14 +000059 CHECK_FORCE_RETURN(); \
Alex Light9fb1ab12017-09-05 09:32:49 -070060 if (!MoveToExceptionHandler(self, shadow_frame, instr)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070061 /* Structured locking is to be enforced for abnormal termination, too. */ \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070062 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame); \
buzbee1452bee2015-03-06 14:43:04 -080063 if (interpret_one_instruction) { \
buzbee93e94f22016-04-07 13:52:48 -070064 /* Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -070065 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee1452bee2015-03-06 14:43:04 -080066 } \
David Srbecky946bb092018-03-09 17:23:01 +000067 ctx->result = JValue(); /* Handled in caller. */ \
68 return; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020069 } else { \
Alex Light0aa7a5a2018-10-10 15:58:14 +000070 CHECK_FORCE_RETURN(); \
Alex Light9fb1ab12017-09-05 09:32:49 -070071 int32_t displacement = \
72 static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020073 inst = inst->RelativeAt(displacement); \
74 } \
75 } while (false)
76
Alex Lightb7edcda2017-04-27 13:20:31 -070077#define HANDLE_PENDING_EXCEPTION() HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instrumentation)
78
Alex Light0aa7a5a2018-10-10 15:58:14 +000079#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, _next_function) \
80 do { \
81 if (UNLIKELY(shadow_frame.GetForceRetryInstruction())) { \
82 /* Don't need to do anything except clear the flag and exception. We leave the */ \
83 /* instruction the same so it will be re-executed on the next go-around. */ \
84 DCHECK(inst->IsInvoke()); \
85 shadow_frame.SetForceRetryInstruction(false); \
86 if (UNLIKELY(_is_exception_pending)) { \
87 DCHECK(self->IsExceptionPending()); \
88 if (kIsDebugBuild) { \
89 LOG(WARNING) << "Suppressing exception for instruction-retry: " \
90 << self->GetException()->Dump(); \
91 } \
92 self->ClearException(); \
93 } \
94 } else if (UNLIKELY(_is_exception_pending)) { \
95 /* Should have succeeded. */ \
96 DCHECK(!shadow_frame.GetForceRetryInstruction()); \
97 HANDLE_PENDING_EXCEPTION(); \
98 } else { \
99 inst = inst->_next_function(); \
100 } \
101 } while (false)
102
103#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(_is_exception_pending) \
104 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, Next_4xx)
105#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(_is_exception_pending) \
106 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, Next_3xx)
107
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200108#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
109 do { \
Alex Light0aa7a5a2018-10-10 15:58:14 +0000110 /* Should only be on invoke instructions. */ \
111 DCHECK(!shadow_frame.GetForceRetryInstruction()); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200112 if (UNLIKELY(_is_exception_pending)) { \
113 HANDLE_PENDING_EXCEPTION(); \
114 } else { \
115 inst = inst->_next_function(); \
116 } \
117 } while (false)
118
Andreas Gampe03ec9302015-08-27 17:41:47 -0700119#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -0700120 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -0700121 HANDLE_PENDING_EXCEPTION(); \
122 }
123
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200124// Code to run before each dex instruction.
Alex Light0aa7a5a2018-10-10 15:58:14 +0000125#define PREAMBLE_SAVE(save_ref) \
Alex Lightfc905672017-06-27 17:53:15 -0700126 { \
Alex Light0aa7a5a2018-10-10 15:58:14 +0000127 /* We need to put this before & after the instrumentation to avoid having to put in a */ \
128 /* post-script macro. */ \
129 CHECK_FORCE_RETURN(); \
130 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
131 if (UNLIKELY(!DoDexPcMoveEvent(self, \
132 accessor, \
133 shadow_frame, \
134 dex_pc, \
135 instrumentation, \
136 save_ref))) { \
137 HANDLE_PENDING_EXCEPTION(); \
138 break; \
139 } \
140 CHECK_FORCE_RETURN(); \
Sebastien Hertz8379b222014-02-24 17:38:15 +0100141 } \
Alex Lightfc905672017-06-27 17:53:15 -0700142 } \
143 do {} while (false)
144
145#define PREAMBLE() PREAMBLE_SAVE(nullptr)
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200146
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000147#define BRANCH_INSTRUMENTATION(offset) \
148 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100149 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
Alex Lightcc917d92018-02-22 13:28:28 -0800150 instrumentation->Branch(self, shadow_frame.GetMethod(), dex_pc, offset); \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100151 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000152 JValue result; \
Alex Lightcc917d92018-02-22 13:28:28 -0800153 if (jit::Jit::MaybeDoOnStackReplacement(self, \
154 shadow_frame.GetMethod(), \
155 dex_pc, \
156 offset, \
157 &result)) { \
buzbee93e94f22016-04-07 13:52:48 -0700158 if (interpret_one_instruction) { \
159 /* OSR has completed execution of the method. Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -0700160 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee93e94f22016-04-07 13:52:48 -0700161 } \
David Srbecky946bb092018-03-09 17:23:01 +0000162 ctx->result = result; \
163 return; \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000164 } \
Nicolas Geoffray3108daf2015-11-24 16:32:33 +0000165 } while (false)
166
Bill Buzbee1d011d92016-04-04 16:59:29 +0000167#define HOTNESS_UPDATE() \
168 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100169 if (jit != nullptr) { \
Alex Lightcc917d92018-02-22 13:28:28 -0800170 jit->AddSamples(self, shadow_frame.GetMethod(), 1, /*with_backedges*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +0000171 } \
172 } while (false)
173
Alex Light848574c2017-09-25 16:59:39 -0700174#define HANDLE_ASYNC_EXCEPTION() \
175 if (UNLIKELY(self->ObserveAsyncException())) { \
176 HANDLE_PENDING_EXCEPTION(); \
177 break; \
178 } \
179 do {} while (false)
180
Andreas Gampef4f76372016-12-13 14:43:58 -0800181#define HANDLE_BACKWARD_BRANCH(offset) \
182 do { \
183 if (IsBackwardBranch(offset)) { \
184 HOTNESS_UPDATE(); \
185 /* Record new dex pc early to have consistent suspend point at loop header. */ \
186 shadow_frame.SetDexPC(inst->GetDexPc(insns)); \
187 self->AllowThreadSuspension(); \
188 } \
189 } while (false)
190
Alex Lightfc905672017-06-27 17:53:15 -0700191// Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
192// the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
193// to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
194// jvmti-agents while handling breakpoint or single step events. We had to move this into its own
195// function because it was making ExecuteSwitchImpl have too large a stack.
Alex Light2989a4a2017-06-29 09:44:57 -0700196NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800197 const CodeItemDataAccessor& accessor,
Alex Light2989a4a2017-06-29 09:44:57 -0700198 const ShadowFrame& shadow_frame,
199 uint32_t dex_pc,
200 const instrumentation::Instrumentation* instrumentation,
201 JValue* save_ref)
Alex Lightfc905672017-06-27 17:53:15 -0700202 REQUIRES_SHARED(Locks::mutator_lock_) {
203 DCHECK(instrumentation->HasDexPcListeners());
204 StackHandleScope<2> hs(self);
205 Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
206 mirror::Object* null_obj = nullptr;
207 HandleWrapper<mirror::Object> h(
208 hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
209 self->ClearException();
210 instrumentation->DexPcMovedEvent(self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800211 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lightfc905672017-06-27 17:53:15 -0700212 shadow_frame.GetMethod(),
213 dex_pc);
214 if (UNLIKELY(self->IsExceptionPending())) {
215 // We got a new exception in the dex-pc-moved event. We just let this exception replace the old
216 // one.
217 // TODO It would be good to add the old exception to the suppressed exceptions of the new one if
218 // possible.
219 return false;
220 } else {
221 if (UNLIKELY(!thr.IsNull())) {
222 self->SetException(thr.Get());
223 }
224 return true;
225 }
226}
227
Alex Lighte814f9d2017-07-31 16:14:39 -0700228static bool NeedsMethodExitEvent(const instrumentation::Instrumentation* ins)
229 REQUIRES_SHARED(Locks::mutator_lock_) {
230 return ins->HasMethodExitListeners() || ins->HasWatchedFramePopListeners();
231}
232
233// Sends the normal method exit event. Returns true if the events succeeded and false if there is a
234// pending exception.
235NO_INLINE static bool SendMethodExitEvents(Thread* self,
236 const instrumentation::Instrumentation* instrumentation,
237 const ShadowFrame& frame,
238 ObjPtr<mirror::Object> thiz,
239 ArtMethod* method,
240 uint32_t dex_pc,
241 const JValue& result)
242 REQUIRES_SHARED(Locks::mutator_lock_) {
243 bool had_event = false;
Alex Light0aa7a5a2018-10-10 15:58:14 +0000244 // We don't send method-exit if it's a pop-frame. We still send frame_popped though.
245 if (UNLIKELY(instrumentation->HasMethodExitListeners() && !frame.GetForcePopFrame())) {
Alex Lighte814f9d2017-07-31 16:14:39 -0700246 had_event = true;
247 instrumentation->MethodExitEvent(self, thiz.Ptr(), method, dex_pc, result);
248 }
249 if (UNLIKELY(frame.NeedsNotifyPop() && instrumentation->HasWatchedFramePopListeners())) {
250 had_event = true;
251 instrumentation->WatchedFramePopped(self, frame);
252 }
253 if (UNLIKELY(had_event)) {
254 return !self->IsExceptionPending();
255 } else {
256 return true;
257 }
258}
259
Alex Light6f22e062018-10-05 15:05:12 -0700260// TODO On ASAN builds this function gets a huge stack frame. Since normally we run in the mterp
261// this shouldn't cause any problems for stack overflow detection. Remove this once b/117341496 is
262// fixed.
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100263template<bool do_access_check, bool transaction_active>
Alex Light6f22e062018-10-05 15:05:12 -0700264ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
David Srbecky946bb092018-03-09 17:23:01 +0000265 Thread* self = ctx->self;
266 const CodeItemDataAccessor& accessor = ctx->accessor;
267 ShadowFrame& shadow_frame = ctx->shadow_frame;
268 JValue result_register = ctx->result_register;
269 bool interpret_one_instruction = ctx->interpret_one_instruction;
Igor Murashkinc449e8b2015-06-10 15:56:42 -0700270 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200271 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
272 LOG(FATAL) << "Invalid shadow frame for interpreter use";
David Srbecky946bb092018-03-09 17:23:01 +0000273 ctx->result = JValue();
274 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200275 }
276 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200277
278 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700279 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800280 const uint16_t* const insns = accessor.Insns();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200281 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200282 uint16_t inst_data;
Bill Buzbee1d011d92016-04-04 16:59:29 +0000283 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700284
Alex Light0aa7a5a2018-10-10 15:58:14 +0000285 DCHECK(!shadow_frame.GetForceRetryInstruction())
286 << "Entered interpreter from invoke without retry instruction being handled!";
287
buzbee1452bee2015-03-06 14:43:04 -0800288 do {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200289 dex_pc = inst->GetDexPc(insns);
290 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800291 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200292 inst_data = inst->Fetch16(0);
293 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200294 case Instruction::NOP:
295 PREAMBLE();
296 inst = inst->Next_1xx();
297 break;
298 case Instruction::MOVE:
299 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200300 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
301 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200302 inst = inst->Next_1xx();
303 break;
304 case Instruction::MOVE_FROM16:
305 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200306 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200307 shadow_frame.GetVReg(inst->VRegB_22x()));
308 inst = inst->Next_2xx();
309 break;
310 case Instruction::MOVE_16:
311 PREAMBLE();
312 shadow_frame.SetVReg(inst->VRegA_32x(),
313 shadow_frame.GetVReg(inst->VRegB_32x()));
314 inst = inst->Next_3xx();
315 break;
316 case Instruction::MOVE_WIDE:
317 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200318 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
319 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200320 inst = inst->Next_1xx();
321 break;
322 case Instruction::MOVE_WIDE_FROM16:
323 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200324 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200325 shadow_frame.GetVRegLong(inst->VRegB_22x()));
326 inst = inst->Next_2xx();
327 break;
328 case Instruction::MOVE_WIDE_16:
329 PREAMBLE();
330 shadow_frame.SetVRegLong(inst->VRegA_32x(),
331 shadow_frame.GetVRegLong(inst->VRegB_32x()));
332 inst = inst->Next_3xx();
333 break;
334 case Instruction::MOVE_OBJECT:
335 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200336 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
337 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200338 inst = inst->Next_1xx();
339 break;
340 case Instruction::MOVE_OBJECT_FROM16:
341 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200342 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200343 shadow_frame.GetVRegReference(inst->VRegB_22x()));
344 inst = inst->Next_2xx();
345 break;
346 case Instruction::MOVE_OBJECT_16:
347 PREAMBLE();
348 shadow_frame.SetVRegReference(inst->VRegA_32x(),
349 shadow_frame.GetVRegReference(inst->VRegB_32x()));
350 inst = inst->Next_3xx();
351 break;
352 case Instruction::MOVE_RESULT:
353 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200354 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200355 inst = inst->Next_1xx();
356 break;
357 case Instruction::MOVE_RESULT_WIDE:
358 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200359 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200360 inst = inst->Next_1xx();
361 break;
362 case Instruction::MOVE_RESULT_OBJECT:
Alex Lightfc905672017-06-27 17:53:15 -0700363 PREAMBLE_SAVE(&result_register);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200364 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200365 inst = inst->Next_1xx();
366 break;
367 case Instruction::MOVE_EXCEPTION: {
368 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700369 ObjPtr<mirror::Throwable> exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100370 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100371 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200372 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200373 inst = inst->Next_1xx();
374 break;
375 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700376 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200377 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200378 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700379 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700380 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700381 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
382 !SendMethodExitEvents(self,
383 instrumentation,
384 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800385 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700386 shadow_frame.GetMethod(),
387 inst->GetDexPc(insns),
388 result))) {
389 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200390 }
buzbee1452bee2015-03-06 14:43:04 -0800391 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700392 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700393 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800394 }
David Srbecky946bb092018-03-09 17:23:01 +0000395 ctx->result = result;
396 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200397 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700398 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200399 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700400 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200401 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700402 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700403 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700404 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
405 !SendMethodExitEvents(self,
406 instrumentation,
407 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800408 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700409 shadow_frame.GetMethod(),
410 inst->GetDexPc(insns),
411 result))) {
412 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200413 }
buzbee1452bee2015-03-06 14:43:04 -0800414 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700415 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700416 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800417 }
David Srbecky946bb092018-03-09 17:23:01 +0000418 ctx->result = result;
419 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200420 }
421 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200422 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200423 JValue result;
424 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200425 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700426 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700427 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700428 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
429 !SendMethodExitEvents(self,
430 instrumentation,
431 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800432 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700433 shadow_frame.GetMethod(),
434 inst->GetDexPc(insns),
435 result))) {
436 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200437 }
buzbee1452bee2015-03-06 14:43:04 -0800438 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700439 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700440 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800441 }
David Srbecky946bb092018-03-09 17:23:01 +0000442 ctx->result = result;
443 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200444 }
445 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200446 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200447 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200448 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700449 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700450 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700451 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
452 !SendMethodExitEvents(self,
453 instrumentation,
454 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800455 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700456 shadow_frame.GetMethod(),
457 inst->GetDexPc(insns),
458 result))) {
459 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200460 }
buzbee1452bee2015-03-06 14:43:04 -0800461 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700462 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700463 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800464 }
David Srbecky946bb092018-03-09 17:23:01 +0000465 ctx->result = result;
466 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200467 }
468 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200469 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200470 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700471 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700472 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700473 const size_t ref_idx = inst->VRegA_11x(inst_data);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700474 ObjPtr<mirror::Object> obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700475 if (do_assignability_check && obj_result != nullptr) {
Alex Lightcc917d92018-02-22 13:28:28 -0800476 ObjPtr<mirror::Class> return_type = shadow_frame.GetMethod()->ResolveReturnType();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700477 // Re-load since it might have moved.
478 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700479 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700480 // Return the pending exception.
481 HANDLE_PENDING_EXCEPTION();
482 }
483 if (!obj_result->VerifierInstanceOf(return_type)) {
484 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700485 std::string temp1, temp2;
Orion Hodsonfef06642016-11-25 16:07:11 +0000486 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700487 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700488 obj_result->GetClass()->GetDescriptor(&temp1),
489 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700490 HANDLE_PENDING_EXCEPTION();
491 }
492 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700493 result.SetL(obj_result);
Alex Lighte814f9d2017-07-31 16:14:39 -0700494 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
495 !SendMethodExitEvents(self,
496 instrumentation,
497 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800498 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700499 shadow_frame.GetMethod(),
500 inst->GetDexPc(insns),
501 result))) {
502 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200503 }
Alex Lighte814f9d2017-07-31 16:14:39 -0700504 // Re-load since it might have moved during the MethodExitEvent.
505 result.SetL(shadow_frame.GetVRegReference(ref_idx));
buzbee1452bee2015-03-06 14:43:04 -0800506 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700507 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700508 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800509 }
David Srbecky946bb092018-03-09 17:23:01 +0000510 ctx->result = result;
511 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200512 }
513 case Instruction::CONST_4: {
514 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200515 uint4_t dst = inst->VRegA_11n(inst_data);
516 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200517 shadow_frame.SetVReg(dst, val);
518 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700519 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200520 }
521 inst = inst->Next_1xx();
522 break;
523 }
524 case Instruction::CONST_16: {
525 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200526 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200527 int16_t val = inst->VRegB_21s();
528 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_2xx();
533 break;
534 }
535 case Instruction::CONST: {
536 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200537 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200538 int32_t val = inst->VRegB_31i();
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_3xx();
544 break;
545 }
546 case Instruction::CONST_HIGH16: {
547 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200548 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200549 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
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_2xx();
555 break;
556 }
557 case Instruction::CONST_WIDE_16:
558 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200559 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200560 inst = inst->Next_2xx();
561 break;
562 case Instruction::CONST_WIDE_32:
563 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200564 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200565 inst = inst->Next_3xx();
566 break;
567 case Instruction::CONST_WIDE:
568 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200569 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200570 inst = inst->Next_51l();
571 break;
572 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200573 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200574 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200575 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
576 inst = inst->Next_2xx();
577 break;
578 case Instruction::CONST_STRING: {
579 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800580 ObjPtr<mirror::String> s = ResolveString(self,
581 shadow_frame,
582 dex::StringIndex(inst->VRegB_21c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700583 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200584 HANDLE_PENDING_EXCEPTION();
585 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100586 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200587 inst = inst->Next_2xx();
588 }
589 break;
590 }
591 case Instruction::CONST_STRING_JUMBO: {
592 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800593 ObjPtr<mirror::String> s = ResolveString(self,
594 shadow_frame,
595 dex::StringIndex(inst->VRegB_31c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700596 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200597 HANDLE_PENDING_EXCEPTION();
598 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100599 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200600 inst = inst->Next_3xx();
601 }
602 break;
603 }
604 case Instruction::CONST_CLASS: {
605 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800606 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700607 shadow_frame.GetMethod(),
608 self,
609 false,
610 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700611 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200612 HANDLE_PENDING_EXCEPTION();
613 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100614 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200615 inst = inst->Next_2xx();
616 }
617 break;
618 }
Orion Hodson2e599942017-09-22 16:17:41 +0100619 case Instruction::CONST_METHOD_HANDLE: {
620 PREAMBLE();
Orion Hodsone7732be2017-10-11 14:35:20 +0100621 ClassLinker* cl = Runtime::Current()->GetClassLinker();
Alex Lightcc917d92018-02-22 13:28:28 -0800622 ObjPtr<mirror::MethodHandle> mh = cl->ResolveMethodHandle(self,
623 inst->VRegB_21c(),
624 shadow_frame.GetMethod());
Orion Hodson2e599942017-09-22 16:17:41 +0100625 if (UNLIKELY(mh == nullptr)) {
626 HANDLE_PENDING_EXCEPTION();
627 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100628 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mh);
Orion Hodson2e599942017-09-22 16:17:41 +0100629 inst = inst->Next_2xx();
630 }
631 break;
632 }
633 case Instruction::CONST_METHOD_TYPE: {
634 PREAMBLE();
Orion Hodsone7732be2017-10-11 14:35:20 +0100635 ClassLinker* cl = Runtime::Current()->GetClassLinker();
Alex Lightcc917d92018-02-22 13:28:28 -0800636 ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(self,
Orion Hodson06d10a72018-05-14 08:53:38 +0100637 dex::ProtoIndex(inst->VRegB_21c()),
Alex Lightcc917d92018-02-22 13:28:28 -0800638 shadow_frame.GetMethod());
Orion Hodson2e599942017-09-22 16:17:41 +0100639 if (UNLIKELY(mt == nullptr)) {
640 HANDLE_PENDING_EXCEPTION();
641 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100642 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mt);
Orion Hodson2e599942017-09-22 16:17:41 +0100643 inst = inst->Next_2xx();
644 }
645 break;
646 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200647 case Instruction::MONITOR_ENTER: {
648 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700649 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700650 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700651 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000652 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200653 HANDLE_PENDING_EXCEPTION();
654 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700655 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200656 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
657 }
658 break;
659 }
660 case Instruction::MONITOR_EXIT: {
661 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700662 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700663 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700664 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000665 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200666 HANDLE_PENDING_EXCEPTION();
667 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700668 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200669 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
670 }
671 break;
672 }
673 case Instruction::CHECK_CAST: {
674 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800675 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700676 shadow_frame.GetMethod(),
677 self,
678 false,
679 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700680 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200681 HANDLE_PENDING_EXCEPTION();
682 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700683 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700684 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200685 ThrowClassCastException(c, obj->GetClass());
686 HANDLE_PENDING_EXCEPTION();
687 } else {
688 inst = inst->Next_2xx();
689 }
690 }
691 break;
692 }
693 case Instruction::INSTANCE_OF: {
694 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800695 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegC_22c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700696 shadow_frame.GetMethod(),
697 self,
698 false,
699 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700700 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200701 HANDLE_PENDING_EXCEPTION();
702 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700703 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700704 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
705 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200706 inst = inst->Next_2xx();
707 }
708 break;
709 }
710 case Instruction::ARRAY_LENGTH: {
711 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700712 ObjPtr<mirror::Object> array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700713 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000714 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200715 HANDLE_PENDING_EXCEPTION();
716 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200717 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200718 inst = inst->Next_1xx();
719 }
720 break;
721 }
722 case Instruction::NEW_INSTANCE: {
723 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700724 ObjPtr<mirror::Object> obj = nullptr;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800725 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700726 shadow_frame.GetMethod(),
727 self,
728 false,
729 do_access_check);
Jeff Hao848f70a2014-01-15 13:49:50 -0800730 if (LIKELY(c != nullptr)) {
731 if (UNLIKELY(c->IsStringClass())) {
732 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700733 obj = mirror::String::AllocEmptyString<true>(self, allocator_type);
Jeff Hao848f70a2014-01-15 13:49:50 -0800734 } else {
Nicolas Geoffray0d3998b2017-01-12 15:35:12 +0000735 obj = AllocObjectFromCode<true>(
736 c.Ptr(),
Andreas Gampea5b09a62016-11-17 15:21:22 -0800737 self,
738 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Jeff Hao848f70a2014-01-15 13:49:50 -0800739 }
740 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700741 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200742 HANDLE_PENDING_EXCEPTION();
743 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200744 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700745 // Don't allow finalizable objects to be allocated during a transaction since these can't
746 // be finalized without a started runtime.
747 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200748 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
David Sehr709b0702016-10-13 09:12:37 -0700749 obj->PrettyTypeOf().c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700750 HANDLE_PENDING_EXCEPTION();
751 break;
752 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100753 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200754 inst = inst->Next_2xx();
755 }
756 break;
757 }
758 case Instruction::NEW_ARRAY: {
759 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200760 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartieref41db72016-10-25 15:08:01 -0700761 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800762 dex::TypeIndex(inst->VRegC_22c()),
763 length,
764 shadow_frame.GetMethod(),
765 self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800766 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700767 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200768 HANDLE_PENDING_EXCEPTION();
769 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100770 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200771 inst = inst->Next_2xx();
772 }
773 break;
774 }
775 case Instruction::FILLED_NEW_ARRAY: {
776 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100777 bool success =
778 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
779 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200780 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
781 break;
782 }
783 case Instruction::FILLED_NEW_ARRAY_RANGE: {
784 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100785 bool success =
786 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
787 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200788 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
789 break;
790 }
791 case Instruction::FILL_ARRAY_DATA: {
792 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200793 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
794 const Instruction::ArrayDataPayload* payload =
795 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700796 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700797 bool success = FillArrayData(obj, payload);
798 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200799 HANDLE_PENDING_EXCEPTION();
800 break;
801 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100802 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700803 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100804 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200805 inst = inst->Next_3xx();
806 break;
807 }
808 case Instruction::THROW: {
809 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700810 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700811 ObjPtr<mirror::Object> exception =
812 shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700813 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000814 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700815 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
816 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700817 std::string temp;
Orion Hodsonfef06642016-11-25 16:07:11 +0000818 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700819 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700820 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200821 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000822 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200823 }
824 HANDLE_PENDING_EXCEPTION();
825 break;
826 }
827 case Instruction::GOTO: {
828 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700829 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200830 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000831 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200832 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800833 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200834 break;
835 }
836 case Instruction::GOTO_16: {
837 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700838 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200839 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000840 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200841 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800842 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200843 break;
844 }
845 case Instruction::GOTO_32: {
846 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700847 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200848 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000849 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200850 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800851 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200852 break;
853 }
854 case Instruction::PACKED_SWITCH: {
855 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200856 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000857 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200858 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800859 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200860 break;
861 }
862 case Instruction::SPARSE_SWITCH: {
863 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200864 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000865 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200866 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800867 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200868 break;
869 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700870
Ian Rogers647b1a82014-10-10 11:02:11 -0700871#pragma clang diagnostic push
872#pragma clang diagnostic ignored "-Wfloat-equal"
Ian Rogers647b1a82014-10-10 11:02:11 -0700873
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200874 case Instruction::CMPL_FLOAT: {
875 PREAMBLE();
876 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
877 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
878 int32_t result;
879 if (val1 > val2) {
880 result = 1;
881 } else if (val1 == val2) {
882 result = 0;
883 } else {
884 result = -1;
885 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200886 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200887 inst = inst->Next_2xx();
888 break;
889 }
890 case Instruction::CMPG_FLOAT: {
891 PREAMBLE();
892 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
893 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
894 int32_t result;
895 if (val1 < val2) {
896 result = -1;
897 } else if (val1 == val2) {
898 result = 0;
899 } else {
900 result = 1;
901 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200902 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200903 inst = inst->Next_2xx();
904 break;
905 }
906 case Instruction::CMPL_DOUBLE: {
907 PREAMBLE();
908 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
909 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
910 int32_t result;
911 if (val1 > val2) {
912 result = 1;
913 } else if (val1 == val2) {
914 result = 0;
915 } else {
916 result = -1;
917 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200918 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200919 inst = inst->Next_2xx();
920 break;
921 }
922
923 case Instruction::CMPG_DOUBLE: {
924 PREAMBLE();
925 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
926 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
927 int32_t result;
928 if (val1 < val2) {
929 result = -1;
930 } else if (val1 == val2) {
931 result = 0;
932 } else {
933 result = 1;
934 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200935 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200936 inst = inst->Next_2xx();
937 break;
938 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700939
Ian Rogers647b1a82014-10-10 11:02:11 -0700940#pragma clang diagnostic pop
Ian Rogers647b1a82014-10-10 11:02:11 -0700941
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200942 case Instruction::CMP_LONG: {
943 PREAMBLE();
944 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
945 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
946 int32_t result;
947 if (val1 > val2) {
948 result = 1;
949 } else if (val1 == val2) {
950 result = 0;
951 } else {
952 result = -1;
953 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200954 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200955 inst = inst->Next_2xx();
956 break;
957 }
958 case Instruction::IF_EQ: {
959 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700960 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
961 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200962 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000963 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200964 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800965 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200966 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800967 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200968 inst = inst->Next_2xx();
969 }
970 break;
971 }
972 case Instruction::IF_NE: {
973 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700974 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
975 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200976 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000977 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200978 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800979 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200980 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800981 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200982 inst = inst->Next_2xx();
983 }
984 break;
985 }
986 case Instruction::IF_LT: {
987 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700988 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
989 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200990 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000991 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200992 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800993 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200994 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800995 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200996 inst = inst->Next_2xx();
997 }
998 break;
999 }
1000 case Instruction::IF_GE: {
1001 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001002 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
1003 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001004 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001005 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001006 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001007 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001008 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001009 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001010 inst = inst->Next_2xx();
1011 }
1012 break;
1013 }
1014 case Instruction::IF_GT: {
1015 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001016 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
1017 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001018 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001019 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001020 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001021 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001022 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001023 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001024 inst = inst->Next_2xx();
1025 }
1026 break;
1027 }
1028 case Instruction::IF_LE: {
1029 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001030 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
1031 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001032 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001033 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001034 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001035 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001036 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001037 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001038 inst = inst->Next_2xx();
1039 }
1040 break;
1041 }
1042 case Instruction::IF_EQZ: {
1043 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001044 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001045 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001046 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001047 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001048 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001049 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001050 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001051 inst = inst->Next_2xx();
1052 }
1053 break;
1054 }
1055 case Instruction::IF_NEZ: {
1056 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001057 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001058 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001059 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001060 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001061 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001062 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001063 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001064 inst = inst->Next_2xx();
1065 }
1066 break;
1067 }
1068 case Instruction::IF_LTZ: {
1069 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001070 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001071 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001072 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001073 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001074 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001075 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001076 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001077 inst = inst->Next_2xx();
1078 }
1079 break;
1080 }
1081 case Instruction::IF_GEZ: {
1082 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001083 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001084 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001085 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001086 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001087 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001088 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001089 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001090 inst = inst->Next_2xx();
1091 }
1092 break;
1093 }
1094 case Instruction::IF_GTZ: {
1095 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001096 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001097 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001098 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001099 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001100 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001101 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001102 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001103 inst = inst->Next_2xx();
1104 }
1105 break;
1106 }
1107 case Instruction::IF_LEZ: {
1108 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001109 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001110 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001111 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001112 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001113 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001114 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001115 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001116 inst = inst->Next_2xx();
1117 }
1118 break;
1119 }
1120 case Instruction::AGET_BOOLEAN: {
1121 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001122 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001123 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001124 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001125 HANDLE_PENDING_EXCEPTION();
1126 break;
1127 }
1128 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001129 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001130 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001131 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001132 inst = inst->Next_2xx();
1133 } else {
1134 HANDLE_PENDING_EXCEPTION();
1135 }
1136 break;
1137 }
1138 case Instruction::AGET_BYTE: {
1139 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001140 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001141 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001142 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001143 HANDLE_PENDING_EXCEPTION();
1144 break;
1145 }
1146 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001147 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001148 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001149 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001150 inst = inst->Next_2xx();
1151 } else {
1152 HANDLE_PENDING_EXCEPTION();
1153 }
1154 break;
1155 }
1156 case Instruction::AGET_CHAR: {
1157 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001158 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001159 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001160 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001161 HANDLE_PENDING_EXCEPTION();
1162 break;
1163 }
1164 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001165 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001166 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001167 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001168 inst = inst->Next_2xx();
1169 } else {
1170 HANDLE_PENDING_EXCEPTION();
1171 }
1172 break;
1173 }
1174 case Instruction::AGET_SHORT: {
1175 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001176 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001177 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001178 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001179 HANDLE_PENDING_EXCEPTION();
1180 break;
1181 }
1182 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001183 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001184 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001185 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001186 inst = inst->Next_2xx();
1187 } else {
1188 HANDLE_PENDING_EXCEPTION();
1189 }
1190 break;
1191 }
1192 case Instruction::AGET: {
1193 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001194 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001195 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001196 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001197 HANDLE_PENDING_EXCEPTION();
1198 break;
1199 }
1200 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001201 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001202 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001203 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001204 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001205 inst = inst->Next_2xx();
1206 } else {
1207 HANDLE_PENDING_EXCEPTION();
1208 }
1209 break;
1210 }
1211 case Instruction::AGET_WIDE: {
1212 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001213 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001214 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001215 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001216 HANDLE_PENDING_EXCEPTION();
1217 break;
1218 }
1219 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001220 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001221 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001222 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001223 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001224 inst = inst->Next_2xx();
1225 } else {
1226 HANDLE_PENDING_EXCEPTION();
1227 }
1228 break;
1229 }
1230 case Instruction::AGET_OBJECT: {
1231 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001232 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001233 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001234 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001235 HANDLE_PENDING_EXCEPTION();
1236 break;
1237 }
1238 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001239 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001240 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001241 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001242 inst = inst->Next_2xx();
1243 } else {
1244 HANDLE_PENDING_EXCEPTION();
1245 }
1246 break;
1247 }
1248 case Instruction::APUT_BOOLEAN: {
1249 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001250 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001251 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001252 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001253 HANDLE_PENDING_EXCEPTION();
1254 break;
1255 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001256 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001257 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001258 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001259 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001260 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001261 inst = inst->Next_2xx();
1262 } else {
1263 HANDLE_PENDING_EXCEPTION();
1264 }
1265 break;
1266 }
1267 case Instruction::APUT_BYTE: {
1268 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001269 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001270 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001271 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001272 HANDLE_PENDING_EXCEPTION();
1273 break;
1274 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001275 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001276 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001277 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001278 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001279 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001280 inst = inst->Next_2xx();
1281 } else {
1282 HANDLE_PENDING_EXCEPTION();
1283 }
1284 break;
1285 }
1286 case Instruction::APUT_CHAR: {
1287 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001288 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001289 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001290 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001291 HANDLE_PENDING_EXCEPTION();
1292 break;
1293 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001294 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001295 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001296 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001297 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001298 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001299 inst = inst->Next_2xx();
1300 } else {
1301 HANDLE_PENDING_EXCEPTION();
1302 }
1303 break;
1304 }
1305 case Instruction::APUT_SHORT: {
1306 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001307 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001308 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001309 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001310 HANDLE_PENDING_EXCEPTION();
1311 break;
1312 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001313 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001314 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001315 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001316 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001317 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001318 inst = inst->Next_2xx();
1319 } else {
1320 HANDLE_PENDING_EXCEPTION();
1321 }
1322 break;
1323 }
1324 case Instruction::APUT: {
1325 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001326 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001327 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001328 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001329 HANDLE_PENDING_EXCEPTION();
1330 break;
1331 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001332 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001333 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001334 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001335 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001336 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001337 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001338 inst = inst->Next_2xx();
1339 } else {
1340 HANDLE_PENDING_EXCEPTION();
1341 }
1342 break;
1343 }
1344 case Instruction::APUT_WIDE: {
1345 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001346 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001347 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001348 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001349 HANDLE_PENDING_EXCEPTION();
1350 break;
1351 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001352 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001353 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001354 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001355 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001356 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001357 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001358 inst = inst->Next_2xx();
1359 } else {
1360 HANDLE_PENDING_EXCEPTION();
1361 }
1362 break;
1363 }
1364 case Instruction::APUT_OBJECT: {
1365 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001366 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001367 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001368 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001369 HANDLE_PENDING_EXCEPTION();
1370 break;
1371 }
1372 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001373 ObjPtr<mirror::Object> val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
1374 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001375 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001376 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001377 inst = inst->Next_2xx();
1378 } else {
1379 HANDLE_PENDING_EXCEPTION();
1380 }
1381 break;
1382 }
1383 case Instruction::IGET_BOOLEAN: {
1384 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001385 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1386 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001387 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1388 break;
1389 }
1390 case Instruction::IGET_BYTE: {
1391 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001392 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1393 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001394 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1395 break;
1396 }
1397 case Instruction::IGET_CHAR: {
1398 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001399 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1400 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001401 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1402 break;
1403 }
1404 case Instruction::IGET_SHORT: {
1405 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001406 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1407 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001408 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1409 break;
1410 }
1411 case Instruction::IGET: {
1412 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001413 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1414 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001415 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1416 break;
1417 }
1418 case Instruction::IGET_WIDE: {
1419 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001420 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1421 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001422 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1423 break;
1424 }
1425 case Instruction::IGET_OBJECT: {
1426 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001427 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1428 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001429 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1430 break;
1431 }
1432 case Instruction::IGET_QUICK: {
1433 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001434 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001435 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1436 break;
1437 }
1438 case Instruction::IGET_WIDE_QUICK: {
1439 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001440 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001441 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1442 break;
1443 }
1444 case Instruction::IGET_OBJECT_QUICK: {
1445 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001446 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001447 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1448 break;
1449 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001450 case Instruction::IGET_BOOLEAN_QUICK: {
1451 PREAMBLE();
1452 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1453 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1454 break;
1455 }
1456 case Instruction::IGET_BYTE_QUICK: {
1457 PREAMBLE();
1458 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1459 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1460 break;
1461 }
1462 case Instruction::IGET_CHAR_QUICK: {
1463 PREAMBLE();
1464 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1465 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1466 break;
1467 }
1468 case Instruction::IGET_SHORT_QUICK: {
1469 PREAMBLE();
1470 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1471 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1472 break;
1473 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001474 case Instruction::SGET_BOOLEAN: {
1475 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001476 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check,
1477 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001478 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1479 break;
1480 }
1481 case Instruction::SGET_BYTE: {
1482 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001483 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check,
1484 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001485 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1486 break;
1487 }
1488 case Instruction::SGET_CHAR: {
1489 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001490 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check,
1491 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001492 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1493 break;
1494 }
1495 case Instruction::SGET_SHORT: {
1496 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001497 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check,
1498 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001499 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1500 break;
1501 }
1502 case Instruction::SGET: {
1503 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001504 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check,
1505 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001506 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1507 break;
1508 }
1509 case Instruction::SGET_WIDE: {
1510 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001511 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check,
1512 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001513 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1514 break;
1515 }
1516 case Instruction::SGET_OBJECT: {
1517 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001518 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check,
1519 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001520 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1521 break;
1522 }
1523 case Instruction::IPUT_BOOLEAN: {
1524 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001525 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1526 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001527 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1528 break;
1529 }
1530 case Instruction::IPUT_BYTE: {
1531 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001532 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1533 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001534 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1535 break;
1536 }
1537 case Instruction::IPUT_CHAR: {
1538 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001539 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1540 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001541 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1542 break;
1543 }
1544 case Instruction::IPUT_SHORT: {
1545 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001546 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1547 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001548 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1549 break;
1550 }
1551 case Instruction::IPUT: {
1552 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001553 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1554 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001555 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1556 break;
1557 }
1558 case Instruction::IPUT_WIDE: {
1559 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001560 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1561 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001562 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1563 break;
1564 }
1565 case Instruction::IPUT_OBJECT: {
1566 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001567 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1568 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001569 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1570 break;
1571 }
1572 case Instruction::IPUT_QUICK: {
1573 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001574 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1575 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001576 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1577 break;
1578 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001579 case Instruction::IPUT_BOOLEAN_QUICK: {
1580 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001581 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1582 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001583 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1584 break;
1585 }
1586 case Instruction::IPUT_BYTE_QUICK: {
1587 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001588 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1589 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001590 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1591 break;
1592 }
1593 case Instruction::IPUT_CHAR_QUICK: {
1594 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001595 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1596 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001597 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1598 break;
1599 }
1600 case Instruction::IPUT_SHORT_QUICK: {
1601 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001602 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1603 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001604 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1605 break;
1606 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001607 case Instruction::IPUT_WIDE_QUICK: {
1608 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001609 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1610 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001611 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1612 break;
1613 }
1614 case Instruction::IPUT_OBJECT_QUICK: {
1615 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001616 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1617 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001618 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1619 break;
1620 }
1621 case Instruction::SPUT_BOOLEAN: {
1622 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001623 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1624 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001625 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1626 break;
1627 }
1628 case Instruction::SPUT_BYTE: {
1629 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001630 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1631 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001632 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1633 break;
1634 }
1635 case Instruction::SPUT_CHAR: {
1636 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001637 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1638 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001639 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1640 break;
1641 }
1642 case Instruction::SPUT_SHORT: {
1643 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001644 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1645 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001646 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1647 break;
1648 }
1649 case Instruction::SPUT: {
1650 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001651 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1652 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001653 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1654 break;
1655 }
1656 case Instruction::SPUT_WIDE: {
1657 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001658 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1659 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001660 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1661 break;
1662 }
1663 case Instruction::SPUT_OBJECT: {
1664 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001665 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1666 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001667 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1668 break;
1669 }
1670 case Instruction::INVOKE_VIRTUAL: {
1671 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001672 bool success = DoInvoke<kVirtual, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001673 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001674 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001675 break;
1676 }
1677 case Instruction::INVOKE_VIRTUAL_RANGE: {
1678 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001679 bool success = DoInvoke<kVirtual, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001680 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001681 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001682 break;
1683 }
1684 case Instruction::INVOKE_SUPER: {
1685 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001686 bool success = DoInvoke<kSuper, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001687 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001688 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001689 break;
1690 }
1691 case Instruction::INVOKE_SUPER_RANGE: {
1692 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001693 bool success = DoInvoke<kSuper, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001694 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001695 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001696 break;
1697 }
1698 case Instruction::INVOKE_DIRECT: {
1699 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001700 bool success = DoInvoke<kDirect, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001701 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001702 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001703 break;
1704 }
1705 case Instruction::INVOKE_DIRECT_RANGE: {
1706 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001707 bool success = DoInvoke<kDirect, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001708 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001709 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001710 break;
1711 }
1712 case Instruction::INVOKE_INTERFACE: {
1713 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001714 bool success = DoInvoke<kInterface, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001715 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001716 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001717 break;
1718 }
1719 case Instruction::INVOKE_INTERFACE_RANGE: {
1720 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001721 bool success = DoInvoke<kInterface, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001722 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001723 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001724 break;
1725 }
1726 case Instruction::INVOKE_STATIC: {
1727 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001728 bool success = DoInvoke<kStatic, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001729 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001730 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001731 break;
1732 }
1733 case Instruction::INVOKE_STATIC_RANGE: {
1734 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001735 bool success = DoInvoke<kStatic, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001736 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001737 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001738 break;
1739 }
1740 case Instruction::INVOKE_VIRTUAL_QUICK: {
1741 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001742 bool success = DoInvokeVirtualQuick<false>(
1743 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001744 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001745 break;
1746 }
1747 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1748 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001749 bool success = DoInvokeVirtualQuick<true>(
1750 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001751 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001752 break;
1753 }
Narayan Kamath9823e782016-08-03 12:46:58 +01001754 case Instruction::INVOKE_POLYMORPHIC: {
1755 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001756 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Orion Hodsonc069a302017-01-18 09:23:12 +00001757 bool success = DoInvokePolymorphic<false /* is_range */>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001758 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001759 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
Narayan Kamath9823e782016-08-03 12:46:58 +01001760 break;
1761 }
1762 case Instruction::INVOKE_POLYMORPHIC_RANGE: {
1763 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001764 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Orion Hodsonc069a302017-01-18 09:23:12 +00001765 bool success = DoInvokePolymorphic<true /* is_range */>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001766 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001767 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
Narayan Kamath9823e782016-08-03 12:46:58 +01001768 break;
Narayan Kamath9823e782016-08-03 12:46:58 +01001769 }
Orion Hodsonc069a302017-01-18 09:23:12 +00001770 case Instruction::INVOKE_CUSTOM: {
1771 PREAMBLE();
1772 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1773 bool success = DoInvokeCustom<false /* is_range */>(
1774 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001775 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Orion Hodsonc069a302017-01-18 09:23:12 +00001776 break;
1777 }
1778 case Instruction::INVOKE_CUSTOM_RANGE: {
1779 PREAMBLE();
1780 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1781 bool success = DoInvokeCustom<true /* is_range */>(
1782 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001783 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Orion Hodsonc069a302017-01-18 09:23:12 +00001784 break;
1785 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001786 case Instruction::NEG_INT:
1787 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001788 shadow_frame.SetVReg(
1789 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001790 inst = inst->Next_1xx();
1791 break;
1792 case Instruction::NOT_INT:
1793 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001794 shadow_frame.SetVReg(
1795 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001796 inst = inst->Next_1xx();
1797 break;
1798 case Instruction::NEG_LONG:
1799 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001800 shadow_frame.SetVRegLong(
1801 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001802 inst = inst->Next_1xx();
1803 break;
1804 case Instruction::NOT_LONG:
1805 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001806 shadow_frame.SetVRegLong(
1807 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001808 inst = inst->Next_1xx();
1809 break;
1810 case Instruction::NEG_FLOAT:
1811 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001812 shadow_frame.SetVRegFloat(
1813 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001814 inst = inst->Next_1xx();
1815 break;
1816 case Instruction::NEG_DOUBLE:
1817 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001818 shadow_frame.SetVRegDouble(
1819 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001820 inst = inst->Next_1xx();
1821 break;
1822 case Instruction::INT_TO_LONG:
1823 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001824 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1825 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001826 inst = inst->Next_1xx();
1827 break;
1828 case Instruction::INT_TO_FLOAT:
1829 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001830 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1831 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001832 inst = inst->Next_1xx();
1833 break;
1834 case Instruction::INT_TO_DOUBLE:
1835 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001836 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1837 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001838 inst = inst->Next_1xx();
1839 break;
1840 case Instruction::LONG_TO_INT:
1841 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001842 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1843 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001844 inst = inst->Next_1xx();
1845 break;
1846 case Instruction::LONG_TO_FLOAT:
1847 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001848 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1849 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001850 inst = inst->Next_1xx();
1851 break;
1852 case Instruction::LONG_TO_DOUBLE:
1853 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001854 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1855 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001856 inst = inst->Next_1xx();
1857 break;
1858 case Instruction::FLOAT_TO_INT: {
1859 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001860 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001861 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001862 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001863 inst = inst->Next_1xx();
1864 break;
1865 }
1866 case Instruction::FLOAT_TO_LONG: {
1867 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001868 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001869 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001870 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001871 inst = inst->Next_1xx();
1872 break;
1873 }
1874 case Instruction::FLOAT_TO_DOUBLE:
1875 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001876 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1877 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001878 inst = inst->Next_1xx();
1879 break;
1880 case Instruction::DOUBLE_TO_INT: {
1881 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001882 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001883 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001884 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001885 inst = inst->Next_1xx();
1886 break;
1887 }
1888 case Instruction::DOUBLE_TO_LONG: {
1889 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001890 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001891 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001892 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001893 inst = inst->Next_1xx();
1894 break;
1895 }
1896 case Instruction::DOUBLE_TO_FLOAT:
1897 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001898 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1899 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001900 inst = inst->Next_1xx();
1901 break;
1902 case Instruction::INT_TO_BYTE:
1903 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001904 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1905 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001906 inst = inst->Next_1xx();
1907 break;
1908 case Instruction::INT_TO_CHAR:
1909 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001910 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1911 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001912 inst = inst->Next_1xx();
1913 break;
1914 case Instruction::INT_TO_SHORT:
1915 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001916 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1917 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001918 inst = inst->Next_1xx();
1919 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001920 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001921 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001922 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001923 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1924 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001925 inst = inst->Next_2xx();
1926 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001927 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001928 case Instruction::SUB_INT:
1929 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001930 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001931 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1932 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001933 inst = inst->Next_2xx();
1934 break;
1935 case Instruction::MUL_INT:
1936 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001937 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001938 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1939 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001940 inst = inst->Next_2xx();
1941 break;
1942 case Instruction::DIV_INT: {
1943 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001944 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001945 shadow_frame.GetVReg(inst->VRegB_23x()),
1946 shadow_frame.GetVReg(inst->VRegC_23x()));
1947 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1948 break;
1949 }
1950 case Instruction::REM_INT: {
1951 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001952 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001953 shadow_frame.GetVReg(inst->VRegB_23x()),
1954 shadow_frame.GetVReg(inst->VRegC_23x()));
1955 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1956 break;
1957 }
1958 case Instruction::SHL_INT:
1959 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001960 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001961 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1962 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1963 inst = inst->Next_2xx();
1964 break;
1965 case Instruction::SHR_INT:
1966 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001967 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001968 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1969 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1970 inst = inst->Next_2xx();
1971 break;
1972 case Instruction::USHR_INT:
1973 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001974 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001975 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1976 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1977 inst = inst->Next_2xx();
1978 break;
1979 case Instruction::AND_INT:
1980 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001981 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001982 shadow_frame.GetVReg(inst->VRegB_23x()) &
1983 shadow_frame.GetVReg(inst->VRegC_23x()));
1984 inst = inst->Next_2xx();
1985 break;
1986 case Instruction::OR_INT:
1987 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001988 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001989 shadow_frame.GetVReg(inst->VRegB_23x()) |
1990 shadow_frame.GetVReg(inst->VRegC_23x()));
1991 inst = inst->Next_2xx();
1992 break;
1993 case Instruction::XOR_INT:
1994 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001995 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001996 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1997 shadow_frame.GetVReg(inst->VRegC_23x()));
1998 inst = inst->Next_2xx();
1999 break;
2000 case Instruction::ADD_LONG:
2001 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002002 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002003 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
2004 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002005 inst = inst->Next_2xx();
2006 break;
2007 case Instruction::SUB_LONG:
2008 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002009 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002010 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
2011 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002012 inst = inst->Next_2xx();
2013 break;
2014 case Instruction::MUL_LONG:
2015 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002016 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002017 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
2018 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002019 inst = inst->Next_2xx();
2020 break;
2021 case Instruction::DIV_LONG:
2022 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002023 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002024 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002025 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002026 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
2027 break;
2028 case Instruction::REM_LONG:
2029 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002030 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002031 shadow_frame.GetVRegLong(inst->VRegB_23x()),
2032 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2033 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
2034 break;
2035 case Instruction::AND_LONG:
2036 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002037 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002038 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
2039 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2040 inst = inst->Next_2xx();
2041 break;
2042 case Instruction::OR_LONG:
2043 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002044 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002045 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
2046 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2047 inst = inst->Next_2xx();
2048 break;
2049 case Instruction::XOR_LONG:
2050 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002051 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002052 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
2053 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2054 inst = inst->Next_2xx();
2055 break;
2056 case Instruction::SHL_LONG:
2057 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002058 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002059 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
2060 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2061 inst = inst->Next_2xx();
2062 break;
2063 case Instruction::SHR_LONG:
2064 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002065 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002066 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
2067 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2068 inst = inst->Next_2xx();
2069 break;
2070 case Instruction::USHR_LONG:
2071 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002072 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002073 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
2074 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2075 inst = inst->Next_2xx();
2076 break;
2077 case Instruction::ADD_FLOAT:
2078 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002079 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002080 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
2081 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2082 inst = inst->Next_2xx();
2083 break;
2084 case Instruction::SUB_FLOAT:
2085 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002086 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002087 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
2088 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2089 inst = inst->Next_2xx();
2090 break;
2091 case Instruction::MUL_FLOAT:
2092 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002093 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002094 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
2095 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2096 inst = inst->Next_2xx();
2097 break;
2098 case Instruction::DIV_FLOAT:
2099 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002100 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002101 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
2102 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2103 inst = inst->Next_2xx();
2104 break;
2105 case Instruction::REM_FLOAT:
2106 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002107 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002108 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
2109 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
2110 inst = inst->Next_2xx();
2111 break;
2112 case Instruction::ADD_DOUBLE:
2113 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002114 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002115 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
2116 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2117 inst = inst->Next_2xx();
2118 break;
2119 case Instruction::SUB_DOUBLE:
2120 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002121 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002122 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
2123 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2124 inst = inst->Next_2xx();
2125 break;
2126 case Instruction::MUL_DOUBLE:
2127 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002128 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002129 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
2130 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2131 inst = inst->Next_2xx();
2132 break;
2133 case Instruction::DIV_DOUBLE:
2134 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002135 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002136 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2137 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2138 inst = inst->Next_2xx();
2139 break;
2140 case Instruction::REM_DOUBLE:
2141 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002142 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002143 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2144 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2145 inst = inst->Next_2xx();
2146 break;
2147 case Instruction::ADD_INT_2ADDR: {
2148 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002149 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07002150 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
2151 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002152 inst = inst->Next_1xx();
2153 break;
2154 }
2155 case Instruction::SUB_INT_2ADDR: {
2156 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002157 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002158 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002159 SafeSub(shadow_frame.GetVReg(vregA),
2160 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002161 inst = inst->Next_1xx();
2162 break;
2163 }
2164 case Instruction::MUL_INT_2ADDR: {
2165 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002166 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002167 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002168 SafeMul(shadow_frame.GetVReg(vregA),
2169 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002170 inst = inst->Next_1xx();
2171 break;
2172 }
2173 case Instruction::DIV_INT_2ADDR: {
2174 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002175 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002176 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002177 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002178 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2179 break;
2180 }
2181 case Instruction::REM_INT_2ADDR: {
2182 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002183 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002184 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002185 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002186 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2187 break;
2188 }
2189 case Instruction::SHL_INT_2ADDR: {
2190 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002191 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002192 shadow_frame.SetVReg(vregA,
2193 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002194 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002195 inst = inst->Next_1xx();
2196 break;
2197 }
2198 case Instruction::SHR_INT_2ADDR: {
2199 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002200 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002201 shadow_frame.SetVReg(vregA,
2202 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002203 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002204 inst = inst->Next_1xx();
2205 break;
2206 }
2207 case Instruction::USHR_INT_2ADDR: {
2208 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002209 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002210 shadow_frame.SetVReg(vregA,
2211 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002212 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002213 inst = inst->Next_1xx();
2214 break;
2215 }
2216 case Instruction::AND_INT_2ADDR: {
2217 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002218 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002219 shadow_frame.SetVReg(vregA,
2220 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002221 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002222 inst = inst->Next_1xx();
2223 break;
2224 }
2225 case Instruction::OR_INT_2ADDR: {
2226 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002227 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002228 shadow_frame.SetVReg(vregA,
2229 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002230 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002231 inst = inst->Next_1xx();
2232 break;
2233 }
2234 case Instruction::XOR_INT_2ADDR: {
2235 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002236 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002237 shadow_frame.SetVReg(vregA,
2238 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002239 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002240 inst = inst->Next_1xx();
2241 break;
2242 }
2243 case Instruction::ADD_LONG_2ADDR: {
2244 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002245 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002246 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002247 SafeAdd(shadow_frame.GetVRegLong(vregA),
2248 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002249 inst = inst->Next_1xx();
2250 break;
2251 }
2252 case Instruction::SUB_LONG_2ADDR: {
2253 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002254 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002255 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002256 SafeSub(shadow_frame.GetVRegLong(vregA),
2257 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002258 inst = inst->Next_1xx();
2259 break;
2260 }
2261 case Instruction::MUL_LONG_2ADDR: {
2262 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002263 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002264 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002265 SafeMul(shadow_frame.GetVRegLong(vregA),
2266 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002267 inst = inst->Next_1xx();
2268 break;
2269 }
2270 case Instruction::DIV_LONG_2ADDR: {
2271 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002272 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002273 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002274 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002275 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2276 break;
2277 }
2278 case Instruction::REM_LONG_2ADDR: {
2279 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002280 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002281 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002282 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002283 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2284 break;
2285 }
2286 case Instruction::AND_LONG_2ADDR: {
2287 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002288 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002289 shadow_frame.SetVRegLong(vregA,
2290 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002291 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002292 inst = inst->Next_1xx();
2293 break;
2294 }
2295 case Instruction::OR_LONG_2ADDR: {
2296 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002297 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002298 shadow_frame.SetVRegLong(vregA,
2299 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002300 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002301 inst = inst->Next_1xx();
2302 break;
2303 }
2304 case Instruction::XOR_LONG_2ADDR: {
2305 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002306 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002307 shadow_frame.SetVRegLong(vregA,
2308 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002309 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002310 inst = inst->Next_1xx();
2311 break;
2312 }
2313 case Instruction::SHL_LONG_2ADDR: {
2314 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002315 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002316 shadow_frame.SetVRegLong(vregA,
2317 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002318 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002319 inst = inst->Next_1xx();
2320 break;
2321 }
2322 case Instruction::SHR_LONG_2ADDR: {
2323 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002324 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002325 shadow_frame.SetVRegLong(vregA,
2326 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002327 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002328 inst = inst->Next_1xx();
2329 break;
2330 }
2331 case Instruction::USHR_LONG_2ADDR: {
2332 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002333 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002334 shadow_frame.SetVRegLong(vregA,
2335 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002336 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002337 inst = inst->Next_1xx();
2338 break;
2339 }
2340 case Instruction::ADD_FLOAT_2ADDR: {
2341 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002342 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002343 shadow_frame.SetVRegFloat(vregA,
2344 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002345 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002346 inst = inst->Next_1xx();
2347 break;
2348 }
2349 case Instruction::SUB_FLOAT_2ADDR: {
2350 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002351 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002352 shadow_frame.SetVRegFloat(vregA,
2353 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002354 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002355 inst = inst->Next_1xx();
2356 break;
2357 }
2358 case Instruction::MUL_FLOAT_2ADDR: {
2359 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002360 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002361 shadow_frame.SetVRegFloat(vregA,
2362 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002363 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002364 inst = inst->Next_1xx();
2365 break;
2366 }
2367 case Instruction::DIV_FLOAT_2ADDR: {
2368 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002369 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002370 shadow_frame.SetVRegFloat(vregA,
2371 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002372 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002373 inst = inst->Next_1xx();
2374 break;
2375 }
2376 case Instruction::REM_FLOAT_2ADDR: {
2377 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002378 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002379 shadow_frame.SetVRegFloat(vregA,
2380 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002381 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002382 inst = inst->Next_1xx();
2383 break;
2384 }
2385 case Instruction::ADD_DOUBLE_2ADDR: {
2386 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002387 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002388 shadow_frame.SetVRegDouble(vregA,
2389 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002390 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002391 inst = inst->Next_1xx();
2392 break;
2393 }
2394 case Instruction::SUB_DOUBLE_2ADDR: {
2395 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002396 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002397 shadow_frame.SetVRegDouble(vregA,
2398 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002399 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002400 inst = inst->Next_1xx();
2401 break;
2402 }
2403 case Instruction::MUL_DOUBLE_2ADDR: {
2404 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002405 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002406 shadow_frame.SetVRegDouble(vregA,
2407 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002408 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002409 inst = inst->Next_1xx();
2410 break;
2411 }
2412 case Instruction::DIV_DOUBLE_2ADDR: {
2413 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002414 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002415 shadow_frame.SetVRegDouble(vregA,
2416 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002417 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002418 inst = inst->Next_1xx();
2419 break;
2420 }
2421 case Instruction::REM_DOUBLE_2ADDR: {
2422 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002423 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002424 shadow_frame.SetVRegDouble(vregA,
2425 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002426 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002427 inst = inst->Next_1xx();
2428 break;
2429 }
2430 case Instruction::ADD_INT_LIT16:
2431 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002432 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002433 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2434 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002435 inst = inst->Next_2xx();
2436 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002437 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002438 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002439 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002440 SafeSub(inst->VRegC_22s(),
2441 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002442 inst = inst->Next_2xx();
2443 break;
2444 case Instruction::MUL_INT_LIT16:
2445 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002446 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002447 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2448 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002449 inst = inst->Next_2xx();
2450 break;
2451 case Instruction::DIV_INT_LIT16: {
2452 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002453 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002454 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2455 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002456 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2457 break;
2458 }
2459 case Instruction::REM_INT_LIT16: {
2460 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002461 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002462 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2463 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002464 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2465 break;
2466 }
2467 case Instruction::AND_INT_LIT16:
2468 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002469 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2470 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002471 inst->VRegC_22s());
2472 inst = inst->Next_2xx();
2473 break;
2474 case Instruction::OR_INT_LIT16:
2475 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002476 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2477 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002478 inst->VRegC_22s());
2479 inst = inst->Next_2xx();
2480 break;
2481 case Instruction::XOR_INT_LIT16:
2482 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002483 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2484 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002485 inst->VRegC_22s());
2486 inst = inst->Next_2xx();
2487 break;
2488 case Instruction::ADD_INT_LIT8:
2489 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002490 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002491 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002492 inst = inst->Next_2xx();
2493 break;
2494 case Instruction::RSUB_INT_LIT8:
2495 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002496 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002497 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002498 inst = inst->Next_2xx();
2499 break;
2500 case Instruction::MUL_INT_LIT8:
2501 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002502 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002503 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002504 inst = inst->Next_2xx();
2505 break;
2506 case Instruction::DIV_INT_LIT8: {
2507 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002508 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002509 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2510 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2511 break;
2512 }
2513 case Instruction::REM_INT_LIT8: {
2514 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002515 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002516 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2517 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2518 break;
2519 }
2520 case Instruction::AND_INT_LIT8:
2521 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002522 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002523 shadow_frame.GetVReg(inst->VRegB_22b()) &
2524 inst->VRegC_22b());
2525 inst = inst->Next_2xx();
2526 break;
2527 case Instruction::OR_INT_LIT8:
2528 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002529 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002530 shadow_frame.GetVReg(inst->VRegB_22b()) |
2531 inst->VRegC_22b());
2532 inst = inst->Next_2xx();
2533 break;
2534 case Instruction::XOR_INT_LIT8:
2535 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002536 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002537 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2538 inst->VRegC_22b());
2539 inst = inst->Next_2xx();
2540 break;
2541 case Instruction::SHL_INT_LIT8:
2542 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002543 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002544 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2545 (inst->VRegC_22b() & 0x1f));
2546 inst = inst->Next_2xx();
2547 break;
2548 case Instruction::SHR_INT_LIT8:
2549 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002550 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002551 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2552 (inst->VRegC_22b() & 0x1f));
2553 inst = inst->Next_2xx();
2554 break;
2555 case Instruction::USHR_INT_LIT8:
2556 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002557 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002558 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2559 (inst->VRegC_22b() & 0x1f));
2560 inst = inst->Next_2xx();
2561 break;
2562 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Orion Hodson2e599942017-09-22 16:17:41 +01002563 case Instruction::UNUSED_79 ... Instruction::UNUSED_7A:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002564 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
Ian Rogerse94652f2014-12-02 11:13:19 -08002565 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002566 }
buzbee1452bee2015-03-06 14:43:04 -08002567 } while (!interpret_one_instruction);
2568 // Record where we stopped.
2569 shadow_frame.SetDexPC(inst->GetDexPc(insns));
David Srbecky946bb092018-03-09 17:23:01 +00002570 ctx->result = result_register;
2571 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002572} // NOLINT(readability/fn_size)
2573
David Srbecky946bb092018-03-09 17:23:01 +00002574// Explicit definitions of ExecuteSwitchImplCpp.
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002575template HOT_ATTR
David Srbecky946bb092018-03-09 17:23:01 +00002576void ExecuteSwitchImplCpp<true, false>(SwitchImplContext* ctx);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002577template HOT_ATTR
David Srbecky946bb092018-03-09 17:23:01 +00002578void ExecuteSwitchImplCpp<false, false>(SwitchImplContext* ctx);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002579template
David Srbecky946bb092018-03-09 17:23:01 +00002580void ExecuteSwitchImplCpp<true, true>(SwitchImplContext* ctx);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002581template
David Srbecky946bb092018-03-09 17:23:01 +00002582void ExecuteSwitchImplCpp<false, true>(SwitchImplContext* ctx);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002583
2584} // namespace interpreter
2585} // namespace art