blob: c430de2b85f79dcd97783c232dc357682931dcb0 [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
David Srbecky2ee09ff2018-10-24 13:24:22 +010017#ifndef ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
18#define ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
19
Andreas Gampe5e26eb12016-08-22 17:54:17 -070020#include "interpreter_switch_impl.h"
21
Andreas Gampe542451c2016-07-26 09:02:02 -070022#include "base/enums.h"
Alex Light6f22e062018-10-05 15:05:12 -070023#include "base/memory_tool.h"
David Sehrc431b9d2018-03-02 12:01:51 -080024#include "base/quasi_atomic.h"
David Sehr9e734c72018-01-04 17:56:19 -080025#include "dex/dex_file_types.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070026#include "experimental_flags.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020027#include "interpreter_common.h"
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +000028#include "jit/jit.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070029#include "jvalue-inl.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000030#include "nth_caller_visitor.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070031#include "safe_math.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010032#include "shadow_frame-inl.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000033#include "thread.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020034
35namespace art {
36namespace interpreter {
37
Alex Light0aa7a5a2018-10-10 15:58:14 +000038#define CHECK_FORCE_RETURN() \
David Srbecky30232c42018-10-26 18:56:01 +010039 { \
Alex Light0aa7a5a2018-10-10 15:58:14 +000040 if (UNLIKELY(shadow_frame.GetForcePopFrame())) { \
41 DCHECK(PrevFrameWillRetry(self, shadow_frame)) \
42 << "Pop frame forced without previous frame ready to retry instruction!"; \
43 DCHECK(Runtime::Current()->AreNonStandardExitsEnabled()); \
44 if (UNLIKELY(NeedsMethodExitEvent(instrumentation))) { \
45 SendMethodExitEvents(self, \
46 instrumentation, \
47 shadow_frame, \
48 shadow_frame.GetThisObject(accessor.InsSize()), \
49 shadow_frame.GetMethod(), \
50 inst->GetDexPc(insns), \
51 JValue()); \
52 } \
53 ctx->result = JValue(); /* Handled in caller. */ \
54 return; \
55 } \
David Srbecky30232c42018-10-26 18:56:01 +010056 } \
57 do {} while (false)
Alex Light0aa7a5a2018-10-10 15:58:14 +000058
Alex Lightb7edcda2017-04-27 13:20:31 -070059#define HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instr) \
David Srbecky30232c42018-10-26 18:56:01 +010060 { \
Sebastien Hertz82aeddb2014-05-20 20:09:45 +020061 DCHECK(self->IsExceptionPending()); \
Ian Rogers7b078e82014-09-10 14:44:24 -070062 self->AllowThreadSuspension(); \
Alex Light0aa7a5a2018-10-10 15:58:14 +000063 CHECK_FORCE_RETURN(); \
Alex Light9fb1ab12017-09-05 09:32:49 -070064 if (!MoveToExceptionHandler(self, shadow_frame, instr)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -070065 /* Structured locking is to be enforced for abnormal termination, too. */ \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -070066 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame); \
buzbee1452bee2015-03-06 14:43:04 -080067 if (interpret_one_instruction) { \
buzbee93e94f22016-04-07 13:52:48 -070068 /* Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -070069 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee1452bee2015-03-06 14:43:04 -080070 } \
David Srbecky946bb092018-03-09 17:23:01 +000071 ctx->result = JValue(); /* Handled in caller. */ \
72 return; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020073 } else { \
Alex Light0aa7a5a2018-10-10 15:58:14 +000074 CHECK_FORCE_RETURN(); \
Alex Light9fb1ab12017-09-05 09:32:49 -070075 int32_t displacement = \
76 static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020077 inst = inst->RelativeAt(displacement); \
David Srbecky30232c42018-10-26 18:56:01 +010078 break; /* Stop executing this opcode and continue in the exception handler. */ \
Sebastien Hertz8ece0502013-08-07 11:26:41 +020079 } \
David Srbecky30232c42018-10-26 18:56:01 +010080 } \
81 do {} while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +020082
Alex Lightb7edcda2017-04-27 13:20:31 -070083#define HANDLE_PENDING_EXCEPTION() HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(instrumentation)
84
Alex Light0aa7a5a2018-10-10 15:58:14 +000085#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, _next_function) \
David Srbecky30232c42018-10-26 18:56:01 +010086 { \
Alex Light0aa7a5a2018-10-10 15:58:14 +000087 if (UNLIKELY(shadow_frame.GetForceRetryInstruction())) { \
88 /* Don't need to do anything except clear the flag and exception. We leave the */ \
89 /* instruction the same so it will be re-executed on the next go-around. */ \
90 DCHECK(inst->IsInvoke()); \
91 shadow_frame.SetForceRetryInstruction(false); \
92 if (UNLIKELY(_is_exception_pending)) { \
93 DCHECK(self->IsExceptionPending()); \
94 if (kIsDebugBuild) { \
95 LOG(WARNING) << "Suppressing exception for instruction-retry: " \
96 << self->GetException()->Dump(); \
97 } \
98 self->ClearException(); \
99 } \
100 } else if (UNLIKELY(_is_exception_pending)) { \
101 /* Should have succeeded. */ \
102 DCHECK(!shadow_frame.GetForceRetryInstruction()); \
103 HANDLE_PENDING_EXCEPTION(); \
104 } else { \
105 inst = inst->_next_function(); \
106 } \
David Srbecky30232c42018-10-26 18:56:01 +0100107 } \
108 do {} while (false)
Alex Light0aa7a5a2018-10-10 15:58:14 +0000109
110#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(_is_exception_pending) \
111 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, Next_4xx)
112#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(_is_exception_pending) \
113 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_IMPL(_is_exception_pending, Next_3xx)
114
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200115#define POSSIBLY_HANDLE_PENDING_EXCEPTION(_is_exception_pending, _next_function) \
David Srbecky30232c42018-10-26 18:56:01 +0100116 { \
Alex Light0aa7a5a2018-10-10 15:58:14 +0000117 /* Should only be on invoke instructions. */ \
118 DCHECK(!shadow_frame.GetForceRetryInstruction()); \
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200119 if (UNLIKELY(_is_exception_pending)) { \
120 HANDLE_PENDING_EXCEPTION(); \
121 } else { \
122 inst = inst->_next_function(); \
123 } \
David Srbecky30232c42018-10-26 18:56:01 +0100124 } \
125 do {} while (false)
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200126
Andreas Gampe03ec9302015-08-27 17:41:47 -0700127#define HANDLE_MONITOR_CHECKS() \
Andreas Gampe56fdd0e2016-04-28 14:56:54 -0700128 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) { \
Andreas Gampe03ec9302015-08-27 17:41:47 -0700129 HANDLE_PENDING_EXCEPTION(); \
130 }
131
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200132// Code to run before each dex instruction.
Alex Light0aa7a5a2018-10-10 15:58:14 +0000133#define PREAMBLE_SAVE(save_ref) \
Alex Lightfc905672017-06-27 17:53:15 -0700134 { \
Alex Light0aa7a5a2018-10-10 15:58:14 +0000135 /* We need to put this before & after the instrumentation to avoid having to put in a */ \
136 /* post-script macro. */ \
137 CHECK_FORCE_RETURN(); \
138 if (UNLIKELY(instrumentation->HasDexPcListeners())) { \
139 if (UNLIKELY(!DoDexPcMoveEvent(self, \
140 accessor, \
141 shadow_frame, \
142 dex_pc, \
143 instrumentation, \
144 save_ref))) { \
145 HANDLE_PENDING_EXCEPTION(); \
146 break; \
147 } \
148 CHECK_FORCE_RETURN(); \
Sebastien Hertz8379b222014-02-24 17:38:15 +0100149 } \
Alex Lightfc905672017-06-27 17:53:15 -0700150 } \
151 do {} while (false)
152
153#define PREAMBLE() PREAMBLE_SAVE(nullptr)
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200154
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000155#define BRANCH_INSTRUMENTATION(offset) \
David Srbecky30232c42018-10-26 18:56:01 +0100156 { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100157 if (UNLIKELY(instrumentation->HasBranchListeners())) { \
Alex Lightcc917d92018-02-22 13:28:28 -0800158 instrumentation->Branch(self, shadow_frame.GetMethod(), dex_pc, offset); \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100159 } \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000160 JValue result; \
Alex Lightcc917d92018-02-22 13:28:28 -0800161 if (jit::Jit::MaybeDoOnStackReplacement(self, \
162 shadow_frame.GetMethod(), \
163 dex_pc, \
164 offset, \
165 &result)) { \
buzbee93e94f22016-04-07 13:52:48 -0700166 if (interpret_one_instruction) { \
167 /* OSR has completed execution of the method. Signal mterp to return to caller */ \
Andreas Gampee2abbc62017-09-15 11:59:26 -0700168 shadow_frame.SetDexPC(dex::kDexNoIndex); \
buzbee93e94f22016-04-07 13:52:48 -0700169 } \
David Srbecky946bb092018-03-09 17:23:01 +0000170 ctx->result = result; \
171 return; \
Nicolas Geoffrayb331feb2016-02-05 16:51:53 +0000172 } \
David Srbecky30232c42018-10-26 18:56:01 +0100173 } \
174 do {} while (false)
Nicolas Geoffray3108daf2015-11-24 16:32:33 +0000175
Bill Buzbee1d011d92016-04-04 16:59:29 +0000176#define HOTNESS_UPDATE() \
David Srbecky30232c42018-10-26 18:56:01 +0100177 { \
Nicolas Geoffray274fe4a2016-04-12 16:33:24 +0100178 if (jit != nullptr) { \
Andreas Gampe98ea9d92018-10-19 14:06:15 -0700179 jit->AddSamples(self, shadow_frame.GetMethod(), 1, /*with_backedges=*/ true); \
Bill Buzbee1d011d92016-04-04 16:59:29 +0000180 } \
David Srbecky30232c42018-10-26 18:56:01 +0100181 } \
182 do {} while (false)
Bill Buzbee1d011d92016-04-04 16:59:29 +0000183
Alex Light848574c2017-09-25 16:59:39 -0700184#define HANDLE_ASYNC_EXCEPTION() \
185 if (UNLIKELY(self->ObserveAsyncException())) { \
186 HANDLE_PENDING_EXCEPTION(); \
Alex Light848574c2017-09-25 16:59:39 -0700187 } \
188 do {} while (false)
189
Andreas Gampef4f76372016-12-13 14:43:58 -0800190#define HANDLE_BACKWARD_BRANCH(offset) \
David Srbecky30232c42018-10-26 18:56:01 +0100191 { \
Andreas Gampef4f76372016-12-13 14:43:58 -0800192 if (IsBackwardBranch(offset)) { \
193 HOTNESS_UPDATE(); \
194 /* Record new dex pc early to have consistent suspend point at loop header. */ \
195 shadow_frame.SetDexPC(inst->GetDexPc(insns)); \
196 self->AllowThreadSuspension(); \
197 } \
David Srbecky30232c42018-10-26 18:56:01 +0100198 } \
199 do {} while (false)
Andreas Gampef4f76372016-12-13 14:43:58 -0800200
Alex Lightfc905672017-06-27 17:53:15 -0700201// Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
202// the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
203// to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
204// jvmti-agents while handling breakpoint or single step events. We had to move this into its own
205// function because it was making ExecuteSwitchImpl have too large a stack.
Alex Light2989a4a2017-06-29 09:44:57 -0700206NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800207 const CodeItemDataAccessor& accessor,
Alex Light2989a4a2017-06-29 09:44:57 -0700208 const ShadowFrame& shadow_frame,
209 uint32_t dex_pc,
210 const instrumentation::Instrumentation* instrumentation,
211 JValue* save_ref)
Alex Lightfc905672017-06-27 17:53:15 -0700212 REQUIRES_SHARED(Locks::mutator_lock_) {
213 DCHECK(instrumentation->HasDexPcListeners());
214 StackHandleScope<2> hs(self);
215 Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
216 mirror::Object* null_obj = nullptr;
217 HandleWrapper<mirror::Object> h(
218 hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
219 self->ClearException();
220 instrumentation->DexPcMovedEvent(self,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800221 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lightfc905672017-06-27 17:53:15 -0700222 shadow_frame.GetMethod(),
223 dex_pc);
224 if (UNLIKELY(self->IsExceptionPending())) {
225 // We got a new exception in the dex-pc-moved event. We just let this exception replace the old
226 // one.
227 // TODO It would be good to add the old exception to the suppressed exceptions of the new one if
228 // possible.
229 return false;
230 } else {
231 if (UNLIKELY(!thr.IsNull())) {
232 self->SetException(thr.Get());
233 }
234 return true;
235 }
236}
237
Alex Lighte814f9d2017-07-31 16:14:39 -0700238static bool NeedsMethodExitEvent(const instrumentation::Instrumentation* ins)
239 REQUIRES_SHARED(Locks::mutator_lock_) {
240 return ins->HasMethodExitListeners() || ins->HasWatchedFramePopListeners();
241}
242
243// Sends the normal method exit event. Returns true if the events succeeded and false if there is a
244// pending exception.
245NO_INLINE static bool SendMethodExitEvents(Thread* self,
246 const instrumentation::Instrumentation* instrumentation,
247 const ShadowFrame& frame,
248 ObjPtr<mirror::Object> thiz,
249 ArtMethod* method,
250 uint32_t dex_pc,
251 const JValue& result)
252 REQUIRES_SHARED(Locks::mutator_lock_) {
253 bool had_event = false;
Alex Light0aa7a5a2018-10-10 15:58:14 +0000254 // We don't send method-exit if it's a pop-frame. We still send frame_popped though.
255 if (UNLIKELY(instrumentation->HasMethodExitListeners() && !frame.GetForcePopFrame())) {
Alex Lighte814f9d2017-07-31 16:14:39 -0700256 had_event = true;
257 instrumentation->MethodExitEvent(self, thiz.Ptr(), method, dex_pc, result);
258 }
259 if (UNLIKELY(frame.NeedsNotifyPop() && instrumentation->HasWatchedFramePopListeners())) {
260 had_event = true;
261 instrumentation->WatchedFramePopped(self, frame);
262 }
263 if (UNLIKELY(had_event)) {
264 return !self->IsExceptionPending();
265 } else {
266 return true;
267 }
268}
269
Alex Light6f22e062018-10-05 15:05:12 -0700270// TODO On ASAN builds this function gets a huge stack frame. Since normally we run in the mterp
271// this shouldn't cause any problems for stack overflow detection. Remove this once b/117341496 is
272// fixed.
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100273template<bool do_access_check, bool transaction_active>
Alex Light6f22e062018-10-05 15:05:12 -0700274ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
David Srbecky946bb092018-03-09 17:23:01 +0000275 Thread* self = ctx->self;
276 const CodeItemDataAccessor& accessor = ctx->accessor;
277 ShadowFrame& shadow_frame = ctx->shadow_frame;
278 JValue result_register = ctx->result_register;
279 bool interpret_one_instruction = ctx->interpret_one_instruction;
Igor Murashkinc449e8b2015-06-10 15:56:42 -0700280 constexpr bool do_assignability_check = do_access_check;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200281 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
282 LOG(FATAL) << "Invalid shadow frame for interpreter use";
David Srbecky946bb092018-03-09 17:23:01 +0000283 ctx->result = JValue();
284 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200285 }
286 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200287
288 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700289 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800290 const uint16_t* const insns = accessor.Insns();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200291 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200292 uint16_t inst_data;
Bill Buzbee1d011d92016-04-04 16:59:29 +0000293 jit::Jit* jit = Runtime::Current()->GetJit();
Igor Murashkin6918bf12015-09-27 19:19:06 -0700294
Alex Light0aa7a5a2018-10-10 15:58:14 +0000295 DCHECK(!shadow_frame.GetForceRetryInstruction())
296 << "Entered interpreter from invoke without retry instruction being handled!";
297
buzbee1452bee2015-03-06 14:43:04 -0800298 do {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200299 dex_pc = inst->GetDexPc(insns);
300 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -0800301 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200302 inst_data = inst->Fetch16(0);
303 switch (inst->Opcode(inst_data)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200304 case Instruction::NOP:
305 PREAMBLE();
306 inst = inst->Next_1xx();
307 break;
308 case Instruction::MOVE:
309 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200310 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
311 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200312 inst = inst->Next_1xx();
313 break;
314 case Instruction::MOVE_FROM16:
315 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200316 shadow_frame.SetVReg(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200317 shadow_frame.GetVReg(inst->VRegB_22x()));
318 inst = inst->Next_2xx();
319 break;
320 case Instruction::MOVE_16:
321 PREAMBLE();
322 shadow_frame.SetVReg(inst->VRegA_32x(),
323 shadow_frame.GetVReg(inst->VRegB_32x()));
324 inst = inst->Next_3xx();
325 break;
326 case Instruction::MOVE_WIDE:
327 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200328 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
329 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200330 inst = inst->Next_1xx();
331 break;
332 case Instruction::MOVE_WIDE_FROM16:
333 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200334 shadow_frame.SetVRegLong(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200335 shadow_frame.GetVRegLong(inst->VRegB_22x()));
336 inst = inst->Next_2xx();
337 break;
338 case Instruction::MOVE_WIDE_16:
339 PREAMBLE();
340 shadow_frame.SetVRegLong(inst->VRegA_32x(),
341 shadow_frame.GetVRegLong(inst->VRegB_32x()));
342 inst = inst->Next_3xx();
343 break;
344 case Instruction::MOVE_OBJECT:
345 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200346 shadow_frame.SetVRegReference(inst->VRegA_12x(inst_data),
347 shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200348 inst = inst->Next_1xx();
349 break;
350 case Instruction::MOVE_OBJECT_FROM16:
351 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200352 shadow_frame.SetVRegReference(inst->VRegA_22x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200353 shadow_frame.GetVRegReference(inst->VRegB_22x()));
354 inst = inst->Next_2xx();
355 break;
356 case Instruction::MOVE_OBJECT_16:
357 PREAMBLE();
358 shadow_frame.SetVRegReference(inst->VRegA_32x(),
359 shadow_frame.GetVRegReference(inst->VRegB_32x()));
360 inst = inst->Next_3xx();
361 break;
362 case Instruction::MOVE_RESULT:
363 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200364 shadow_frame.SetVReg(inst->VRegA_11x(inst_data), result_register.GetI());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200365 inst = inst->Next_1xx();
366 break;
367 case Instruction::MOVE_RESULT_WIDE:
368 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200369 shadow_frame.SetVRegLong(inst->VRegA_11x(inst_data), result_register.GetJ());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200370 inst = inst->Next_1xx();
371 break;
372 case Instruction::MOVE_RESULT_OBJECT:
Alex Lightfc905672017-06-27 17:53:15 -0700373 PREAMBLE_SAVE(&result_register);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200374 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), result_register.GetL());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200375 inst = inst->Next_1xx();
376 break;
377 case Instruction::MOVE_EXCEPTION: {
378 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700379 ObjPtr<mirror::Throwable> exception = self->GetException();
Sebastien Hertz270a0e12015-01-16 19:49:09 +0100380 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100381 shadow_frame.SetVRegReference(inst->VRegA_11x(inst_data), exception);
Sebastien Hertz5c004902014-05-21 10:07:42 +0200382 self->ClearException();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200383 inst = inst->Next_1xx();
384 break;
385 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700386 case Instruction::RETURN_VOID_NO_BARRIER: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200387 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200388 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700389 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700390 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700391 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
392 !SendMethodExitEvents(self,
393 instrumentation,
394 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800395 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700396 shadow_frame.GetMethod(),
397 inst->GetDexPc(insns),
398 result))) {
399 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200400 }
buzbee1452bee2015-03-06 14:43:04 -0800401 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700402 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700403 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800404 }
David Srbecky946bb092018-03-09 17:23:01 +0000405 ctx->result = result;
406 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200407 }
Mathieu Chartierd7cbf8a2015-03-19 12:43:20 -0700408 case Instruction::RETURN_VOID: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200409 PREAMBLE();
Hans Boehm30359612014-05-21 17:46:23 -0700410 QuasiAtomic::ThreadFenceForConstructor();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200411 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700412 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700413 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700414 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
415 !SendMethodExitEvents(self,
416 instrumentation,
417 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800418 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700419 shadow_frame.GetMethod(),
420 inst->GetDexPc(insns),
421 result))) {
422 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200423 }
buzbee1452bee2015-03-06 14:43:04 -0800424 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700425 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700426 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800427 }
David Srbecky946bb092018-03-09 17:23:01 +0000428 ctx->result = result;
429 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200430 }
431 case Instruction::RETURN: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200432 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200433 JValue result;
434 result.SetJ(0);
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200435 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700436 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700437 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700438 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
439 !SendMethodExitEvents(self,
440 instrumentation,
441 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800442 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700443 shadow_frame.GetMethod(),
444 inst->GetDexPc(insns),
445 result))) {
446 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200447 }
buzbee1452bee2015-03-06 14:43:04 -0800448 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700449 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700450 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800451 }
David Srbecky946bb092018-03-09 17:23:01 +0000452 ctx->result = result;
453 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200454 }
455 case Instruction::RETURN_WIDE: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200456 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200457 JValue result;
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200458 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x(inst_data)));
Ian Rogers7b078e82014-09-10 14:44:24 -0700459 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700460 HANDLE_MONITOR_CHECKS();
Alex Lighte814f9d2017-07-31 16:14:39 -0700461 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
462 !SendMethodExitEvents(self,
463 instrumentation,
464 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800465 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700466 shadow_frame.GetMethod(),
467 inst->GetDexPc(insns),
468 result))) {
469 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200470 }
buzbee1452bee2015-03-06 14:43:04 -0800471 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700472 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700473 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800474 }
David Srbecky946bb092018-03-09 17:23:01 +0000475 ctx->result = result;
476 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200477 }
478 case Instruction::RETURN_OBJECT: {
Sebastien Hertz9d6bf692015-04-10 12:12:33 +0200479 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200480 JValue result;
Ian Rogers7b078e82014-09-10 14:44:24 -0700481 self->AllowThreadSuspension();
Andreas Gampe03ec9302015-08-27 17:41:47 -0700482 HANDLE_MONITOR_CHECKS();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700483 const size_t ref_idx = inst->VRegA_11x(inst_data);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700484 ObjPtr<mirror::Object> obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700485 if (do_assignability_check && obj_result != nullptr) {
Alex Lightcc917d92018-02-22 13:28:28 -0800486 ObjPtr<mirror::Class> return_type = shadow_frame.GetMethod()->ResolveReturnType();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700487 // Re-load since it might have moved.
488 obj_result = shadow_frame.GetVRegReference(ref_idx);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700489 if (return_type == nullptr) {
Jeff Haoa3faaf42013-09-03 19:07:00 -0700490 // Return the pending exception.
491 HANDLE_PENDING_EXCEPTION();
492 }
493 if (!obj_result->VerifierInstanceOf(return_type)) {
494 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700495 std::string temp1, temp2;
Orion Hodsonfef06642016-11-25 16:07:11 +0000496 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700497 "Returning '%s' that is not instance of return type '%s'",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700498 obj_result->GetClass()->GetDescriptor(&temp1),
499 return_type->GetDescriptor(&temp2));
Jeff Haoa3faaf42013-09-03 19:07:00 -0700500 HANDLE_PENDING_EXCEPTION();
501 }
502 }
Mathieu Chartierbfd9a432014-05-21 17:43:44 -0700503 result.SetL(obj_result);
Alex Lighte814f9d2017-07-31 16:14:39 -0700504 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
505 !SendMethodExitEvents(self,
506 instrumentation,
507 shadow_frame,
Mathieu Chartier808c7a52017-12-15 11:19:33 -0800508 shadow_frame.GetThisObject(accessor.InsSize()),
Alex Lighte814f9d2017-07-31 16:14:39 -0700509 shadow_frame.GetMethod(),
510 inst->GetDexPc(insns),
511 result))) {
512 HANDLE_PENDING_EXCEPTION_WITH_INSTRUMENTATION(nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200513 }
Alex Lighte814f9d2017-07-31 16:14:39 -0700514 // Re-load since it might have moved during the MethodExitEvent.
515 result.SetL(shadow_frame.GetVRegReference(ref_idx));
buzbee1452bee2015-03-06 14:43:04 -0800516 if (interpret_one_instruction) {
buzbee93e94f22016-04-07 13:52:48 -0700517 /* Signal mterp to return to caller */
Andreas Gampee2abbc62017-09-15 11:59:26 -0700518 shadow_frame.SetDexPC(dex::kDexNoIndex);
buzbee1452bee2015-03-06 14:43:04 -0800519 }
David Srbecky946bb092018-03-09 17:23:01 +0000520 ctx->result = result;
521 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200522 }
523 case Instruction::CONST_4: {
524 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200525 uint4_t dst = inst->VRegA_11n(inst_data);
526 int4_t val = inst->VRegB_11n(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200527 shadow_frame.SetVReg(dst, val);
528 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700529 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200530 }
531 inst = inst->Next_1xx();
532 break;
533 }
534 case Instruction::CONST_16: {
535 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200536 uint8_t dst = inst->VRegA_21s(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200537 int16_t val = inst->VRegB_21s();
538 shadow_frame.SetVReg(dst, val);
539 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700540 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200541 }
542 inst = inst->Next_2xx();
543 break;
544 }
545 case Instruction::CONST: {
546 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200547 uint8_t dst = inst->VRegA_31i(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200548 int32_t val = inst->VRegB_31i();
549 shadow_frame.SetVReg(dst, val);
550 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700551 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200552 }
553 inst = inst->Next_3xx();
554 break;
555 }
556 case Instruction::CONST_HIGH16: {
557 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200558 uint8_t dst = inst->VRegA_21h(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200559 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16);
560 shadow_frame.SetVReg(dst, val);
561 if (val == 0) {
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700562 shadow_frame.SetVRegReference(dst, nullptr);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200563 }
564 inst = inst->Next_2xx();
565 break;
566 }
567 case Instruction::CONST_WIDE_16:
568 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200569 shadow_frame.SetVRegLong(inst->VRegA_21s(inst_data), inst->VRegB_21s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200570 inst = inst->Next_2xx();
571 break;
572 case Instruction::CONST_WIDE_32:
573 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200574 shadow_frame.SetVRegLong(inst->VRegA_31i(inst_data), inst->VRegB_31i());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200575 inst = inst->Next_3xx();
576 break;
577 case Instruction::CONST_WIDE:
578 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200579 shadow_frame.SetVRegLong(inst->VRegA_51l(inst_data), inst->VRegB_51l());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200580 inst = inst->Next_51l();
581 break;
582 case Instruction::CONST_WIDE_HIGH16:
Sebastien Hertz3c5aec12014-06-04 09:41:21 +0200583 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200584 shadow_frame.SetVRegLong(inst->VRegA_21h(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200585 static_cast<uint64_t>(inst->VRegB_21h()) << 48);
586 inst = inst->Next_2xx();
587 break;
588 case Instruction::CONST_STRING: {
589 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800590 ObjPtr<mirror::String> s = ResolveString(self,
591 shadow_frame,
592 dex::StringIndex(inst->VRegB_21c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700593 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200594 HANDLE_PENDING_EXCEPTION();
595 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100596 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200597 inst = inst->Next_2xx();
598 }
599 break;
600 }
601 case Instruction::CONST_STRING_JUMBO: {
602 PREAMBLE();
Andreas Gampe8a0128a2016-11-28 07:38:35 -0800603 ObjPtr<mirror::String> s = ResolveString(self,
604 shadow_frame,
605 dex::StringIndex(inst->VRegB_31c()));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700606 if (UNLIKELY(s == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200607 HANDLE_PENDING_EXCEPTION();
608 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100609 shadow_frame.SetVRegReference(inst->VRegA_31c(inst_data), s);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200610 inst = inst->Next_3xx();
611 }
612 break;
613 }
614 case Instruction::CONST_CLASS: {
615 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800616 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700617 shadow_frame.GetMethod(),
618 self,
619 false,
620 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700621 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200622 HANDLE_PENDING_EXCEPTION();
623 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100624 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), c);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200625 inst = inst->Next_2xx();
626 }
627 break;
628 }
Orion Hodson2e599942017-09-22 16:17:41 +0100629 case Instruction::CONST_METHOD_HANDLE: {
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::MethodHandle> mh = cl->ResolveMethodHandle(self,
633 inst->VRegB_21c(),
634 shadow_frame.GetMethod());
Orion Hodson2e599942017-09-22 16:17:41 +0100635 if (UNLIKELY(mh == nullptr)) {
636 HANDLE_PENDING_EXCEPTION();
637 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100638 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mh);
Orion Hodson2e599942017-09-22 16:17:41 +0100639 inst = inst->Next_2xx();
640 }
641 break;
642 }
643 case Instruction::CONST_METHOD_TYPE: {
644 PREAMBLE();
Orion Hodsone7732be2017-10-11 14:35:20 +0100645 ClassLinker* cl = Runtime::Current()->GetClassLinker();
Alex Lightcc917d92018-02-22 13:28:28 -0800646 ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(self,
Orion Hodson06d10a72018-05-14 08:53:38 +0100647 dex::ProtoIndex(inst->VRegB_21c()),
Alex Lightcc917d92018-02-22 13:28:28 -0800648 shadow_frame.GetMethod());
Orion Hodson2e599942017-09-22 16:17:41 +0100649 if (UNLIKELY(mt == nullptr)) {
650 HANDLE_PENDING_EXCEPTION();
651 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100652 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), mt);
Orion Hodson2e599942017-09-22 16:17:41 +0100653 inst = inst->Next_2xx();
654 }
655 break;
656 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200657 case Instruction::MONITOR_ENTER: {
658 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700659 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700660 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700661 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000662 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200663 HANDLE_PENDING_EXCEPTION();
664 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700665 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200666 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
667 }
668 break;
669 }
670 case Instruction::MONITOR_EXIT: {
671 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700672 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700673 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700674 if (UNLIKELY(obj == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000675 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200676 HANDLE_PENDING_EXCEPTION();
677 } else {
Andreas Gampe03ec9302015-08-27 17:41:47 -0700678 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200679 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
680 }
681 break;
682 }
683 case Instruction::CHECK_CAST: {
684 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800685 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700686 shadow_frame.GetMethod(),
687 self,
688 false,
689 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700690 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200691 HANDLE_PENDING_EXCEPTION();
692 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700693 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_21c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700694 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200695 ThrowClassCastException(c, obj->GetClass());
696 HANDLE_PENDING_EXCEPTION();
697 } else {
698 inst = inst->Next_2xx();
699 }
700 }
701 break;
702 }
703 case Instruction::INSTANCE_OF: {
704 PREAMBLE();
Andreas Gampea5b09a62016-11-17 15:21:22 -0800705 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegC_22c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700706 shadow_frame.GetMethod(),
707 self,
708 false,
709 do_access_check);
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700710 if (UNLIKELY(c == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200711 HANDLE_PENDING_EXCEPTION();
712 } else {
Mathieu Chartieref41db72016-10-25 15:08:01 -0700713 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700714 shadow_frame.SetVReg(inst->VRegA_22c(inst_data),
715 (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200716 inst = inst->Next_2xx();
717 }
718 break;
719 }
720 case Instruction::ARRAY_LENGTH: {
721 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700722 ObjPtr<mirror::Object> array = shadow_frame.GetVRegReference(inst->VRegB_12x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700723 if (UNLIKELY(array == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000724 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200725 HANDLE_PENDING_EXCEPTION();
726 } else {
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200727 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), array->AsArray()->GetLength());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200728 inst = inst->Next_1xx();
729 }
730 break;
731 }
732 case Instruction::NEW_INSTANCE: {
733 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700734 ObjPtr<mirror::Object> obj = nullptr;
Andreas Gampea5b09a62016-11-17 15:21:22 -0800735 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(inst->VRegB_21c()),
Mathieu Chartieref41db72016-10-25 15:08:01 -0700736 shadow_frame.GetMethod(),
737 self,
738 false,
739 do_access_check);
Jeff Hao848f70a2014-01-15 13:49:50 -0800740 if (LIKELY(c != nullptr)) {
741 if (UNLIKELY(c->IsStringClass())) {
742 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
jessicahandojo3aaa37b2016-07-29 14:46:37 -0700743 obj = mirror::String::AllocEmptyString<true>(self, allocator_type);
Jeff Hao848f70a2014-01-15 13:49:50 -0800744 } else {
Nicolas Geoffray0d3998b2017-01-12 15:35:12 +0000745 obj = AllocObjectFromCode<true>(
746 c.Ptr(),
Andreas Gampea5b09a62016-11-17 15:21:22 -0800747 self,
748 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Jeff Hao848f70a2014-01-15 13:49:50 -0800749 }
750 }
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700751 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200752 HANDLE_PENDING_EXCEPTION();
753 } else {
Sebastien Hertz4e99b3d2014-06-24 14:35:40 +0200754 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700755 // Don't allow finalizable objects to be allocated during a transaction since these can't
756 // be finalized without a started runtime.
757 if (transaction_active && obj->GetClass()->IsFinalizable()) {
Sebastien Hertz45b15972015-04-03 16:07:05 +0200758 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
David Sehr709b0702016-10-13 09:12:37 -0700759 obj->PrettyTypeOf().c_str());
Mathieu Chartierb2c7ead2014-04-29 11:13:16 -0700760 HANDLE_PENDING_EXCEPTION();
761 break;
762 }
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100763 shadow_frame.SetVRegReference(inst->VRegA_21c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200764 inst = inst->Next_2xx();
765 }
766 break;
767 }
768 case Instruction::NEW_ARRAY: {
769 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200770 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c(inst_data));
Mathieu Chartieref41db72016-10-25 15:08:01 -0700771 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check, true>(
Andreas Gampea5b09a62016-11-17 15:21:22 -0800772 dex::TypeIndex(inst->VRegC_22c()),
773 length,
774 shadow_frame.GetMethod(),
775 self,
Mathieu Chartiercbb2d202013-11-14 17:45:16 -0800776 Runtime::Current()->GetHeap()->GetCurrentAllocator());
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700777 if (UNLIKELY(obj == nullptr)) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200778 HANDLE_PENDING_EXCEPTION();
779 } else {
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +0100780 shadow_frame.SetVRegReference(inst->VRegA_22c(inst_data), obj);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200781 inst = inst->Next_2xx();
782 }
783 break;
784 }
785 case Instruction::FILLED_NEW_ARRAY: {
786 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100787 bool success =
788 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
789 &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200790 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
791 break;
792 }
793 case Instruction::FILLED_NEW_ARRAY_RANGE: {
794 PREAMBLE();
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100795 bool success =
796 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
797 self, &result_register);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200798 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
799 break;
800 }
801 case Instruction::FILL_ARRAY_DATA: {
802 PREAMBLE();
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200803 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t();
804 const Instruction::ArrayDataPayload* payload =
805 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
Mathieu Chartieref41db72016-10-25 15:08:01 -0700806 ObjPtr<mirror::Object> obj = shadow_frame.GetVRegReference(inst->VRegA_31t(inst_data));
Ian Rogers832336b2014-10-08 15:35:22 -0700807 bool success = FillArrayData(obj, payload);
808 if (!success) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200809 HANDLE_PENDING_EXCEPTION();
810 break;
811 }
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100812 if (transaction_active) {
Ian Rogers832336b2014-10-08 15:35:22 -0700813 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +0100814 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200815 inst = inst->Next_3xx();
816 break;
817 }
818 case Instruction::THROW: {
819 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700820 HANDLE_ASYNC_EXCEPTION();
Mathieu Chartieref41db72016-10-25 15:08:01 -0700821 ObjPtr<mirror::Object> exception =
822 shadow_frame.GetVRegReference(inst->VRegA_11x(inst_data));
Mathieu Chartier2cebb242015-04-21 16:50:40 -0700823 if (UNLIKELY(exception == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +0000824 ThrowNullPointerException("throw with null exception");
Jeff Haoa3faaf42013-09-03 19:07:00 -0700825 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
826 // This should never happen.
Ian Rogers1ff3c982014-08-12 02:30:58 -0700827 std::string temp;
Orion Hodsonfef06642016-11-25 16:07:11 +0000828 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
Jeff Haoa3faaf42013-09-03 19:07:00 -0700829 "Throwing '%s' that is not instance of Throwable",
Ian Rogers1ff3c982014-08-12 02:30:58 -0700830 exception->GetClass()->GetDescriptor(&temp));
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200831 } else {
Nicolas Geoffray14691c52015-03-05 10:40:17 +0000832 self->SetException(exception->AsThrowable());
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200833 }
834 HANDLE_PENDING_EXCEPTION();
835 break;
836 }
837 case Instruction::GOTO: {
838 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700839 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200840 int8_t offset = inst->VRegA_10t(inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000841 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200842 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800843 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200844 break;
845 }
846 case Instruction::GOTO_16: {
847 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700848 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200849 int16_t offset = inst->VRegA_20t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000850 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200851 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800852 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200853 break;
854 }
855 case Instruction::GOTO_32: {
856 PREAMBLE();
Alex Light848574c2017-09-25 16:59:39 -0700857 HANDLE_ASYNC_EXCEPTION();
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200858 int32_t offset = inst->VRegA_30t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000859 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +0200860 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800861 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200862 break;
863 }
864 case Instruction::PACKED_SWITCH: {
865 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200866 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000867 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200868 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800869 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200870 break;
871 }
872 case Instruction::SPARSE_SWITCH: {
873 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200874 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
Nicolas Geoffray81f0f952016-01-20 16:25:19 +0000875 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200876 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -0800877 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200878 break;
879 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700880
Ian Rogers647b1a82014-10-10 11:02:11 -0700881#pragma clang diagnostic push
882#pragma clang diagnostic ignored "-Wfloat-equal"
Ian Rogers647b1a82014-10-10 11:02:11 -0700883
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200884 case Instruction::CMPL_FLOAT: {
885 PREAMBLE();
886 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
887 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
888 int32_t result;
889 if (val1 > val2) {
890 result = 1;
891 } else if (val1 == val2) {
892 result = 0;
893 } else {
894 result = -1;
895 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200896 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200897 inst = inst->Next_2xx();
898 break;
899 }
900 case Instruction::CMPG_FLOAT: {
901 PREAMBLE();
902 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x());
903 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x());
904 int32_t result;
905 if (val1 < val2) {
906 result = -1;
907 } else if (val1 == val2) {
908 result = 0;
909 } else {
910 result = 1;
911 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200912 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200913 inst = inst->Next_2xx();
914 break;
915 }
916 case Instruction::CMPL_DOUBLE: {
917 PREAMBLE();
918 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
919 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
920 int32_t result;
921 if (val1 > val2) {
922 result = 1;
923 } else if (val1 == val2) {
924 result = 0;
925 } else {
926 result = -1;
927 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200928 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200929 inst = inst->Next_2xx();
930 break;
931 }
932
933 case Instruction::CMPG_DOUBLE: {
934 PREAMBLE();
935 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x());
936 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x());
937 int32_t result;
938 if (val1 < val2) {
939 result = -1;
940 } else if (val1 == val2) {
941 result = 0;
942 } else {
943 result = 1;
944 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200945 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200946 inst = inst->Next_2xx();
947 break;
948 }
Ian Rogers647b1a82014-10-10 11:02:11 -0700949
Ian Rogers647b1a82014-10-10 11:02:11 -0700950#pragma clang diagnostic pop
Ian Rogers647b1a82014-10-10 11:02:11 -0700951
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200952 case Instruction::CMP_LONG: {
953 PREAMBLE();
954 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x());
955 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x());
956 int32_t result;
957 if (val1 > val2) {
958 result = 1;
959 } else if (val1 == val2) {
960 result = 0;
961 } else {
962 result = -1;
963 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +0200964 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +0200965 inst = inst->Next_2xx();
966 break;
967 }
968 case Instruction::IF_EQ: {
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_NE: {
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_LT: {
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_GE: {
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_GT: {
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_LE: {
1039 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001040 if (shadow_frame.GetVReg(inst->VRegA_22t(inst_data)) <=
1041 shadow_frame.GetVReg(inst->VRegB_22t(inst_data))) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001042 int16_t offset = inst->VRegC_22t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001043 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001044 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001045 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001046 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001047 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001048 inst = inst->Next_2xx();
1049 }
1050 break;
1051 }
1052 case Instruction::IF_EQZ: {
1053 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001054 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) == 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001055 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001056 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001057 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001058 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001059 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001060 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001061 inst = inst->Next_2xx();
1062 }
1063 break;
1064 }
1065 case Instruction::IF_NEZ: {
1066 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001067 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) != 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001068 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001069 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001070 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001071 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001072 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001073 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001074 inst = inst->Next_2xx();
1075 }
1076 break;
1077 }
1078 case Instruction::IF_LTZ: {
1079 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001080 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) < 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001081 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001082 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001083 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001084 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001085 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001086 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001087 inst = inst->Next_2xx();
1088 }
1089 break;
1090 }
1091 case Instruction::IF_GEZ: {
1092 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001093 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) >= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001094 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001095 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001096 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001097 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001098 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001099 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001100 inst = inst->Next_2xx();
1101 }
1102 break;
1103 }
1104 case Instruction::IF_GTZ: {
1105 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001106 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) > 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001107 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001108 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001109 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001110 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001111 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001112 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001113 inst = inst->Next_2xx();
1114 }
1115 break;
1116 }
1117 case Instruction::IF_LEZ: {
1118 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001119 if (shadow_frame.GetVReg(inst->VRegA_21t(inst_data)) <= 0) {
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001120 int16_t offset = inst->VRegB_21t();
Nicolas Geoffray81f0f952016-01-20 16:25:19 +00001121 BRANCH_INSTRUMENTATION(offset);
Sebastien Hertz1eda2262013-09-09 16:53:14 +02001122 inst = inst->RelativeAt(offset);
Andreas Gampef4f76372016-12-13 14:43:58 -08001123 HANDLE_BACKWARD_BRANCH(offset);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001124 } else {
buzbeef1dcacc2016-02-24 14:24:24 -08001125 BRANCH_INSTRUMENTATION(2);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001126 inst = inst->Next_2xx();
1127 }
1128 break;
1129 }
1130 case Instruction::AGET_BOOLEAN: {
1131 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001132 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001133 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001134 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001135 HANDLE_PENDING_EXCEPTION();
1136 break;
1137 }
1138 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001139 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001140 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001141 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001142 inst = inst->Next_2xx();
1143 } else {
1144 HANDLE_PENDING_EXCEPTION();
1145 }
1146 break;
1147 }
1148 case Instruction::AGET_BYTE: {
1149 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001150 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001151 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001152 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001153 HANDLE_PENDING_EXCEPTION();
1154 break;
1155 }
1156 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001157 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001158 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001159 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001160 inst = inst->Next_2xx();
1161 } else {
1162 HANDLE_PENDING_EXCEPTION();
1163 }
1164 break;
1165 }
1166 case Instruction::AGET_CHAR: {
1167 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001168 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001169 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001170 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001171 HANDLE_PENDING_EXCEPTION();
1172 break;
1173 }
1174 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001175 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001176 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001177 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001178 inst = inst->Next_2xx();
1179 } else {
1180 HANDLE_PENDING_EXCEPTION();
1181 }
1182 break;
1183 }
1184 case Instruction::AGET_SHORT: {
1185 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001186 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001187 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001188 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001189 HANDLE_PENDING_EXCEPTION();
1190 break;
1191 }
1192 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001193 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001194 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001195 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001196 inst = inst->Next_2xx();
1197 } else {
1198 HANDLE_PENDING_EXCEPTION();
1199 }
1200 break;
1201 }
1202 case Instruction::AGET: {
1203 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001204 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001205 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001206 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001207 HANDLE_PENDING_EXCEPTION();
1208 break;
1209 }
1210 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001211 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001212 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001213 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001214 shadow_frame.SetVReg(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001215 inst = inst->Next_2xx();
1216 } else {
1217 HANDLE_PENDING_EXCEPTION();
1218 }
1219 break;
1220 }
1221 case Instruction::AGET_WIDE: {
1222 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001223 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001224 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001225 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001226 HANDLE_PENDING_EXCEPTION();
1227 break;
1228 }
1229 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001230 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001231 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001232 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzabff6432014-01-27 18:01:39 +01001233 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001234 inst = inst->Next_2xx();
1235 } else {
1236 HANDLE_PENDING_EXCEPTION();
1237 }
1238 break;
1239 }
1240 case Instruction::AGET_OBJECT: {
1241 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001242 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001243 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001244 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001245 HANDLE_PENDING_EXCEPTION();
1246 break;
1247 }
1248 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001249 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001250 if (array->CheckIsValidIndex(index)) {
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001251 shadow_frame.SetVRegReference(inst->VRegA_23x(inst_data), array->GetWithoutChecks(index));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001252 inst = inst->Next_2xx();
1253 } else {
1254 HANDLE_PENDING_EXCEPTION();
1255 }
1256 break;
1257 }
1258 case Instruction::APUT_BOOLEAN: {
1259 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001260 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001261 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001262 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001263 HANDLE_PENDING_EXCEPTION();
1264 break;
1265 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001266 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001267 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001268 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001269 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001270 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001271 inst = inst->Next_2xx();
1272 } else {
1273 HANDLE_PENDING_EXCEPTION();
1274 }
1275 break;
1276 }
1277 case Instruction::APUT_BYTE: {
1278 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001279 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001280 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001281 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001282 HANDLE_PENDING_EXCEPTION();
1283 break;
1284 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001285 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001286 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001287 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001288 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001289 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001290 inst = inst->Next_2xx();
1291 } else {
1292 HANDLE_PENDING_EXCEPTION();
1293 }
1294 break;
1295 }
1296 case Instruction::APUT_CHAR: {
1297 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001298 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001299 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001300 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001301 HANDLE_PENDING_EXCEPTION();
1302 break;
1303 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001304 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001305 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001306 ObjPtr<mirror::CharArray> array = a->AsCharArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001307 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001308 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001309 inst = inst->Next_2xx();
1310 } else {
1311 HANDLE_PENDING_EXCEPTION();
1312 }
1313 break;
1314 }
1315 case Instruction::APUT_SHORT: {
1316 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001317 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001318 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001319 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001320 HANDLE_PENDING_EXCEPTION();
1321 break;
1322 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001323 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001324 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001325 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001326 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001327 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001328 inst = inst->Next_2xx();
1329 } else {
1330 HANDLE_PENDING_EXCEPTION();
1331 }
1332 break;
1333 }
1334 case Instruction::APUT: {
1335 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001336 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001337 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001338 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001339 HANDLE_PENDING_EXCEPTION();
1340 break;
1341 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001342 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001343 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001344 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001345 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001346 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001347 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001348 inst = inst->Next_2xx();
1349 } else {
1350 HANDLE_PENDING_EXCEPTION();
1351 }
1352 break;
1353 }
1354 case Instruction::APUT_WIDE: {
1355 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001356 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001357 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001358 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001359 HANDLE_PENDING_EXCEPTION();
1360 break;
1361 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001362 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x(inst_data));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001363 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
David Sehr709b0702016-10-13 09:12:37 -07001364 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001365 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001366 if (array->CheckIsValidIndex(index)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001367 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001368 inst = inst->Next_2xx();
1369 } else {
1370 HANDLE_PENDING_EXCEPTION();
1371 }
1372 break;
1373 }
1374 case Instruction::APUT_OBJECT: {
1375 PREAMBLE();
Mathieu Chartieref41db72016-10-25 15:08:01 -07001376 ObjPtr<mirror::Object> a = shadow_frame.GetVRegReference(inst->VRegB_23x());
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001377 if (UNLIKELY(a == nullptr)) {
Nicolas Geoffray0aa50ce2015-03-10 11:03:29 +00001378 ThrowNullPointerExceptionFromInterpreter();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001379 HANDLE_PENDING_EXCEPTION();
1380 break;
1381 }
1382 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x());
Mathieu Chartieref41db72016-10-25 15:08:01 -07001383 ObjPtr<mirror::Object> val = shadow_frame.GetVRegReference(inst->VRegA_23x(inst_data));
1384 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
Ian Rogersb0fa5dc2014-04-28 16:47:08 -07001385 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001386 array->SetWithoutChecks<transaction_active>(index, val);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001387 inst = inst->Next_2xx();
1388 } else {
1389 HANDLE_PENDING_EXCEPTION();
1390 }
1391 break;
1392 }
1393 case Instruction::IGET_BOOLEAN: {
1394 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001395 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, 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_BYTE: {
1401 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001402 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, 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_CHAR: {
1408 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001409 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, 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_SHORT: {
1415 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001416 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, 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: {
1422 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001423 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, 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_WIDE: {
1429 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001430 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1431 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001432 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1433 break;
1434 }
1435 case Instruction::IGET_OBJECT: {
1436 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001437 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1438 self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001439 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1440 break;
1441 }
1442 case Instruction::IGET_QUICK: {
1443 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001444 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001445 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1446 break;
1447 }
1448 case Instruction::IGET_WIDE_QUICK: {
1449 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001450 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001451 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1452 break;
1453 }
1454 case Instruction::IGET_OBJECT_QUICK: {
1455 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001456 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001457 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1458 break;
1459 }
Mathieu Chartierffc605c2014-12-10 10:35:44 -08001460 case Instruction::IGET_BOOLEAN_QUICK: {
1461 PREAMBLE();
1462 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1463 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1464 break;
1465 }
1466 case Instruction::IGET_BYTE_QUICK: {
1467 PREAMBLE();
1468 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1469 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1470 break;
1471 }
1472 case Instruction::IGET_CHAR_QUICK: {
1473 PREAMBLE();
1474 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1475 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1476 break;
1477 }
1478 case Instruction::IGET_SHORT_QUICK: {
1479 PREAMBLE();
1480 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1481 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1482 break;
1483 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001484 case Instruction::SGET_BOOLEAN: {
1485 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001486 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, 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_BYTE: {
1492 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001493 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, 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_CHAR: {
1499 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001500 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, 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_SHORT: {
1506 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001507 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, 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: {
1513 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001514 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check,
1515 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001516 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1517 break;
1518 }
1519 case Instruction::SGET_WIDE: {
1520 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001521 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, 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::SGET_OBJECT: {
1527 PREAMBLE();
Chang Xingbd208d82017-07-12 14:53:17 -07001528 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, 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_BOOLEAN: {
1534 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001535 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1536 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001537 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1538 break;
1539 }
1540 case Instruction::IPUT_BYTE: {
1541 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001542 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1543 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001544 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1545 break;
1546 }
1547 case Instruction::IPUT_CHAR: {
1548 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001549 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1550 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001551 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1552 break;
1553 }
1554 case Instruction::IPUT_SHORT: {
1555 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001556 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1557 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001558 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1559 break;
1560 }
1561 case Instruction::IPUT: {
1562 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001563 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1564 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001565 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1566 break;
1567 }
1568 case Instruction::IPUT_WIDE: {
1569 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001570 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1571 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001572 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1573 break;
1574 }
1575 case Instruction::IPUT_OBJECT: {
1576 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001577 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1578 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001579 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1580 break;
1581 }
1582 case Instruction::IPUT_QUICK: {
1583 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001584 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1585 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001586 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1587 break;
1588 }
Fred Shih37f05ef2014-07-16 18:38:08 -07001589 case Instruction::IPUT_BOOLEAN_QUICK: {
1590 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001591 bool success = DoIPutQuick<Primitive::kPrimBoolean, 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_BYTE_QUICK: {
1597 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001598 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1599 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001600 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1601 break;
1602 }
1603 case Instruction::IPUT_CHAR_QUICK: {
1604 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001605 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1606 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001607 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1608 break;
1609 }
1610 case Instruction::IPUT_SHORT_QUICK: {
1611 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001612 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1613 shadow_frame, inst, inst_data);
Fred Shih37f05ef2014-07-16 18:38:08 -07001614 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1615 break;
1616 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001617 case Instruction::IPUT_WIDE_QUICK: {
1618 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001619 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1620 shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001621 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1622 break;
1623 }
1624 case Instruction::IPUT_OBJECT_QUICK: {
1625 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001626 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1627 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_BOOLEAN: {
1632 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001633 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, 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_BYTE: {
1639 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001640 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, 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_CHAR: {
1646 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001647 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, 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_SHORT: {
1653 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001654 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, 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: {
1660 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001661 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1662 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001663 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1664 break;
1665 }
1666 case Instruction::SPUT_WIDE: {
1667 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001668 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1669 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001670 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1671 break;
1672 }
1673 case Instruction::SPUT_OBJECT: {
1674 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001675 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1676 transaction_active>(self, shadow_frame, inst, inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001677 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1678 break;
1679 }
1680 case Instruction::INVOKE_VIRTUAL: {
1681 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001682 bool success = DoInvoke<kVirtual, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001683 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001684 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001685 break;
1686 }
1687 case Instruction::INVOKE_VIRTUAL_RANGE: {
1688 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001689 bool success = DoInvoke<kVirtual, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001690 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001691 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001692 break;
1693 }
1694 case Instruction::INVOKE_SUPER: {
1695 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001696 bool success = DoInvoke<kSuper, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001697 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001698 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001699 break;
1700 }
1701 case Instruction::INVOKE_SUPER_RANGE: {
1702 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001703 bool success = DoInvoke<kSuper, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001704 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001705 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001706 break;
1707 }
1708 case Instruction::INVOKE_DIRECT: {
1709 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001710 bool success = DoInvoke<kDirect, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001711 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001712 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001713 break;
1714 }
1715 case Instruction::INVOKE_DIRECT_RANGE: {
1716 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001717 bool success = DoInvoke<kDirect, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001718 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001719 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001720 break;
1721 }
1722 case Instruction::INVOKE_INTERFACE: {
1723 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001724 bool success = DoInvoke<kInterface, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001725 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001726 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001727 break;
1728 }
1729 case Instruction::INVOKE_INTERFACE_RANGE: {
1730 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001731 bool success = DoInvoke<kInterface, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001732 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001733 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001734 break;
1735 }
1736 case Instruction::INVOKE_STATIC: {
1737 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001738 bool success = DoInvoke<kStatic, false, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001739 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001740 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001741 break;
1742 }
1743 case Instruction::INVOKE_STATIC_RANGE: {
1744 PREAMBLE();
David Srbecky1f5ab4e2018-10-15 11:46:46 +01001745 bool success = DoInvoke<kStatic, true, do_access_check, /*is_mterp=*/ false>(
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001746 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001747 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001748 break;
1749 }
1750 case Instruction::INVOKE_VIRTUAL_QUICK: {
1751 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001752 bool success = DoInvokeVirtualQuick<false>(
1753 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001754 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001755 break;
1756 }
1757 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
1758 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001759 bool success = DoInvokeVirtualQuick<true>(
1760 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001761 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001762 break;
1763 }
Narayan Kamath9823e782016-08-03 12:46:58 +01001764 case Instruction::INVOKE_POLYMORPHIC: {
1765 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001766 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001767 bool success = DoInvokePolymorphic</* is_range= */ false>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001768 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001769 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
Narayan Kamath9823e782016-08-03 12:46:58 +01001770 break;
1771 }
1772 case Instruction::INVOKE_POLYMORPHIC_RANGE: {
1773 PREAMBLE();
Narayan Kamath269cb432016-10-28 10:19:54 +01001774 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001775 bool success = DoInvokePolymorphic</* is_range= */ true>(
Narayan Kamath9823e782016-08-03 12:46:58 +01001776 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001777 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
Narayan Kamath9823e782016-08-03 12:46:58 +01001778 break;
Narayan Kamath9823e782016-08-03 12:46:58 +01001779 }
Orion Hodsonc069a302017-01-18 09:23:12 +00001780 case Instruction::INVOKE_CUSTOM: {
1781 PREAMBLE();
1782 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001783 bool success = DoInvokeCustom</* is_range= */ false>(
Orion Hodsonc069a302017-01-18 09:23:12 +00001784 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001785 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Orion Hodsonc069a302017-01-18 09:23:12 +00001786 break;
1787 }
1788 case Instruction::INVOKE_CUSTOM_RANGE: {
1789 PREAMBLE();
1790 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
Andreas Gampe98ea9d92018-10-19 14:06:15 -07001791 bool success = DoInvokeCustom</* is_range= */ true>(
Orion Hodsonc069a302017-01-18 09:23:12 +00001792 self, shadow_frame, inst, inst_data, &result_register);
Alex Light0aa7a5a2018-10-10 15:58:14 +00001793 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
Orion Hodsonc069a302017-01-18 09:23:12 +00001794 break;
1795 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001796 case Instruction::NEG_INT:
1797 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001798 shadow_frame.SetVReg(
1799 inst->VRegA_12x(inst_data), -shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001800 inst = inst->Next_1xx();
1801 break;
1802 case Instruction::NOT_INT:
1803 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001804 shadow_frame.SetVReg(
1805 inst->VRegA_12x(inst_data), ~shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001806 inst = inst->Next_1xx();
1807 break;
1808 case Instruction::NEG_LONG:
1809 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001810 shadow_frame.SetVRegLong(
1811 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001812 inst = inst->Next_1xx();
1813 break;
1814 case Instruction::NOT_LONG:
1815 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001816 shadow_frame.SetVRegLong(
1817 inst->VRegA_12x(inst_data), ~shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001818 inst = inst->Next_1xx();
1819 break;
1820 case Instruction::NEG_FLOAT:
1821 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001822 shadow_frame.SetVRegFloat(
1823 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001824 inst = inst->Next_1xx();
1825 break;
1826 case Instruction::NEG_DOUBLE:
1827 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001828 shadow_frame.SetVRegDouble(
1829 inst->VRegA_12x(inst_data), -shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001830 inst = inst->Next_1xx();
1831 break;
1832 case Instruction::INT_TO_LONG:
1833 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001834 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data),
1835 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001836 inst = inst->Next_1xx();
1837 break;
1838 case Instruction::INT_TO_FLOAT:
1839 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001840 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1841 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001842 inst = inst->Next_1xx();
1843 break;
1844 case Instruction::INT_TO_DOUBLE:
1845 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001846 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1847 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001848 inst = inst->Next_1xx();
1849 break;
1850 case Instruction::LONG_TO_INT:
1851 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001852 shadow_frame.SetVReg(inst->VRegA_12x(inst_data),
1853 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001854 inst = inst->Next_1xx();
1855 break;
1856 case Instruction::LONG_TO_FLOAT:
1857 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001858 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1859 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001860 inst = inst->Next_1xx();
1861 break;
1862 case Instruction::LONG_TO_DOUBLE:
1863 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001864 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1865 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001866 inst = inst->Next_1xx();
1867 break;
1868 case Instruction::FLOAT_TO_INT: {
1869 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001870 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001871 int32_t result = art_float_to_integral<int32_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001872 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001873 inst = inst->Next_1xx();
1874 break;
1875 }
1876 case Instruction::FLOAT_TO_LONG: {
1877 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001878 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001879 int64_t result = art_float_to_integral<int64_t, float>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001880 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001881 inst = inst->Next_1xx();
1882 break;
1883 }
1884 case Instruction::FLOAT_TO_DOUBLE:
1885 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001886 shadow_frame.SetVRegDouble(inst->VRegA_12x(inst_data),
1887 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001888 inst = inst->Next_1xx();
1889 break;
1890 case Instruction::DOUBLE_TO_INT: {
1891 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001892 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001893 int32_t result = art_float_to_integral<int32_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001894 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001895 inst = inst->Next_1xx();
1896 break;
1897 }
1898 case Instruction::DOUBLE_TO_LONG: {
1899 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001900 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data));
Ian Rogers450dcb52013-09-20 17:36:02 -07001901 int64_t result = art_float_to_integral<int64_t, double>(val);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001902 shadow_frame.SetVRegLong(inst->VRegA_12x(inst_data), result);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001903 inst = inst->Next_1xx();
1904 break;
1905 }
1906 case Instruction::DOUBLE_TO_FLOAT:
1907 PREAMBLE();
Ian Rogers450dcb52013-09-20 17:36:02 -07001908 shadow_frame.SetVRegFloat(inst->VRegA_12x(inst_data),
1909 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001910 inst = inst->Next_1xx();
1911 break;
1912 case Instruction::INT_TO_BYTE:
1913 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001914 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int8_t>(
1915 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001916 inst = inst->Next_1xx();
1917 break;
1918 case Instruction::INT_TO_CHAR:
1919 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001920 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<uint16_t>(
1921 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001922 inst = inst->Next_1xx();
1923 break;
1924 case Instruction::INT_TO_SHORT:
1925 PREAMBLE();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001926 shadow_frame.SetVReg(inst->VRegA_12x(inst_data), static_cast<int16_t>(
1927 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001928 inst = inst->Next_1xx();
1929 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001930 case Instruction::ADD_INT: {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001931 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001932 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001933 SafeAdd(shadow_frame.GetVReg(inst->VRegB_23x()),
1934 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001935 inst = inst->Next_2xx();
1936 break;
Ian Rogersf72a11d2014-10-30 15:41:08 -07001937 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001938 case Instruction::SUB_INT:
1939 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001940 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001941 SafeSub(shadow_frame.GetVReg(inst->VRegB_23x()),
1942 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001943 inst = inst->Next_2xx();
1944 break;
1945 case Instruction::MUL_INT:
1946 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001947 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07001948 SafeMul(shadow_frame.GetVReg(inst->VRegB_23x()),
1949 shadow_frame.GetVReg(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001950 inst = inst->Next_2xx();
1951 break;
1952 case Instruction::DIV_INT: {
1953 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001954 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001955 shadow_frame.GetVReg(inst->VRegB_23x()),
1956 shadow_frame.GetVReg(inst->VRegC_23x()));
1957 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1958 break;
1959 }
1960 case Instruction::REM_INT: {
1961 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001962 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001963 shadow_frame.GetVReg(inst->VRegB_23x()),
1964 shadow_frame.GetVReg(inst->VRegC_23x()));
1965 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
1966 break;
1967 }
1968 case Instruction::SHL_INT:
1969 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001970 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001971 shadow_frame.GetVReg(inst->VRegB_23x()) <<
1972 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1973 inst = inst->Next_2xx();
1974 break;
1975 case Instruction::SHR_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()) & 0x1f));
1980 inst = inst->Next_2xx();
1981 break;
1982 case Instruction::USHR_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 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >>
1986 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f));
1987 inst = inst->Next_2xx();
1988 break;
1989 case Instruction::AND_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::OR_INT:
1997 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02001998 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001999 shadow_frame.GetVReg(inst->VRegB_23x()) |
2000 shadow_frame.GetVReg(inst->VRegC_23x()));
2001 inst = inst->Next_2xx();
2002 break;
2003 case Instruction::XOR_INT:
2004 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002005 shadow_frame.SetVReg(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002006 shadow_frame.GetVReg(inst->VRegB_23x()) ^
2007 shadow_frame.GetVReg(inst->VRegC_23x()));
2008 inst = inst->Next_2xx();
2009 break;
2010 case Instruction::ADD_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 SafeAdd(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::SUB_LONG:
2018 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002019 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002020 SafeSub(shadow_frame.GetVRegLong(inst->VRegB_23x()),
2021 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002022 inst = inst->Next_2xx();
2023 break;
2024 case Instruction::MUL_LONG:
2025 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002026 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002027 SafeMul(shadow_frame.GetVRegLong(inst->VRegB_23x()),
2028 shadow_frame.GetVRegLong(inst->VRegC_23x())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002029 inst = inst->Next_2xx();
2030 break;
2031 case Instruction::DIV_LONG:
2032 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002033 DoLongDivide(shadow_frame, inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002034 shadow_frame.GetVRegLong(inst->VRegB_23x()),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002035 shadow_frame.GetVRegLong(inst->VRegC_23x()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002036 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
2037 break;
2038 case Instruction::REM_LONG:
2039 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002040 DoLongRemainder(shadow_frame, 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 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
2044 break;
2045 case Instruction::AND_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::OR_LONG:
2053 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002054 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002055 shadow_frame.GetVRegLong(inst->VRegB_23x()) |
2056 shadow_frame.GetVRegLong(inst->VRegC_23x()));
2057 inst = inst->Next_2xx();
2058 break;
2059 case Instruction::XOR_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.GetVRegLong(inst->VRegC_23x()));
2064 inst = inst->Next_2xx();
2065 break;
2066 case Instruction::SHL_LONG:
2067 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002068 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002069 shadow_frame.GetVRegLong(inst->VRegB_23x()) <<
2070 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2071 inst = inst->Next_2xx();
2072 break;
2073 case Instruction::SHR_LONG:
2074 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002075 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002076 shadow_frame.GetVRegLong(inst->VRegB_23x()) >>
2077 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2078 inst = inst->Next_2xx();
2079 break;
2080 case Instruction::USHR_LONG:
2081 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002082 shadow_frame.SetVRegLong(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002083 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >>
2084 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f));
2085 inst = inst->Next_2xx();
2086 break;
2087 case Instruction::ADD_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::SUB_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::MUL_FLOAT:
2102 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002103 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002104 shadow_frame.GetVRegFloat(inst->VRegB_23x()) *
2105 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2106 inst = inst->Next_2xx();
2107 break;
2108 case Instruction::DIV_FLOAT:
2109 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002110 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002111 shadow_frame.GetVRegFloat(inst->VRegB_23x()) /
2112 shadow_frame.GetVRegFloat(inst->VRegC_23x()));
2113 inst = inst->Next_2xx();
2114 break;
2115 case Instruction::REM_FLOAT:
2116 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002117 shadow_frame.SetVRegFloat(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002118 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()),
2119 shadow_frame.GetVRegFloat(inst->VRegC_23x())));
2120 inst = inst->Next_2xx();
2121 break;
2122 case Instruction::ADD_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::SUB_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::MUL_DOUBLE:
2137 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002138 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002139 shadow_frame.GetVRegDouble(inst->VRegB_23x()) *
2140 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2141 inst = inst->Next_2xx();
2142 break;
2143 case Instruction::DIV_DOUBLE:
2144 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002145 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002146 shadow_frame.GetVRegDouble(inst->VRegB_23x()) /
2147 shadow_frame.GetVRegDouble(inst->VRegC_23x()));
2148 inst = inst->Next_2xx();
2149 break;
2150 case Instruction::REM_DOUBLE:
2151 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002152 shadow_frame.SetVRegDouble(inst->VRegA_23x(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002153 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()),
2154 shadow_frame.GetVRegDouble(inst->VRegC_23x())));
2155 inst = inst->Next_2xx();
2156 break;
2157 case Instruction::ADD_INT_2ADDR: {
2158 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002159 uint4_t vregA = inst->VRegA_12x(inst_data);
Ian Rogersf72a11d2014-10-30 15:41:08 -07002160 shadow_frame.SetVReg(vregA, SafeAdd(shadow_frame.GetVReg(vregA),
2161 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002162 inst = inst->Next_1xx();
2163 break;
2164 }
2165 case Instruction::SUB_INT_2ADDR: {
2166 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002167 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002168 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002169 SafeSub(shadow_frame.GetVReg(vregA),
2170 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002171 inst = inst->Next_1xx();
2172 break;
2173 }
2174 case Instruction::MUL_INT_2ADDR: {
2175 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002176 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002177 shadow_frame.SetVReg(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002178 SafeMul(shadow_frame.GetVReg(vregA),
2179 shadow_frame.GetVReg(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002180 inst = inst->Next_1xx();
2181 break;
2182 }
2183 case Instruction::DIV_INT_2ADDR: {
2184 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002185 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002186 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002187 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002188 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2189 break;
2190 }
2191 case Instruction::REM_INT_2ADDR: {
2192 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002193 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002194 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002195 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002196 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
2197 break;
2198 }
2199 case Instruction::SHL_INT_2ADDR: {
2200 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002201 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002202 shadow_frame.SetVReg(vregA,
2203 shadow_frame.GetVReg(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002204 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002205 inst = inst->Next_1xx();
2206 break;
2207 }
2208 case Instruction::SHR_INT_2ADDR: {
2209 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002210 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002211 shadow_frame.SetVReg(vregA,
2212 shadow_frame.GetVReg(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002213 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002214 inst = inst->Next_1xx();
2215 break;
2216 }
2217 case Instruction::USHR_INT_2ADDR: {
2218 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002219 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002220 shadow_frame.SetVReg(vregA,
2221 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002222 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x1f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002223 inst = inst->Next_1xx();
2224 break;
2225 }
2226 case Instruction::AND_INT_2ADDR: {
2227 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002228 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002229 shadow_frame.SetVReg(vregA,
2230 shadow_frame.GetVReg(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002231 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002232 inst = inst->Next_1xx();
2233 break;
2234 }
2235 case Instruction::OR_INT_2ADDR: {
2236 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002237 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002238 shadow_frame.SetVReg(vregA,
2239 shadow_frame.GetVReg(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002240 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002241 inst = inst->Next_1xx();
2242 break;
2243 }
2244 case Instruction::XOR_INT_2ADDR: {
2245 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002246 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002247 shadow_frame.SetVReg(vregA,
2248 shadow_frame.GetVReg(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002249 shadow_frame.GetVReg(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002250 inst = inst->Next_1xx();
2251 break;
2252 }
2253 case Instruction::ADD_LONG_2ADDR: {
2254 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002255 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002256 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002257 SafeAdd(shadow_frame.GetVRegLong(vregA),
2258 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002259 inst = inst->Next_1xx();
2260 break;
2261 }
2262 case Instruction::SUB_LONG_2ADDR: {
2263 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002264 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002265 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002266 SafeSub(shadow_frame.GetVRegLong(vregA),
2267 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002268 inst = inst->Next_1xx();
2269 break;
2270 }
2271 case Instruction::MUL_LONG_2ADDR: {
2272 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002273 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002274 shadow_frame.SetVRegLong(vregA,
Ian Rogersf72a11d2014-10-30 15:41:08 -07002275 SafeMul(shadow_frame.GetVRegLong(vregA),
2276 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002277 inst = inst->Next_1xx();
2278 break;
2279 }
2280 case Instruction::DIV_LONG_2ADDR: {
2281 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002282 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002283 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002284 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002285 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2286 break;
2287 }
2288 case Instruction::REM_LONG_2ADDR: {
2289 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002290 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002291 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002292 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002293 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
2294 break;
2295 }
2296 case Instruction::AND_LONG_2ADDR: {
2297 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002298 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002299 shadow_frame.SetVRegLong(vregA,
2300 shadow_frame.GetVRegLong(vregA) &
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002301 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002302 inst = inst->Next_1xx();
2303 break;
2304 }
2305 case Instruction::OR_LONG_2ADDR: {
2306 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002307 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002308 shadow_frame.SetVRegLong(vregA,
2309 shadow_frame.GetVRegLong(vregA) |
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002310 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002311 inst = inst->Next_1xx();
2312 break;
2313 }
2314 case Instruction::XOR_LONG_2ADDR: {
2315 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002316 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002317 shadow_frame.SetVRegLong(vregA,
2318 shadow_frame.GetVRegLong(vregA) ^
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002319 shadow_frame.GetVRegLong(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002320 inst = inst->Next_1xx();
2321 break;
2322 }
2323 case Instruction::SHL_LONG_2ADDR: {
2324 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002325 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002326 shadow_frame.SetVRegLong(vregA,
2327 shadow_frame.GetVRegLong(vregA) <<
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002328 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002329 inst = inst->Next_1xx();
2330 break;
2331 }
2332 case Instruction::SHR_LONG_2ADDR: {
2333 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002334 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002335 shadow_frame.SetVRegLong(vregA,
2336 shadow_frame.GetVRegLong(vregA) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002337 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002338 inst = inst->Next_1xx();
2339 break;
2340 }
2341 case Instruction::USHR_LONG_2ADDR: {
2342 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002343 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002344 shadow_frame.SetVRegLong(vregA,
2345 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >>
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002346 (shadow_frame.GetVReg(inst->VRegB_12x(inst_data)) & 0x3f));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002347 inst = inst->Next_1xx();
2348 break;
2349 }
2350 case Instruction::ADD_FLOAT_2ADDR: {
2351 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002352 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002353 shadow_frame.SetVRegFloat(vregA,
2354 shadow_frame.GetVRegFloat(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002355 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002356 inst = inst->Next_1xx();
2357 break;
2358 }
2359 case Instruction::SUB_FLOAT_2ADDR: {
2360 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002361 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002362 shadow_frame.SetVRegFloat(vregA,
2363 shadow_frame.GetVRegFloat(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002364 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002365 inst = inst->Next_1xx();
2366 break;
2367 }
2368 case Instruction::MUL_FLOAT_2ADDR: {
2369 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002370 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002371 shadow_frame.SetVRegFloat(vregA,
2372 shadow_frame.GetVRegFloat(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002373 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002374 inst = inst->Next_1xx();
2375 break;
2376 }
2377 case Instruction::DIV_FLOAT_2ADDR: {
2378 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002379 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002380 shadow_frame.SetVRegFloat(vregA,
2381 shadow_frame.GetVRegFloat(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002382 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002383 inst = inst->Next_1xx();
2384 break;
2385 }
2386 case Instruction::REM_FLOAT_2ADDR: {
2387 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002388 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002389 shadow_frame.SetVRegFloat(vregA,
2390 fmodf(shadow_frame.GetVRegFloat(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002391 shadow_frame.GetVRegFloat(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002392 inst = inst->Next_1xx();
2393 break;
2394 }
2395 case Instruction::ADD_DOUBLE_2ADDR: {
2396 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002397 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002398 shadow_frame.SetVRegDouble(vregA,
2399 shadow_frame.GetVRegDouble(vregA) +
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002400 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002401 inst = inst->Next_1xx();
2402 break;
2403 }
2404 case Instruction::SUB_DOUBLE_2ADDR: {
2405 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002406 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002407 shadow_frame.SetVRegDouble(vregA,
2408 shadow_frame.GetVRegDouble(vregA) -
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002409 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002410 inst = inst->Next_1xx();
2411 break;
2412 }
2413 case Instruction::MUL_DOUBLE_2ADDR: {
2414 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002415 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002416 shadow_frame.SetVRegDouble(vregA,
2417 shadow_frame.GetVRegDouble(vregA) *
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002418 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002419 inst = inst->Next_1xx();
2420 break;
2421 }
2422 case Instruction::DIV_DOUBLE_2ADDR: {
2423 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002424 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002425 shadow_frame.SetVRegDouble(vregA,
2426 shadow_frame.GetVRegDouble(vregA) /
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002427 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data)));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002428 inst = inst->Next_1xx();
2429 break;
2430 }
2431 case Instruction::REM_DOUBLE_2ADDR: {
2432 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002433 uint4_t vregA = inst->VRegA_12x(inst_data);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002434 shadow_frame.SetVRegDouble(vregA,
2435 fmod(shadow_frame.GetVRegDouble(vregA),
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002436 shadow_frame.GetVRegDouble(inst->VRegB_12x(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002437 inst = inst->Next_1xx();
2438 break;
2439 }
2440 case Instruction::ADD_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 SafeAdd(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;
Ian Rogersf72a11d2014-10-30 15:41:08 -07002447 case Instruction::RSUB_INT_LIT16:
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002448 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002449 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002450 SafeSub(inst->VRegC_22s(),
2451 shadow_frame.GetVReg(inst->VRegB_22s(inst_data))));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002452 inst = inst->Next_2xx();
2453 break;
2454 case Instruction::MUL_INT_LIT16:
2455 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002456 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002457 SafeMul(shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2458 inst->VRegC_22s()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002459 inst = inst->Next_2xx();
2460 break;
2461 case Instruction::DIV_INT_LIT16: {
2462 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002463 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002464 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2465 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002466 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2467 break;
2468 }
2469 case Instruction::REM_INT_LIT16: {
2470 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002471 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(inst_data),
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002472 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)),
2473 inst->VRegC_22s());
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002474 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2475 break;
2476 }
2477 case Instruction::AND_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::OR_INT_LIT16:
2485 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002486 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2487 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) |
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002488 inst->VRegC_22s());
2489 inst = inst->Next_2xx();
2490 break;
2491 case Instruction::XOR_INT_LIT16:
2492 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002493 shadow_frame.SetVReg(inst->VRegA_22s(inst_data),
2494 shadow_frame.GetVReg(inst->VRegB_22s(inst_data)) ^
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002495 inst->VRegC_22s());
2496 inst = inst->Next_2xx();
2497 break;
2498 case Instruction::ADD_INT_LIT8:
2499 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002500 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002501 SafeAdd(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002502 inst = inst->Next_2xx();
2503 break;
2504 case Instruction::RSUB_INT_LIT8:
2505 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002506 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002507 SafeSub(inst->VRegC_22b(), shadow_frame.GetVReg(inst->VRegB_22b())));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002508 inst = inst->Next_2xx();
2509 break;
2510 case Instruction::MUL_INT_LIT8:
2511 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002512 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Ian Rogersf72a11d2014-10-30 15:41:08 -07002513 SafeMul(shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()));
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002514 inst = inst->Next_2xx();
2515 break;
2516 case Instruction::DIV_INT_LIT8: {
2517 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002518 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002519 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2520 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2521 break;
2522 }
2523 case Instruction::REM_INT_LIT8: {
2524 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002525 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002526 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b());
2527 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
2528 break;
2529 }
2530 case Instruction::AND_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::OR_INT_LIT8:
2538 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002539 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002540 shadow_frame.GetVReg(inst->VRegB_22b()) |
2541 inst->VRegC_22b());
2542 inst = inst->Next_2xx();
2543 break;
2544 case Instruction::XOR_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());
2549 inst = inst->Next_2xx();
2550 break;
2551 case Instruction::SHL_INT_LIT8:
2552 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002553 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002554 shadow_frame.GetVReg(inst->VRegB_22b()) <<
2555 (inst->VRegC_22b() & 0x1f));
2556 inst = inst->Next_2xx();
2557 break;
2558 case Instruction::SHR_INT_LIT8:
2559 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002560 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002561 shadow_frame.GetVReg(inst->VRegB_22b()) >>
2562 (inst->VRegC_22b() & 0x1f));
2563 inst = inst->Next_2xx();
2564 break;
2565 case Instruction::USHR_INT_LIT8:
2566 PREAMBLE();
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002567 shadow_frame.SetVReg(inst->VRegA_22b(inst_data),
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002568 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >>
2569 (inst->VRegC_22b() & 0x1f));
2570 inst = inst->Next_2xx();
2571 break;
2572 case Instruction::UNUSED_3E ... Instruction::UNUSED_43:
Orion Hodson2e599942017-09-22 16:17:41 +01002573 case Instruction::UNUSED_79 ... Instruction::UNUSED_7A:
Narayan Kamath8ec3bd22016-08-03 12:46:23 +01002574 case Instruction::UNUSED_F3 ... Instruction::UNUSED_F9:
Ian Rogerse94652f2014-12-02 11:13:19 -08002575 UnexpectedOpcode(inst, shadow_frame);
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002576 }
buzbee1452bee2015-03-06 14:43:04 -08002577 } while (!interpret_one_instruction);
2578 // Record where we stopped.
2579 shadow_frame.SetDexPC(inst->GetDexPc(insns));
David Srbecky946bb092018-03-09 17:23:01 +00002580 ctx->result = result_register;
2581 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002582} // NOLINT(readability/fn_size)
2583
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002584} // namespace interpreter
2585} // namespace art
David Srbecky2ee09ff2018-10-24 13:24:22 +01002586
2587#endif // ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_