blob: c4b03b256301bd56ee4d4eb9223b1dfb7c833fcd [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Andreas Gampe5e26eb12016-08-22 17:54:17 -070017#include "interpreter_switch_impl.h"
18
Andreas Gampe542451c2016-07-26 09:02:02 -070019#include "base/enums.h"
David Sehrc431b9d2018-03-02 12:01:51 -080020#include "base/quasi_atomic.h"
David Sehr9e734c72018-01-04 17:56:19 -080021#include "dex/dex_file_types.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070022#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020023#include "interpreter_common.h"
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000024#include "jit/jit.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070025#include "jvalue-inl.h"
Alex Light88a2a9d2018-03-14 14:44:29 -070026#include "nth_caller_visitor.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070027#include "safe_math.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010028#include "shadow_frame-inl.h"
Alex Light88a2a9d2018-03-14 14:44:29 -070029#include "thread.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020030
31namespace art {
32namespace interpreter {
33
Alex Light88a2a9d2018-03-14 14:44:29 -070034#define CHECK_FORCE_RETURN() \
35 do { \
36 if (UNLIKELY(shadow_frame.GetForcePopFrame())) { \
37 DCHECK(PrevFrameWillRetry(self, shadow_frame)) \
38 << "Pop frame forced without previous frame ready to retry instruction!"; \
39 DCHECK(Runtime::Current()->AreNonStandardExitsEnabled()); \
40 if (UNLIKELY(NeedsMethodExitEvent(instrumentation))) { \
41 SendMethodExitEvents(self, \
42 instrumentation, \
43 shadow_frame, \
44 shadow_frame.GetThisObject(accessor.InsSize()), \
45 shadow_frame.GetMethod(), \
46 inst->GetDexPc(insns), \
47 JValue()); \
48 } \
49 ctx->result = JValue(); /* Handled in caller. */ \
50 return; \
51 } \
52 } while (false)
53
Alex Lightb7edcda2017-04-27 13:20:31 -070054#define HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instr) \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020055 do { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020056 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070057 self->AllowThreadSuspension(); \
Alex Light88a2a9d2018-03-14 14:44:29 -070058 CHECK_FORCE_RETURN(); \
Alex Light9fb1ab12017-09-05 09:32:49 -070059 if (!MoveToExceptionHandler(self, shadow_frame, instr)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070060 /* Structured locking is to be enforced for abnormal termination, too. */ \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070061 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame); \
buzbee1452bee2015-03-06 14:43:04 -080062 if (interpret_one_instruction) { \
buzbee93e94f22016-04-07 13:52:48 -070063 /* Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -070064 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee1452bee2015-03-06 14:43:04 -080065 } \
David Srbecky946bb092018-03-09 17:23:01 +000066 ctx->result = JValue(); /* Handled in caller. */ \
67 return; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020068 } else { \
Alex Light88a2a9d2018-03-14 14:44:29 -070069 CHECK_FORCE_RETURN(); \
Alex Light9fb1ab12017-09-05 09:32:49 -070070 int32_t displacement = \
71 static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020072 inst = inst->RelativeAt(displacement); \
73 } \
74 } while (false)
75
Alex Lightb7edcda2017-04-27 13:20:31 -070076#define HANDLE_PENDING_EXCEPTION() HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instrumentation)
77
Alex Light88a2a9d2018-03-14 14:44:29 -070078#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, _next_function) \
79 do { \
80 if (UNLIKELY(shadow_frame.GetForceRetryInstruction())) { \
81 /* Don't need to do anything except clear the flag and exception. We leave the */ \
82 /* instruction the same so it will be re-executed on the next go-around. */ \
83 DCHECK(inst->IsInvoke()); \
84 shadow_frame.SetForceRetryInstruction(false); \
85 if (UNLIKELY(_is_exception_pending)) { \
86 DCHECK(self->IsExceptionPending()); \
87 if (kIsDebugBuild) { \
88 LOG(WARNING) << "Suppressing exception for instruction-retry: " \
89 << self->GetException()->Dump(); \
90 } \
91 self->ClearException(); \
92 } \
93 } else if (UNLIKELY(_is_exception_pending)) { \
94 /* Should have succeeded. */ \
95 DCHECK(!shadow_frame.GetForceRetryInstruction()); \
96 HANDLE_PENDING_EXCEPTION(); \
97 } else { \
98 inst = inst->_next_function(); \
99 } \
100 } while (false)
101
102#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(_is_exception_pending) \
103 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, Next_4xx)
104#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(_is_exception_pending) \
105 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, Next_3xx)
106
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200107#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
108 do { \
Alex Light88a2a9d2018-03-14 14:44:29 -0700109 /* Should only be on invoke instructions. */ \
110 DCHECK(!shadow_frame.GetForceRetryInstruction()); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200111 if (UNLIKELY(_is_exception_pending)) { \
112 HANDLE_PENDING_EXCEPTION(); \
113 } else { \
114 inst = inst->_next_function(); \
115 } \
116 } while (false)
117
Andreas Gampe03ec9302015-08-27 17:41:47 -0700118#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -0700119 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -0700120 HANDLE_PENDING_EXCEPTION(); \
121 }
122
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200123// Code to run before each dex instruction.
Alex Light88a2a9d2018-03-14 14:44:29 -0700124#define PREAMBLE_SAVE(save_ref) \
Alex Lightfc905672017-06-27 17:53:15 -0700125 { \
Alex Light88a2a9d2018-03-14 14:44:29 -0700126 /* We need to put this before & after the instrumentation to avoid having to put in a */ \
127 /* post-script macro. */ \
128 CHECK_FORCE_RETURN(); \
129 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
130 if (UNLIKELY(!DoDexPcMoveEvent(self, \
131 accessor, \
132 shadow_frame, \
133 dex_pc, \
134 instrumentation, \
135 save_ref))) { \
136 HANDLE_PENDING_EXCEPTION(); \
137 break; \
138 } \
139 CHECK_FORCE_RETURN(); \
Sebastien Hertz8379b222014-02-24 17:38:15 +0100140 } \
Alex Lightfc905672017-06-27 17:53:15 -0700141 } \
142 do {} while (false)
143
144#define PREAMBLE() PREAMBLE_SAVE(nullptr)
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200145
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000146#define BRANCH_INSTRUMENTATION(offset) \
147 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100148 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
Alex Lightcc917d92018-02-22 13:28:28 -0800149 instrumentation->Branch(self, shadow_frame.GetMethod(), dex_pc, offset); \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100150 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000151 JValue result; \
Alex Lightcc917d92018-02-22 13:28:28 -0800152 if (jit::Jit::MaybeDoOnStackReplacement(self, \
153 shadow_frame.GetMethod(), \
154 dex_pc, \
155 offset, \
156 &result)) { \
buzbee93e94f22016-04-07 13:52:48 -0700157 if (interpret_one_instruction) { \
158 /* OSR has completed execution of the method. Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -0700159 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee93e94f22016-04-07 13:52:48 -0700160 } \
David Srbecky946bb092018-03-09 17:23:01 +0000161 ctx->result = result; \
162 return; \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000163 } \
Nicolas Geoffray3108daf2015-11-24 16:32:33 +0000164 } while (false)
165
Bill Buzbee1d011d92016-04-04 16:59:29 +0000166#define HOTNESS_UPDATE() \
167 do { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100168 if (jit != nullptr) { \
Alex Lightcc917d92018-02-22 13:28:28 -0800169 jit->AddSamples(self, shadow_frame.GetMethod(), 1, /*with_backedges*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +0000170 } \
171 } while (false)
172
Alex Light848574c2017-09-25 16:59:39 -0700173#define HANDLE_ASYNC_EXCEPTION() \
174 if (UNLIKELY(self->ObserveAsyncException())) { \
175 HANDLE_PENDING_EXCEPTION(); \
176 break; \
177 } \
178 do {} while (false)
179
Andreas Gampef4f76372016-12-13 14:43:58 -0800180#define HANDLE_BACKWARD_BRANCH(offset) \
181 do { \
182 if (IsBackwardBranch(offset)) { \
183 HOTNESS_UPDATE(); \
184 /* Record new dex pc early to have consistent suspend point at loop header. */ \
185 shadow_frame.SetDexPC(inst->GetDexPc(insns)); \
186 self->AllowThreadSuspension(); \
187 } \
188 } while (false)
189
Alex Lightfc905672017-06-27 17:53:15 -0700190// Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
191// the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
192// to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
193// jvmti-agents while handling breakpoint or single step events. We had to move this into its own
194// function because it was making ExecuteSwitchImpl have too large a stack.
Alex Light2989a4a2017-06-29 09:44:57 -0700195NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800196 const CodeItemDataAccessor& accessor,
Alex Light2989a4a2017-06-29 09:44:57 -0700197 const ShadowFrame& shadow_frame,
198 uint32_t dex_pc,
199 const instrumentation::Instrumentation* instrumentation,
200 JValue* save_ref)
Alex Lightfc905672017-06-27 17:53:15 -0700201 REQUIRES_SHARED(Locks::mutator_lock_) {
202 DCHECK(instrumentation->HasDexPcListeners());
203 StackHandleScope<2> hs(self);
204 Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
205 mirror::Object* null_obj = nullptr;
206 HandleWrapper<mirror::Object> h(
207 hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
208 self->ClearException();
209 instrumentation->DexPcMovedEvent(self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800210 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lightfc905672017-06-27 17:53:15 -0700211 shadow_frame.GetMethod(),
212 dex_pc);
213 if (UNLIKELY(self->IsExceptionPending())) {
214 // We got a new exception in the dex-pc-moved event. We just let this exception replace the old
215 // one.
216 // TODO It would be good to add the old exception to the suppressed exceptions of the new one if
217 // possible.
218 return false;
219 } else {
220 if (UNLIKELY(!thr.IsNull())) {
221 self->SetException(thr.Get());
222 }
223 return true;
224 }
225}
226
Alex Lighte814f9d2017-07-31 16:14:39 -0700227static bool NeedsMethodExitEvent(const instrumentation::Instrumentation* ins)
228 REQUIRES_SHARED(Locks::mutator_lock_) {
229 return ins->HasMethodExitListeners() || ins->HasWatchedFramePopListeners();
230}
231
232// Sends the normal method exit event. Returns true if the events succeeded and false if there is a
233// pending exception.
234NO_INLINE static bool SendMethodExitEvents(Thread* self,
235 const instrumentation::Instrumentation* instrumentation,
236 const ShadowFrame& frame,
237 ObjPtr<mirror::Object> thiz,
238 ArtMethod* method,
239 uint32_t dex_pc,
240 const JValue& result)
241 REQUIRES_SHARED(Locks::mutator_lock_) {
242 bool had_event = false;
Alex Light88a2a9d2018-03-14 14:44:29 -0700243 // We don't send method-exit if it's a pop-frame. We still send frame_popped though.
244 if (UNLIKELY(instrumentation->HasMethodExitListeners() && !frame.GetForcePopFrame())) {
Alex Lighte814f9d2017-07-31 16:14:39 -0700245 had_event = true;
246 instrumentation->MethodExitEvent(self, thiz.Ptr(), method, dex_pc, result);
247 }
248 if (UNLIKELY(frame.NeedsNotifyPop() && instrumentation->HasWatchedFramePopListeners())) {
249 had_event = true;
250 instrumentation->WatchedFramePopped(self, frame);
251 }
252 if (UNLIKELY(had_event)) {
253 return !self->IsExceptionPending();
254 } else {
255 return true;
256 }
257}
258
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100259template<bool do_access_check, bool transaction_active>
David Srbecky946bb092018-03-09 17:23:01 +0000260void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
261 Thread* self = ctx->self;
262 const CodeItemDataAccessor& accessor = ctx->accessor;
263 ShadowFrame& shadow_frame = ctx->shadow_frame;
264 JValue result_register = ctx->result_register;
265 bool interpret_one_instruction = ctx->interpret_one_instruction;
Igor Murashkinc449e8b2015-06-10 15:56:42 -0700266 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200267 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
268 LOG(FATAL) << "Invalid shadow frame for interpreter use";
David Srbecky946bb092018-03-09 17:23:01 +0000269 ctx->result = JValue();
270 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200271 }
272 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200273
274 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700275 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800276 const uint16_t* const insns = accessor.Insns();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200277 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200278 uint16_t inst_data;
Bill Buzbee1d011d92016-04-04 16:59:29 +0000279 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700280
Alex Light88a2a9d2018-03-14 14:44:29 -0700281 DCHECK(!shadow_frame.GetForceRetryInstruction())
282 << "Entered interpreter from invoke without retry instruction being handled!";
283
buzbee1452bee2015-03-06 14:43:04 -0800284 do {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200285 dex_pc = inst->GetDexPc(insns);
286 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800287 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200288 inst_data = inst->Fetch16(0);
289 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200290 case Instruction::NOP:
291 PREAMBLE();
292 inst = inst->Next_1xx();
293 break;
294 case Instruction::MOVE:
295 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200296 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
297 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200298 inst = inst->Next_1xx();
299 break;
300 case Instruction::MOVE_FROM16:
301 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200302 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200303 shadow_frame.GetVReg(inst->VRegB_22x()));
304 inst = inst->Next_2xx();
305 break;
306 case Instruction::MOVE_16:
307 PREAMBLE();
308 shadow_frame.SetVReg(inst->VRegA_32x(),
309 shadow_frame.GetVReg(inst->VRegB_32x()));
310 inst = inst->Next_3xx();
311 break;
312 case Instruction::MOVE_WIDE:
313 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200314 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
315 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200316 inst = inst->Next_1xx();
317 break;
318 case Instruction::MOVE_WIDE_FROM16:
319 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200320 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200321 shadow_frame.GetVRegLong(inst->VRegB_22x()));
322 inst = inst->Next_2xx();
323 break;
324 case Instruction::MOVE_WIDE_16:
325 PREAMBLE();
326 shadow_frame.SetVRegLong(inst->VRegA_32x(),
327 shadow_frame.GetVRegLong(inst->VRegB_32x()));
328 inst = inst->Next_3xx();
329 break;
330 case Instruction::MOVE_OBJECT:
331 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200332 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
333 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200334 inst = inst->Next_1xx();
335 break;
336 case Instruction::MOVE_OBJECT_FROM16:
337 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200338 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200339 shadow_frame.GetVRegReference(inst->VRegB_22x()));
340 inst = inst->Next_2xx();
341 break;
342 case Instruction::MOVE_OBJECT_16:
343 PREAMBLE();
344 shadow_frame.SetVRegReference(inst->VRegA_32x(),
345 shadow_frame.GetVRegReference(inst->VRegB_32x()));
346 inst = inst->Next_3xx();
347 break;
348 case Instruction::MOVE_RESULT:
349 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200350 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200351 inst = inst->Next_1xx();
352 break;
353 case Instruction::MOVE_RESULT_WIDE:
354 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200355 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200356 inst = inst->Next_1xx();
357 break;
358 case Instruction::MOVE_RESULT_OBJECT:
Alex Lightfc905672017-06-27 17:53:15 -0700359 PREAMBLE_SAVE(&result_register);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200360 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200361 inst = inst->Next_1xx();
362 break;
363 case Instruction::MOVE_EXCEPTION: {
364 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700365 ObjPtr<mirror::Throwable> exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100366 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100367 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200368 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200369 inst = inst->Next_1xx();
370 break;
371 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700372 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200373 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200374 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700375 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700376 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700377 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
378 !SendMethodExitEvents(self,
379 instrumentation,
380 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800381 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700382 shadow_frame.GetMethod(),
383 inst->GetDexPc(insns),
384 result))) {
385 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200386 }
buzbee1452bee2015-03-06 14:43:04 -0800387 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700388 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700389 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800390 }
David Srbecky946bb092018-03-09 17:23:01 +0000391 ctx->result = result;
392 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200393 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700394 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200395 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700396 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200397 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700398 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700399 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700400 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
401 !SendMethodExitEvents(self,
402 instrumentation,
403 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800404 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700405 shadow_frame.GetMethod(),
406 inst->GetDexPc(insns),
407 result))) {
408 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200409 }
buzbee1452bee2015-03-06 14:43:04 -0800410 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700411 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700412 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800413 }
David Srbecky946bb092018-03-09 17:23:01 +0000414 ctx->result = result;
415 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200416 }
417 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200418 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200419 JValue result;
420 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200421 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700422 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700423 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700424 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
425 !SendMethodExitEvents(self,
426 instrumentation,
427 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800428 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700429 shadow_frame.GetMethod(),
430 inst->GetDexPc(insns),
431 result))) {
432 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200433 }
buzbee1452bee2015-03-06 14:43:04 -0800434 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700435 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700436 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800437 }
David Srbecky946bb092018-03-09 17:23:01 +0000438 ctx->result = result;
439 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200440 }
441 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200442 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200443 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200444 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700445 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700446 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700447 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
448 !SendMethodExitEvents(self,
449 instrumentation,
450 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800451 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700452 shadow_frame.GetMethod(),
453 inst->GetDexPc(insns),
454 result))) {
455 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200456 }
buzbee1452bee2015-03-06 14:43:04 -0800457 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700458 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700459 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800460 }
David Srbecky946bb092018-03-09 17:23:01 +0000461 ctx->result = result;
462 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200463 }
464 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200465 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200466 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700467 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700468 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700469 const size_t ref_idx = inst->VRegA_11x(inst_data);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700470 ObjPtr<mirror::Object> obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700471 if (do_assignability_check && obj_result != nullptr) {
Alex Lightcc917d92018-02-22 13:28:28 -0800472 ObjPtr<mirror::Class> return_type = shadow_frame.GetMethod()->ResolveReturnType();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700473 // Re-load since it might have moved.
474 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700475 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700476 // Return the pending exception.
477 HANDLE_PENDING_EXCEPTION();
478 }
479 if (!obj_result->VerifierInstanceOf(return_type)) {
480 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700481 std::string temp1, temp2;
Orion Hodsonfef06642016-11-25 16:07:11 +0000482 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700483 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700484 obj_result->GetClass()->GetDescriptor(&temp1),
485 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700486 HANDLE_PENDING_EXCEPTION();
487 }
488 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700489 result.SetL(obj_result);
Alex Lighte814f9d2017-07-31 16:14:39 -0700490 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
491 !SendMethodExitEvents(self,
492 instrumentation,
493 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800494 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700495 shadow_frame.GetMethod(),
496 inst->GetDexPc(insns),
497 result))) {
498 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200499 }
Alex Lighte814f9d2017-07-31 16:14:39 -0700500 // Re-load since it might have moved during the MethodExitEvent.
501 result.SetL(shadow_frame.GetVRegReference(ref_idx));
buzbee1452bee2015-03-06 14:43:04 -0800502 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700503 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700504 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800505 }
David Srbecky946bb092018-03-09 17:23:01 +0000506 ctx->result = result;
507 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200508 }
509 case Instruction::CONST_4: {
510 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200511 uint4_t dst = inst->VRegA_11n(inst_data);
512 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200513 shadow_frame.SetVReg(dst, val);
514 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700515 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200516 }
517 inst = inst->Next_1xx();
518 break;
519 }
520 case Instruction::CONST_16: {
521 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200522 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200523 int16_t val = inst->VRegB_21s();
524 shadow_frame.SetVReg(dst, val);
525 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700526 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200527 }
528 inst = inst->Next_2xx();
529 break;
530 }
531 case Instruction::CONST: {
532 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200533 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200534 int32_t val = inst->VRegB_31i();
535 shadow_frame.SetVReg(dst, val);
536 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700537 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200538 }
539 inst = inst->Next_3xx();
540 break;
541 }
542 case Instruction::CONST_HIGH16: {
543 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200544 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200545 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
546 shadow_frame.SetVReg(dst, val);
547 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700548 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200549 }
550 inst = inst->Next_2xx();
551 break;
552 }
553 case Instruction::CONST_WIDE_16:
554 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200555 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200556 inst = inst->Next_2xx();
557 break;
558 case Instruction::CONST_WIDE_32:
559 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200560 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200561 inst = inst->Next_3xx();
562 break;
563 case Instruction::CONST_WIDE:
564 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200565 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200566 inst = inst->Next_51l();
567 break;
568 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200569 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200570 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200571 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
572 inst = inst->Next_2xx();
573 break;
574 case Instruction::CONST_STRING: {
575 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800576 ObjPtr<mirror::String> s = ResolveString(self,
577 shadow_frame,
578 dex::StringIndex(inst->VRegB_21c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700579 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200580 HANDLE_PENDING_EXCEPTION();
581 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100582 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200583 inst = inst->Next_2xx();
584 }
585 break;
586 }
587 case Instruction::CONST_STRING_JUMBO: {
588 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800589 ObjPtr<mirror::String> s = ResolveString(self,
590 shadow_frame,
591 dex::StringIndex(inst->VRegB_31c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700592 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200593 HANDLE_PENDING_EXCEPTION();
594 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100595 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200596 inst = inst->Next_3xx();
597 }
598 break;
599 }
600 case Instruction::CONST_CLASS: {
601 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800602 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700603 shadow_frame.GetMethod(),
604 self,
605 false,
606 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700607 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200608 HANDLE_PENDING_EXCEPTION();
609 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100610 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200611 inst = inst->Next_2xx();
612 }
613 break;
614 }
Orion Hodson2e599942017-09-22 16:17:41 +0100615 case Instruction::CONST_METHOD_HANDLE: {
616 PREAMBLE();
Orion Hodsone7732be2017-10-11 14:35:20 +0100617 ClassLinker* cl = Runtime::Current()->GetClassLinker();
Alex Lightcc917d92018-02-22 13:28:28 -0800618 ObjPtr<mirror::MethodHandle> mh = cl->ResolveMethodHandle(self,
619 inst->VRegB_21c(),
620 shadow_frame.GetMethod());
Orion Hodson2e599942017-09-22 16:17:41 +0100621 if (UNLIKELY(mh == nullptr)) {
622 HANDLE_PENDING_EXCEPTION();
623 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100624 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mh);
Orion Hodson2e599942017-09-22 16:17:41 +0100625 inst = inst->Next_2xx();
626 }
627 break;
628 }
629 case Instruction::CONST_METHOD_TYPE: {
630 PREAMBLE();
Orion Hodsone7732be2017-10-11 14:35:20 +0100631 ClassLinker* cl = Runtime::Current()->GetClassLinker();
Alex Lightcc917d92018-02-22 13:28:28 -0800632 ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(self,
Orion Hodson06d10a72018-05-14 08:53:38 +0100633 dex::ProtoIndex(inst->VRegB_21c()),
Alex Lightcc917d92018-02-22 13:28:28 -0800634 shadow_frame.GetMethod());
Orion Hodson2e599942017-09-22 16:17:41 +0100635 if (UNLIKELY(mt == nullptr)) {
636 HANDLE_PENDING_EXCEPTION();
637 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100638 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mt);
Orion Hodson2e599942017-09-22 16:17:41 +0100639 inst = inst->Next_2xx();
640 }
641 break;
642 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200643 case Instruction::MONITOR_ENTER: {
644 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700645 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700646 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700647 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000648 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200649 HANDLE_PENDING_EXCEPTION();
650 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700651 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200652 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
653 }
654 break;
655 }
656 case Instruction::MONITOR_EXIT: {
657 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700658 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700659 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700660 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000661 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200662 HANDLE_PENDING_EXCEPTION();
663 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700664 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200665 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
666 }
667 break;
668 }
669 case Instruction::CHECK_CAST: {
670 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800671 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700672 shadow_frame.GetMethod(),
673 self,
674 false,
675 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700676 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200677 HANDLE_PENDING_EXCEPTION();
678 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700679 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700680 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200681 ThrowClassCastException(c, obj->GetClass());
682 HANDLE_PENDING_EXCEPTION();
683 } else {
684 inst = inst->Next_2xx();
685 }
686 }
687 break;
688 }
689 case Instruction::INSTANCE_OF: {
690 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800691 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegC_22c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700692 shadow_frame.GetMethod(),
693 self,
694 false,
695 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700696 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200697 HANDLE_PENDING_EXCEPTION();
698 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700699 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700700 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
701 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200702 inst = inst->Next_2xx();
703 }
704 break;
705 }
706 case Instruction::ARRAY_LENGTH: {
707 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700708 ObjPtr<mirror::Object> array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700709 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000710 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200711 HANDLE_PENDING_EXCEPTION();
712 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200713 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200714 inst = inst->Next_1xx();
715 }
716 break;
717 }
718 case Instruction::NEW_INSTANCE: {
719 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700720 ObjPtr<mirror::Object> obj = nullptr;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800721 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700722 shadow_frame.GetMethod(),
723 self,
724 false,
725 do_access_check);
Jeff Hao848f70a2014-01-15 13:49:50 -0800726 if (LIKELY(c != nullptr)) {
727 if (UNLIKELY(c->IsStringClass())) {
728 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700729 obj = mirror::String::AllocEmptyString<true>(self, allocator_type);
Jeff Hao848f70a2014-01-15 13:49:50 -0800730 } else {
Nicolas Geoffray0d3998b2017-01-12 15:35:12 +0000731 obj = AllocObjectFromCode<true>(
732 c.Ptr(),
Andreas Gampea5b09a62016-11-17 15:21:22 -0800733 self,
734 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Jeff Hao848f70a2014-01-15 13:49:50 -0800735 }
736 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700737 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200738 HANDLE_PENDING_EXCEPTION();
739 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200740 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700741 // Don't allow finalizable objects to be allocated during a transaction since these can't
742 // be finalized without a started runtime.
743 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200744 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
David Sehr709b0702016-10-13 09:12:37 -0700745 obj->PrettyTypeOf().c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700746 HANDLE_PENDING_EXCEPTION();
747 break;
748 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100749 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200750 inst = inst->Next_2xx();
751 }
752 break;
753 }
754 case Instruction::NEW_ARRAY: {
755 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200756 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartieref41db72016-10-25 15:08:01 -0700757 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800758 dex::TypeIndex(inst->VRegC_22c()),
759 length,
760 shadow_frame.GetMethod(),
761 self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800762 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700763 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200764 HANDLE_PENDING_EXCEPTION();
765 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100766 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200767 inst = inst->Next_2xx();
768 }
769 break;
770 }
771 case Instruction::FILLED_NEW_ARRAY: {
772 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100773 bool success =
774 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
775 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200776 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
777 break;
778 }
779 case Instruction::FILLED_NEW_ARRAY_RANGE: {
780 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100781 bool success =
782 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
783 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200784 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
785 break;
786 }
787 case Instruction::FILL_ARRAY_DATA: {
788 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200789 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
790 const Instruction::ArrayDataPayload* payload =
791 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700792 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700793 bool success = FillArrayData(obj, payload);
794 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200795 HANDLE_PENDING_EXCEPTION();
796 break;
797 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100798 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700799 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100800 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200801 inst = inst->Next_3xx();
802 break;
803 }
804 case Instruction::THROW: {
805 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700806 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700807 ObjPtr<mirror::Object> exception =
808 shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700809 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000810 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700811 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
812 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700813 std::string temp;
Orion Hodsonfef06642016-11-25 16:07:11 +0000814 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700815 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700816 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200817 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000818 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200819 }
820 HANDLE_PENDING_EXCEPTION();
821 break;
822 }
823 case Instruction::GOTO: {
824 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700825 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200826 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000827 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200828 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800829 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200830 break;
831 }
832 case Instruction::GOTO_16: {
833 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700834 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200835 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000836 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200837 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800838 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200839 break;
840 }
841 case Instruction::GOTO_32: {
842 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700843 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200844 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000845 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200846 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800847 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200848 break;
849 }
850 case Instruction::PACKED_SWITCH: {
851 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200852 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000853 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200854 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800855 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200856 break;
857 }
858 case Instruction::SPARSE_SWITCH: {
859 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200860 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000861 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200862 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800863 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200864 break;
865 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700866
Ian Rogers647b1a82014-10-10 11:02:11 -0700867#pragma clang diagnostic push
868#pragma clang diagnostic ignored "-Wfloat-equal"
Ian Rogers647b1a82014-10-10 11:02:11 -0700869
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200870 case Instruction::CMPL_FLOAT: {
871 PREAMBLE();
872 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
873 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
874 int32_t result;
875 if (val1 > val2) {
876 result = 1;
877 } else if (val1 == val2) {
878 result = 0;
879 } else {
880 result = -1;
881 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200882 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200883 inst = inst->Next_2xx();
884 break;
885 }
886 case Instruction::CMPG_FLOAT: {
887 PREAMBLE();
888 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
889 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
890 int32_t result;
891 if (val1 < val2) {
892 result = -1;
893 } else if (val1 == val2) {
894 result = 0;
895 } else {
896 result = 1;
897 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200898 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200899 inst = inst->Next_2xx();
900 break;
901 }
902 case Instruction::CMPL_DOUBLE: {
903 PREAMBLE();
904 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
905 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
906 int32_t result;
907 if (val1 > val2) {
908 result = 1;
909 } else if (val1 == val2) {
910 result = 0;
911 } else {
912 result = -1;
913 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200914 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200915 inst = inst->Next_2xx();
916 break;
917 }
918
919 case Instruction::CMPG_DOUBLE: {
920 PREAMBLE();
921 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
922 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
923 int32_t result;
924 if (val1 < val2) {
925 result = -1;
926 } else if (val1 == val2) {
927 result = 0;
928 } else {
929 result = 1;
930 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200931 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200932 inst = inst->Next_2xx();
933 break;
934 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700935
Ian Rogers647b1a82014-10-10 11:02:11 -0700936#pragma clang diagnostic pop
Ian Rogers647b1a82014-10-10 11:02:11 -0700937
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200938 case Instruction::CMP_LONG: {
939 PREAMBLE();
940 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
941 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
942 int32_t result;
943 if (val1 > val2) {
944 result = 1;
945 } else if (val1 == val2) {
946 result = 0;
947 } else {
948 result = -1;
949 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200950 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200951 inst = inst->Next_2xx();
952 break;
953 }
954 case Instruction::IF_EQ: {
955 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700956 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) ==
957 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200958 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000959 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200960 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800961 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200962 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800963 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200964 inst = inst->Next_2xx();
965 }
966 break;
967 }
968 case Instruction::IF_NE: {
969 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700970 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) !=
971 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200972 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000973 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200974 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800975 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200976 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800977 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200978 inst = inst->Next_2xx();
979 }
980 break;
981 }
982 case Instruction::IF_LT: {
983 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700984 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <
985 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200986 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000987 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200988 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800989 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200990 } else {
buzbeef1dcacc2016-02-24 14:24:24 -0800991 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200992 inst = inst->Next_2xx();
993 }
994 break;
995 }
996 case Instruction::IF_GE: {
997 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700998 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >=
999 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001000 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001001 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001002 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001003 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001004 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001005 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001006 inst = inst->Next_2xx();
1007 }
1008 break;
1009 }
1010 case Instruction::IF_GT: {
1011 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001012 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) >
1013 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001014 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001015 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001016 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001017 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001018 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001019 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001020 inst = inst->Next_2xx();
1021 }
1022 break;
1023 }
1024 case Instruction::IF_LE: {
1025 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001026 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
1027 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001028 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001029 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001030 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001031 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001032 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001033 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001034 inst = inst->Next_2xx();
1035 }
1036 break;
1037 }
1038 case Instruction::IF_EQZ: {
1039 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001040 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001041 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001042 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001043 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001044 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001045 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001046 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001047 inst = inst->Next_2xx();
1048 }
1049 break;
1050 }
1051 case Instruction::IF_NEZ: {
1052 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001053 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001054 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001055 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001056 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001057 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001058 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001059 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001060 inst = inst->Next_2xx();
1061 }
1062 break;
1063 }
1064 case Instruction::IF_LTZ: {
1065 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001066 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001067 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001068 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001069 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001070 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001071 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001072 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001073 inst = inst->Next_2xx();
1074 }
1075 break;
1076 }
1077 case Instruction::IF_GEZ: {
1078 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001079 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001080 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001081 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001082 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001083 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001084 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001085 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001086 inst = inst->Next_2xx();
1087 }
1088 break;
1089 }
1090 case Instruction::IF_GTZ: {
1091 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001092 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001093 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001094 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001095 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001096 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001097 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001098 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001099 inst = inst->Next_2xx();
1100 }
1101 break;
1102 }
1103 case Instruction::IF_LEZ: {
1104 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001105 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001106 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001107 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001108 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001109 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001110 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001111 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001112 inst = inst->Next_2xx();
1113 }
1114 break;
1115 }
1116 case Instruction::AGET_BOOLEAN: {
1117 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001118 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001119 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001120 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001121 HANDLE_PENDING_EXCEPTION();
1122 break;
1123 }
1124 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001125 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001126 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001127 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001128 inst = inst->Next_2xx();
1129 } else {
1130 HANDLE_PENDING_EXCEPTION();
1131 }
1132 break;
1133 }
1134 case Instruction::AGET_BYTE: {
1135 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001136 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001137 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001138 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001139 HANDLE_PENDING_EXCEPTION();
1140 break;
1141 }
1142 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001143 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001144 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001145 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001146 inst = inst->Next_2xx();
1147 } else {
1148 HANDLE_PENDING_EXCEPTION();
1149 }
1150 break;
1151 }
1152 case Instruction::AGET_CHAR: {
1153 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001154 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001155 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001156 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001157 HANDLE_PENDING_EXCEPTION();
1158 break;
1159 }
1160 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001161 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001162 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001163 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001164 inst = inst->Next_2xx();
1165 } else {
1166 HANDLE_PENDING_EXCEPTION();
1167 }
1168 break;
1169 }
1170 case Instruction::AGET_SHORT: {
1171 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001172 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001173 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001174 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001175 HANDLE_PENDING_EXCEPTION();
1176 break;
1177 }
1178 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001179 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001180 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001181 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001182 inst = inst->Next_2xx();
1183 } else {
1184 HANDLE_PENDING_EXCEPTION();
1185 }
1186 break;
1187 }
1188 case Instruction::AGET: {
1189 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001190 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001191 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001192 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001193 HANDLE_PENDING_EXCEPTION();
1194 break;
1195 }
1196 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001197 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001198 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001199 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001200 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001201 inst = inst->Next_2xx();
1202 } else {
1203 HANDLE_PENDING_EXCEPTION();
1204 }
1205 break;
1206 }
1207 case Instruction::AGET_WIDE: {
1208 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001209 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001210 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001211 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001212 HANDLE_PENDING_EXCEPTION();
1213 break;
1214 }
1215 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001216 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001217 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001218 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001219 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001220 inst = inst->Next_2xx();
1221 } else {
1222 HANDLE_PENDING_EXCEPTION();
1223 }
1224 break;
1225 }
1226 case Instruction::AGET_OBJECT: {
1227 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001228 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001229 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001230 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001231 HANDLE_PENDING_EXCEPTION();
1232 break;
1233 }
1234 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001235 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001236 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001237 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001238 inst = inst->Next_2xx();
1239 } else {
1240 HANDLE_PENDING_EXCEPTION();
1241 }
1242 break;
1243 }
1244 case Instruction::APUT_BOOLEAN: {
1245 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001246 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001247 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001248 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001249 HANDLE_PENDING_EXCEPTION();
1250 break;
1251 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001252 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001253 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001254 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001255 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001256 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001257 inst = inst->Next_2xx();
1258 } else {
1259 HANDLE_PENDING_EXCEPTION();
1260 }
1261 break;
1262 }
1263 case Instruction::APUT_BYTE: {
1264 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001265 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001266 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001267 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001268 HANDLE_PENDING_EXCEPTION();
1269 break;
1270 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001271 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001272 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001273 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001274 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001275 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001276 inst = inst->Next_2xx();
1277 } else {
1278 HANDLE_PENDING_EXCEPTION();
1279 }
1280 break;
1281 }
1282 case Instruction::APUT_CHAR: {
1283 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001284 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001285 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001286 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001287 HANDLE_PENDING_EXCEPTION();
1288 break;
1289 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001290 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001291 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001292 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001293 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001294 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001295 inst = inst->Next_2xx();
1296 } else {
1297 HANDLE_PENDING_EXCEPTION();
1298 }
1299 break;
1300 }
1301 case Instruction::APUT_SHORT: {
1302 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001303 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001304 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001305 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001306 HANDLE_PENDING_EXCEPTION();
1307 break;
1308 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001309 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001310 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001311 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001312 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001313 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001314 inst = inst->Next_2xx();
1315 } else {
1316 HANDLE_PENDING_EXCEPTION();
1317 }
1318 break;
1319 }
1320 case Instruction::APUT: {
1321 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001322 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001323 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001324 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001325 HANDLE_PENDING_EXCEPTION();
1326 break;
1327 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001328 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001329 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001330 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001331 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001332 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001333 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001334 inst = inst->Next_2xx();
1335 } else {
1336 HANDLE_PENDING_EXCEPTION();
1337 }
1338 break;
1339 }
1340 case Instruction::APUT_WIDE: {
1341 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001342 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001343 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001344 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001345 HANDLE_PENDING_EXCEPTION();
1346 break;
1347 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001348 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001349 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001350 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001351 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001352 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001353 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001354 inst = inst->Next_2xx();
1355 } else {
1356 HANDLE_PENDING_EXCEPTION();
1357 }
1358 break;
1359 }
1360 case Instruction::APUT_OBJECT: {
1361 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001362 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001363 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001364 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001365 HANDLE_PENDING_EXCEPTION();
1366 break;
1367 }
1368 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001369 ObjPtr<mirror::Object> val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
1370 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001371 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001372 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001373 inst = inst->Next_2xx();
1374 } else {
1375 HANDLE_PENDING_EXCEPTION();
1376 }
1377 break;
1378 }
1379 case Instruction::IGET_BOOLEAN: {
1380 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001381 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1382 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001383 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1384 break;
1385 }
1386 case Instruction::IGET_BYTE: {
1387 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001388 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1389 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001390 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1391 break;
1392 }
1393 case Instruction::IGET_CHAR: {
1394 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001395 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1396 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001397 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1398 break;
1399 }
1400 case Instruction::IGET_SHORT: {
1401 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001402 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1403 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001404 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1405 break;
1406 }
1407 case Instruction::IGET: {
1408 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001409 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1410 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001411 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1412 break;
1413 }
1414 case Instruction::IGET_WIDE: {
1415 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001416 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1417 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001418 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1419 break;
1420 }
1421 case Instruction::IGET_OBJECT: {
1422 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001423 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1424 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001425 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1426 break;
1427 }
1428 case Instruction::IGET_QUICK: {
1429 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001430 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001431 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1432 break;
1433 }
1434 case Instruction::IGET_WIDE_QUICK: {
1435 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001436 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001437 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1438 break;
1439 }
1440 case Instruction::IGET_OBJECT_QUICK: {
1441 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001442 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001443 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1444 break;
1445 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001446 case Instruction::IGET_BOOLEAN_QUICK: {
1447 PREAMBLE();
1448 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1449 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1450 break;
1451 }
1452 case Instruction::IGET_BYTE_QUICK: {
1453 PREAMBLE();
1454 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1455 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1456 break;
1457 }
1458 case Instruction::IGET_CHAR_QUICK: {
1459 PREAMBLE();
1460 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1461 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1462 break;
1463 }
1464 case Instruction::IGET_SHORT_QUICK: {
1465 PREAMBLE();
1466 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1467 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1468 break;
1469 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001470 case Instruction::SGET_BOOLEAN: {
1471 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001472 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check,
1473 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001474 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1475 break;
1476 }
1477 case Instruction::SGET_BYTE: {
1478 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001479 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check,
1480 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001481 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1482 break;
1483 }
1484 case Instruction::SGET_CHAR: {
1485 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001486 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check,
1487 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001488 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1489 break;
1490 }
1491 case Instruction::SGET_SHORT: {
1492 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001493 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check,
1494 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001495 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1496 break;
1497 }
1498 case Instruction::SGET: {
1499 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001500 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check,
1501 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001502 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1503 break;
1504 }
1505 case Instruction::SGET_WIDE: {
1506 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001507 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check,
1508 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001509 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1510 break;
1511 }
1512 case Instruction::SGET_OBJECT: {
1513 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001514 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check,
1515 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001516 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1517 break;
1518 }
1519 case Instruction::IPUT_BOOLEAN: {
1520 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001521 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1522 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001523 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1524 break;
1525 }
1526 case Instruction::IPUT_BYTE: {
1527 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001528 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1529 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001530 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1531 break;
1532 }
1533 case Instruction::IPUT_CHAR: {
1534 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001535 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1536 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001537 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1538 break;
1539 }
1540 case Instruction::IPUT_SHORT: {
1541 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001542 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1543 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001544 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1545 break;
1546 }
1547 case Instruction::IPUT: {
1548 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001549 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1550 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001551 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1552 break;
1553 }
1554 case Instruction::IPUT_WIDE: {
1555 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001556 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1557 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001558 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1559 break;
1560 }
1561 case Instruction::IPUT_OBJECT: {
1562 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001563 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1564 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001565 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1566 break;
1567 }
1568 case Instruction::IPUT_QUICK: {
1569 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001570 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1571 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001572 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1573 break;
1574 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001575 case Instruction::IPUT_BOOLEAN_QUICK: {
1576 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001577 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1578 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001579 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1580 break;
1581 }
1582 case Instruction::IPUT_BYTE_QUICK: {
1583 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001584 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1585 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001586 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1587 break;
1588 }
1589 case Instruction::IPUT_CHAR_QUICK: {
1590 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001591 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1592 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001593 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1594 break;
1595 }
1596 case Instruction::IPUT_SHORT_QUICK: {
1597 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001598 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1599 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001600 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1601 break;
1602 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001603 case Instruction::IPUT_WIDE_QUICK: {
1604 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001605 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1606 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001607 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1608 break;
1609 }
1610 case Instruction::IPUT_OBJECT_QUICK: {
1611 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001612 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1613 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001614 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1615 break;
1616 }
1617 case Instruction::SPUT_BOOLEAN: {
1618 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001619 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1620 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001621 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1622 break;
1623 }
1624 case Instruction::SPUT_BYTE: {
1625 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001626 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1627 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001628 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1629 break;
1630 }
1631 case Instruction::SPUT_CHAR: {
1632 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001633 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1634 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001635 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1636 break;
1637 }
1638 case Instruction::SPUT_SHORT: {
1639 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001640 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1641 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001642 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1643 break;
1644 }
1645 case Instruction::SPUT: {
1646 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001647 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1648 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001649 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1650 break;
1651 }
1652 case Instruction::SPUT_WIDE: {
1653 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001654 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1655 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001656 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1657 break;
1658 }
1659 case Instruction::SPUT_OBJECT: {
1660 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001661 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1662 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001663 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1664 break;
1665 }
1666 case Instruction::INVOKE_VIRTUAL: {
1667 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001668 bool success = DoInvoke<kVirtual, false, do_access_check>(
1669 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001670 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001671 break;
1672 }
1673 case Instruction::INVOKE_VIRTUAL_RANGE: {
1674 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001675 bool success = DoInvoke<kVirtual, true, do_access_check>(
1676 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001677 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001678 break;
1679 }
1680 case Instruction::INVOKE_SUPER: {
1681 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001682 bool success = DoInvoke<kSuper, false, do_access_check>(
1683 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001684 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001685 break;
1686 }
1687 case Instruction::INVOKE_SUPER_RANGE: {
1688 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001689 bool success = DoInvoke<kSuper, true, do_access_check>(
1690 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001691 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001692 break;
1693 }
1694 case Instruction::INVOKE_DIRECT: {
1695 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001696 bool success = DoInvoke<kDirect, false, do_access_check>(
1697 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001698 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001699 break;
1700 }
1701 case Instruction::INVOKE_DIRECT_RANGE: {
1702 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001703 bool success = DoInvoke<kDirect, true, do_access_check>(
1704 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001705 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001706 break;
1707 }
1708 case Instruction::INVOKE_INTERFACE: {
1709 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001710 bool success = DoInvoke<kInterface, false, do_access_check>(
1711 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001712 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001713 break;
1714 }
1715 case Instruction::INVOKE_INTERFACE_RANGE: {
1716 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001717 bool success = DoInvoke<kInterface, true, do_access_check>(
1718 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001719 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001720 break;
1721 }
1722 case Instruction::INVOKE_STATIC: {
1723 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001724 bool success = DoInvoke<kStatic, false, do_access_check>(
1725 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001726 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001727 break;
1728 }
1729 case Instruction::INVOKE_STATIC_RANGE: {
1730 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001731 bool success = DoInvoke<kStatic, true, do_access_check>(
1732 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001733 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001734 break;
1735 }
1736 case Instruction::INVOKE_VIRTUAL_QUICK: {
1737 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001738 bool success = DoInvokeVirtualQuick<false>(
1739 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001740 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001741 break;
1742 }
1743 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1744 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001745 bool success = DoInvokeVirtualQuick<true>(
1746 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001747 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001748 break;
1749 }
Narayan Kamath9823e782016-08-03 12:46:58 +01001750 case Instruction::INVOKE_POLYMORPHIC: {
1751 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001752 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Orion Hodsonc069a302017-01-18 09:23:12 +00001753 bool success = DoInvokePolymorphic<false /* is_range */>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001754 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001755 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
Narayan Kamath9823e782016-08-03 12:46:58 +01001756 break;
1757 }
1758 case Instruction::INVOKE_POLYMORPHIC_RANGE: {
1759 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001760 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Orion Hodsonc069a302017-01-18 09:23:12 +00001761 bool success = DoInvokePolymorphic<true /* is_range */>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001762 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001763 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
Narayan Kamath9823e782016-08-03 12:46:58 +01001764 break;
Narayan Kamath9823e782016-08-03 12:46:58 +01001765 }
Orion Hodsonc069a302017-01-18 09:23:12 +00001766 case Instruction::INVOKE_CUSTOM: {
1767 PREAMBLE();
1768 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1769 bool success = DoInvokeCustom<false /* is_range */>(
1770 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001771 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Orion Hodsonc069a302017-01-18 09:23:12 +00001772 break;
1773 }
1774 case Instruction::INVOKE_CUSTOM_RANGE: {
1775 PREAMBLE();
1776 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1777 bool success = DoInvokeCustom<true /* is_range */>(
1778 self, shadow_frame, inst, inst_data, &result_register);
Alex Light88a2a9d2018-03-14 14:44:29 -07001779 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Orion Hodsonc069a302017-01-18 09:23:12 +00001780 break;
1781 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001782 case Instruction::NEG_INT:
1783 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001784 shadow_frame.SetVReg(
1785 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001786 inst = inst->Next_1xx();
1787 break;
1788 case Instruction::NOT_INT:
1789 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001790 shadow_frame.SetVReg(
1791 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001792 inst = inst->Next_1xx();
1793 break;
1794 case Instruction::NEG_LONG:
1795 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001796 shadow_frame.SetVRegLong(
1797 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001798 inst = inst->Next_1xx();
1799 break;
1800 case Instruction::NOT_LONG:
1801 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001802 shadow_frame.SetVRegLong(
1803 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001804 inst = inst->Next_1xx();
1805 break;
1806 case Instruction::NEG_FLOAT:
1807 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001808 shadow_frame.SetVRegFloat(
1809 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001810 inst = inst->Next_1xx();
1811 break;
1812 case Instruction::NEG_DOUBLE:
1813 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001814 shadow_frame.SetVRegDouble(
1815 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001816 inst = inst->Next_1xx();
1817 break;
1818 case Instruction::INT_TO_LONG:
1819 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001820 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1821 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001822 inst = inst->Next_1xx();
1823 break;
1824 case Instruction::INT_TO_FLOAT:
1825 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001826 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1827 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001828 inst = inst->Next_1xx();
1829 break;
1830 case Instruction::INT_TO_DOUBLE:
1831 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001832 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1833 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001834 inst = inst->Next_1xx();
1835 break;
1836 case Instruction::LONG_TO_INT:
1837 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001838 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1839 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001840 inst = inst->Next_1xx();
1841 break;
1842 case Instruction::LONG_TO_FLOAT:
1843 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001844 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1845 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001846 inst = inst->Next_1xx();
1847 break;
1848 case Instruction::LONG_TO_DOUBLE:
1849 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001850 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1851 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001852 inst = inst->Next_1xx();
1853 break;
1854 case Instruction::FLOAT_TO_INT: {
1855 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001856 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001857 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001858 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001859 inst = inst->Next_1xx();
1860 break;
1861 }
1862 case Instruction::FLOAT_TO_LONG: {
1863 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001864 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001865 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001866 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001867 inst = inst->Next_1xx();
1868 break;
1869 }
1870 case Instruction::FLOAT_TO_DOUBLE:
1871 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001872 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1873 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001874 inst = inst->Next_1xx();
1875 break;
1876 case Instruction::DOUBLE_TO_INT: {
1877 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001878 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001879 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001880 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001881 inst = inst->Next_1xx();
1882 break;
1883 }
1884 case Instruction::DOUBLE_TO_LONG: {
1885 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001886 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001887 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001888 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001889 inst = inst->Next_1xx();
1890 break;
1891 }
1892 case Instruction::DOUBLE_TO_FLOAT:
1893 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001894 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1895 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001896 inst = inst->Next_1xx();
1897 break;
1898 case Instruction::INT_TO_BYTE:
1899 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001900 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1901 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001902 inst = inst->Next_1xx();
1903 break;
1904 case Instruction::INT_TO_CHAR:
1905 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001906 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1907 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001908 inst = inst->Next_1xx();
1909 break;
1910 case Instruction::INT_TO_SHORT:
1911 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001912 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1913 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001914 inst = inst->Next_1xx();
1915 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001916 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001917 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001918 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001919 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1920 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001921 inst = inst->Next_2xx();
1922 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001923 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001924 case Instruction::SUB_INT:
1925 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001926 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001927 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1928 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001929 inst = inst->Next_2xx();
1930 break;
1931 case Instruction::MUL_INT:
1932 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001933 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001934 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1935 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001936 inst = inst->Next_2xx();
1937 break;
1938 case Instruction::DIV_INT: {
1939 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001940 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001941 shadow_frame.GetVReg(inst->VRegB_23x()),
1942 shadow_frame.GetVReg(inst->VRegC_23x()));
1943 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1944 break;
1945 }
1946 case Instruction::REM_INT: {
1947 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001948 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001949 shadow_frame.GetVReg(inst->VRegB_23x()),
1950 shadow_frame.GetVReg(inst->VRegC_23x()));
1951 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1952 break;
1953 }
1954 case Instruction::SHL_INT:
1955 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001956 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001957 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1958 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1959 inst = inst->Next_2xx();
1960 break;
1961 case Instruction::SHR_INT:
1962 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001963 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001964 shadow_frame.GetVReg(inst->VRegB_23x()) >>
1965 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1966 inst = inst->Next_2xx();
1967 break;
1968 case Instruction::USHR_INT:
1969 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001970 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001971 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1972 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1973 inst = inst->Next_2xx();
1974 break;
1975 case Instruction::AND_INT:
1976 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001977 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001978 shadow_frame.GetVReg(inst->VRegB_23x()) &
1979 shadow_frame.GetVReg(inst->VRegC_23x()));
1980 inst = inst->Next_2xx();
1981 break;
1982 case Instruction::OR_INT:
1983 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001984 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001985 shadow_frame.GetVReg(inst->VRegB_23x()) |
1986 shadow_frame.GetVReg(inst->VRegC_23x()));
1987 inst = inst->Next_2xx();
1988 break;
1989 case Instruction::XOR_INT:
1990 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001991 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001992 shadow_frame.GetVReg(inst->VRegB_23x()) ^
1993 shadow_frame.GetVReg(inst->VRegC_23x()));
1994 inst = inst->Next_2xx();
1995 break;
1996 case Instruction::ADD_LONG:
1997 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001998 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001999 SafeAdd(shadow_frame.GetVRegLong(inst->VRegB_23x()),
2000 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002001 inst = inst->Next_2xx();
2002 break;
2003 case Instruction::SUB_LONG:
2004 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002005 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002006 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
2007 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002008 inst = inst->Next_2xx();
2009 break;
2010 case Instruction::MUL_LONG:
2011 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002012 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002013 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
2014 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002015 inst = inst->Next_2xx();
2016 break;
2017 case Instruction::DIV_LONG:
2018 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002019 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002020 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002021 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002022 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
2023 break;
2024 case Instruction::REM_LONG:
2025 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002026 DoLongRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002027 shadow_frame.GetVRegLong(inst->VRegB_23x()),
2028 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2029 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
2030 break;
2031 case Instruction::AND_LONG:
2032 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002033 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002034 shadow_frame.GetVRegLong(inst->VRegB_23x()) &
2035 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2036 inst = inst->Next_2xx();
2037 break;
2038 case Instruction::OR_LONG:
2039 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002040 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002041 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
2042 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2043 inst = inst->Next_2xx();
2044 break;
2045 case Instruction::XOR_LONG:
2046 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002047 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002048 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^
2049 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2050 inst = inst->Next_2xx();
2051 break;
2052 case Instruction::SHL_LONG:
2053 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002054 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002055 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
2056 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2057 inst = inst->Next_2xx();
2058 break;
2059 case Instruction::SHR_LONG:
2060 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002061 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002062 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
2063 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2064 inst = inst->Next_2xx();
2065 break;
2066 case Instruction::USHR_LONG:
2067 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002068 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002069 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
2070 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2071 inst = inst->Next_2xx();
2072 break;
2073 case Instruction::ADD_FLOAT:
2074 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002075 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002076 shadow_frame.GetVRegFloat(inst->VRegB_23x()) +
2077 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2078 inst = inst->Next_2xx();
2079 break;
2080 case Instruction::SUB_FLOAT:
2081 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002082 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002083 shadow_frame.GetVRegFloat(inst->VRegB_23x()) -
2084 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2085 inst = inst->Next_2xx();
2086 break;
2087 case Instruction::MUL_FLOAT:
2088 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002089 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002090 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
2091 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2092 inst = inst->Next_2xx();
2093 break;
2094 case Instruction::DIV_FLOAT:
2095 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002096 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002097 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
2098 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2099 inst = inst->Next_2xx();
2100 break;
2101 case Instruction::REM_FLOAT:
2102 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002103 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002104 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
2105 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
2106 inst = inst->Next_2xx();
2107 break;
2108 case Instruction::ADD_DOUBLE:
2109 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002110 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002111 shadow_frame.GetVRegDouble(inst->VRegB_23x()) +
2112 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2113 inst = inst->Next_2xx();
2114 break;
2115 case Instruction::SUB_DOUBLE:
2116 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002117 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002118 shadow_frame.GetVRegDouble(inst->VRegB_23x()) -
2119 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2120 inst = inst->Next_2xx();
2121 break;
2122 case Instruction::MUL_DOUBLE:
2123 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002124 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002125 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
2126 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2127 inst = inst->Next_2xx();
2128 break;
2129 case Instruction::DIV_DOUBLE:
2130 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002131 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002132 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2133 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2134 inst = inst->Next_2xx();
2135 break;
2136 case Instruction::REM_DOUBLE:
2137 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002138 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002139 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2140 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2141 inst = inst->Next_2xx();
2142 break;
2143 case Instruction::ADD_INT_2ADDR: {
2144 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002145 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07002146 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
2147 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002148 inst = inst->Next_1xx();
2149 break;
2150 }
2151 case Instruction::SUB_INT_2ADDR: {
2152 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002153 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002154 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002155 SafeSub(shadow_frame.GetVReg(vregA),
2156 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002157 inst = inst->Next_1xx();
2158 break;
2159 }
2160 case Instruction::MUL_INT_2ADDR: {
2161 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002162 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002163 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002164 SafeMul(shadow_frame.GetVReg(vregA),
2165 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002166 inst = inst->Next_1xx();
2167 break;
2168 }
2169 case Instruction::DIV_INT_2ADDR: {
2170 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002171 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002172 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002173 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002174 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2175 break;
2176 }
2177 case Instruction::REM_INT_2ADDR: {
2178 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002179 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002180 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002181 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002182 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2183 break;
2184 }
2185 case Instruction::SHL_INT_2ADDR: {
2186 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002187 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002188 shadow_frame.SetVReg(vregA,
2189 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002190 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002191 inst = inst->Next_1xx();
2192 break;
2193 }
2194 case Instruction::SHR_INT_2ADDR: {
2195 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002196 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002197 shadow_frame.SetVReg(vregA,
2198 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002199 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002200 inst = inst->Next_1xx();
2201 break;
2202 }
2203 case Instruction::USHR_INT_2ADDR: {
2204 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002205 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002206 shadow_frame.SetVReg(vregA,
2207 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002208 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002209 inst = inst->Next_1xx();
2210 break;
2211 }
2212 case Instruction::AND_INT_2ADDR: {
2213 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002214 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002215 shadow_frame.SetVReg(vregA,
2216 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002217 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002218 inst = inst->Next_1xx();
2219 break;
2220 }
2221 case Instruction::OR_INT_2ADDR: {
2222 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002223 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002224 shadow_frame.SetVReg(vregA,
2225 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002226 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002227 inst = inst->Next_1xx();
2228 break;
2229 }
2230 case Instruction::XOR_INT_2ADDR: {
2231 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002232 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002233 shadow_frame.SetVReg(vregA,
2234 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002235 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002236 inst = inst->Next_1xx();
2237 break;
2238 }
2239 case Instruction::ADD_LONG_2ADDR: {
2240 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002241 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002242 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002243 SafeAdd(shadow_frame.GetVRegLong(vregA),
2244 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002245 inst = inst->Next_1xx();
2246 break;
2247 }
2248 case Instruction::SUB_LONG_2ADDR: {
2249 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002250 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002251 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002252 SafeSub(shadow_frame.GetVRegLong(vregA),
2253 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002254 inst = inst->Next_1xx();
2255 break;
2256 }
2257 case Instruction::MUL_LONG_2ADDR: {
2258 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002259 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002260 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002261 SafeMul(shadow_frame.GetVRegLong(vregA),
2262 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002263 inst = inst->Next_1xx();
2264 break;
2265 }
2266 case Instruction::DIV_LONG_2ADDR: {
2267 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002268 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002269 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002270 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002271 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2272 break;
2273 }
2274 case Instruction::REM_LONG_2ADDR: {
2275 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002276 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002277 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002278 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002279 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2280 break;
2281 }
2282 case Instruction::AND_LONG_2ADDR: {
2283 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002284 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002285 shadow_frame.SetVRegLong(vregA,
2286 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002287 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002288 inst = inst->Next_1xx();
2289 break;
2290 }
2291 case Instruction::OR_LONG_2ADDR: {
2292 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002293 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002294 shadow_frame.SetVRegLong(vregA,
2295 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002296 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002297 inst = inst->Next_1xx();
2298 break;
2299 }
2300 case Instruction::XOR_LONG_2ADDR: {
2301 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002302 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002303 shadow_frame.SetVRegLong(vregA,
2304 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002305 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002306 inst = inst->Next_1xx();
2307 break;
2308 }
2309 case Instruction::SHL_LONG_2ADDR: {
2310 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002311 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002312 shadow_frame.SetVRegLong(vregA,
2313 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002314 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002315 inst = inst->Next_1xx();
2316 break;
2317 }
2318 case Instruction::SHR_LONG_2ADDR: {
2319 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002320 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002321 shadow_frame.SetVRegLong(vregA,
2322 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002323 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002324 inst = inst->Next_1xx();
2325 break;
2326 }
2327 case Instruction::USHR_LONG_2ADDR: {
2328 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002329 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002330 shadow_frame.SetVRegLong(vregA,
2331 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002332 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002333 inst = inst->Next_1xx();
2334 break;
2335 }
2336 case Instruction::ADD_FLOAT_2ADDR: {
2337 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002338 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002339 shadow_frame.SetVRegFloat(vregA,
2340 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002341 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002342 inst = inst->Next_1xx();
2343 break;
2344 }
2345 case Instruction::SUB_FLOAT_2ADDR: {
2346 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002347 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002348 shadow_frame.SetVRegFloat(vregA,
2349 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002350 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002351 inst = inst->Next_1xx();
2352 break;
2353 }
2354 case Instruction::MUL_FLOAT_2ADDR: {
2355 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002356 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002357 shadow_frame.SetVRegFloat(vregA,
2358 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002359 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002360 inst = inst->Next_1xx();
2361 break;
2362 }
2363 case Instruction::DIV_FLOAT_2ADDR: {
2364 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002365 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002366 shadow_frame.SetVRegFloat(vregA,
2367 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002368 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002369 inst = inst->Next_1xx();
2370 break;
2371 }
2372 case Instruction::REM_FLOAT_2ADDR: {
2373 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002374 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002375 shadow_frame.SetVRegFloat(vregA,
2376 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002377 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002378 inst = inst->Next_1xx();
2379 break;
2380 }
2381 case Instruction::ADD_DOUBLE_2ADDR: {
2382 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002383 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002384 shadow_frame.SetVRegDouble(vregA,
2385 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002386 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002387 inst = inst->Next_1xx();
2388 break;
2389 }
2390 case Instruction::SUB_DOUBLE_2ADDR: {
2391 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002392 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002393 shadow_frame.SetVRegDouble(vregA,
2394 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002395 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002396 inst = inst->Next_1xx();
2397 break;
2398 }
2399 case Instruction::MUL_DOUBLE_2ADDR: {
2400 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002401 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002402 shadow_frame.SetVRegDouble(vregA,
2403 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002404 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002405 inst = inst->Next_1xx();
2406 break;
2407 }
2408 case Instruction::DIV_DOUBLE_2ADDR: {
2409 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002410 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002411 shadow_frame.SetVRegDouble(vregA,
2412 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002413 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002414 inst = inst->Next_1xx();
2415 break;
2416 }
2417 case Instruction::REM_DOUBLE_2ADDR: {
2418 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002419 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002420 shadow_frame.SetVRegDouble(vregA,
2421 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002422 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002423 inst = inst->Next_1xx();
2424 break;
2425 }
2426 case Instruction::ADD_INT_LIT16:
2427 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002428 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002429 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2430 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002431 inst = inst->Next_2xx();
2432 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002433 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002434 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002435 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002436 SafeSub(inst->VRegC_22s(),
2437 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002438 inst = inst->Next_2xx();
2439 break;
2440 case Instruction::MUL_INT_LIT16:
2441 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002442 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002443 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2444 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002445 inst = inst->Next_2xx();
2446 break;
2447 case Instruction::DIV_INT_LIT16: {
2448 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002449 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002450 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2451 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002452 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2453 break;
2454 }
2455 case Instruction::REM_INT_LIT16: {
2456 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002457 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002458 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2459 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002460 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2461 break;
2462 }
2463 case Instruction::AND_INT_LIT16:
2464 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002465 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2466 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) &
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002467 inst->VRegC_22s());
2468 inst = inst->Next_2xx();
2469 break;
2470 case Instruction::OR_INT_LIT16:
2471 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002472 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2473 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002474 inst->VRegC_22s());
2475 inst = inst->Next_2xx();
2476 break;
2477 case Instruction::XOR_INT_LIT16:
2478 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002479 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2480 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002481 inst->VRegC_22s());
2482 inst = inst->Next_2xx();
2483 break;
2484 case Instruction::ADD_INT_LIT8:
2485 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002486 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002487 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002488 inst = inst->Next_2xx();
2489 break;
2490 case Instruction::RSUB_INT_LIT8:
2491 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002492 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002493 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002494 inst = inst->Next_2xx();
2495 break;
2496 case Instruction::MUL_INT_LIT8:
2497 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002498 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002499 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002500 inst = inst->Next_2xx();
2501 break;
2502 case Instruction::DIV_INT_LIT8: {
2503 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002504 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002505 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2506 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2507 break;
2508 }
2509 case Instruction::REM_INT_LIT8: {
2510 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002511 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002512 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2513 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2514 break;
2515 }
2516 case Instruction::AND_INT_LIT8:
2517 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002518 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002519 shadow_frame.GetVReg(inst->VRegB_22b()) &
2520 inst->VRegC_22b());
2521 inst = inst->Next_2xx();
2522 break;
2523 case Instruction::OR_INT_LIT8:
2524 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002525 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002526 shadow_frame.GetVReg(inst->VRegB_22b()) |
2527 inst->VRegC_22b());
2528 inst = inst->Next_2xx();
2529 break;
2530 case Instruction::XOR_INT_LIT8:
2531 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002532 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002533 shadow_frame.GetVReg(inst->VRegB_22b()) ^
2534 inst->VRegC_22b());
2535 inst = inst->Next_2xx();
2536 break;
2537 case Instruction::SHL_INT_LIT8:
2538 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002539 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002540 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2541 (inst->VRegC_22b() & 0x1f));
2542 inst = inst->Next_2xx();
2543 break;
2544 case Instruction::SHR_INT_LIT8:
2545 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002546 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002547 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2548 (inst->VRegC_22b() & 0x1f));
2549 inst = inst->Next_2xx();
2550 break;
2551 case Instruction::USHR_INT_LIT8:
2552 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002553 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002554 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2555 (inst->VRegC_22b() & 0x1f));
2556 inst = inst->Next_2xx();
2557 break;
2558 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Orion Hodson2e599942017-09-22 16:17:41 +01002559 case Instruction::UNUSED_79 ... Instruction::UNUSED_7A:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002560 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
Ian Rogerse94652f2014-12-02 11:13:19 -08002561 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002562 }
buzbee1452bee2015-03-06 14:43:04 -08002563 } while (!interpret_one_instruction);
2564 // Record where we stopped.
2565 shadow_frame.SetDexPC(inst->GetDexPc(insns));
David Srbecky946bb092018-03-09 17:23:01 +00002566 ctx->result = result_register;
2567 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002568} // NOLINT(readability/fn_size)
2569
David Srbecky946bb092018-03-09 17:23:01 +00002570// Explicit definitions of ExecuteSwitchImplCpp.
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002571template HOT_ATTR
David Srbecky946bb092018-03-09 17:23:01 +00002572void ExecuteSwitchImplCpp<true, false>(SwitchImplContext* ctx);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002573template HOT_ATTR
David Srbecky946bb092018-03-09 17:23:01 +00002574void ExecuteSwitchImplCpp<false, false>(SwitchImplContext* ctx);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002575template
David Srbecky946bb092018-03-09 17:23:01 +00002576void ExecuteSwitchImplCpp<true, true>(SwitchImplContext* ctx);
Andreas Gampe5e26eb12016-08-22 17:54:17 -07002577template
David Srbecky946bb092018-03-09 17:23:01 +00002578void ExecuteSwitchImplCpp<false, true>(SwitchImplContext* ctx);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002579
2580} // namespace interpreter
2581} // namespace art