blob: 085c475783e08ac934b5d596233ea7536c5229cd [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 Light49af7042019-05-29 18:30:33 -070023#include "base/globals.h"
Alex Light6f22e062018-10-05 15:05:12 -070024#include "base/memory_tool.h"
David Sehrc431b9d2018-03-02 12:01:51 -080025#include "base/quasi_atomic.h"
David Sehr9e734c72018-01-04 17:56:19 -080026#include "dex/dex_file_types.h"
David Srbecky6da82472018-10-23 14:03:08 +010027#include "dex/dex_instruction_list.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070028#include "experimental_flags.h"
Alex Light49af7042019-05-29 18:30:33 -070029#include "handle_scope.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020030#include "interpreter_common.h"
Alex Light49af7042019-05-29 18:30:33 -070031#include "interpreter/shadow_frame.h"
David Srbeckye3fc2d12018-11-30 13:41:14 +000032#include "jit/jit-inl.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070033#include "jvalue-inl.h"
Andreas Gampefd63bbf2018-10-29 12:55:35 -070034#include "mirror/string-alloc-inl.h"
Alex Light49af7042019-05-29 18:30:33 -070035#include "mirror/throwable.h"
Alex Lightb7c640d2019-03-20 15:52:13 -070036#include "monitor.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000037#include "nth_caller_visitor.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070038#include "safe_math.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010039#include "shadow_frame-inl.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000040#include "thread.h"
Alex Light49af7042019-05-29 18:30:33 -070041#include "verifier/method_verifier.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020042
43namespace art {
44namespace interpreter {
45
David Srbecky6da82472018-10-23 14:03:08 +010046// Short-lived helper class which executes single DEX bytecode. It is inlined by compiler.
47//
48// The function names must match the names from dex_instruction_list.h and have no arguments.
49//
50// Any relevant execution information is stored in the fields - it should be kept to minimum.
51//
David Srbecky47ad3762018-10-31 12:43:40 +000052// Helper methods may return boolean value - in which case 'false' always means
53// "stop executing current opcode" (which does not necessarily exit the interpreter loop).
54//
David Srbecky436f6c12019-05-22 13:28:42 +010055template<bool do_access_check, bool transaction_active, Instruction::Format kFormat>
David Srbecky6da82472018-10-23 14:03:08 +010056class InstructionHandler {
57 public:
David Srbecky47ad3762018-10-31 12:43:40 +000058 ALWAYS_INLINE WARN_UNUSED bool CheckForceReturn()
59 REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Lightb7c640d2019-03-20 15:52:13 -070060 if (PerformNonStandardReturn<kMonitorState>(self,
61 shadow_frame,
62 ctx->result,
63 instrumentation,
64 Accessor().InsSize(),
65 inst->GetDexPc(Insns()))) {
David Srbecky47ad3762018-10-31 12:43:40 +000066 exit_interpreter_loop = true;
67 return false;
68 }
69 return true;
70 }
71
David Srbecky5f250012018-11-08 14:16:38 +000072 NO_INLINE WARN_UNUSED bool HandlePendingExceptionWithInstrumentationImpl(
David Srbecky47ad3762018-10-31 12:43:40 +000073 const instrumentation::Instrumentation* instr)
74 REQUIRES_SHARED(Locks::mutator_lock_) {
75 DCHECK(self->IsExceptionPending());
76 self->AllowThreadSuspension();
77 if (!CheckForceReturn()) {
78 return false;
79 }
80 if (!MoveToExceptionHandler(self, shadow_frame, instr)) {
81 /* Structured locking is to be enforced for abnormal termination, too. */
82 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame);
83 if (ctx->interpret_one_instruction) {
84 /* Signal mterp to return to caller */
85 shadow_frame.SetDexPC(dex::kDexNoIndex);
86 }
87 ctx->result = JValue(); /* Handled in caller. */
88 exit_interpreter_loop = true;
89 return false; // Return to caller.
90 }
91 if (!CheckForceReturn()) {
92 return false;
93 }
94 int32_t displacement =
95 static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc);
David Srbecky8867f3b2019-05-31 20:01:46 +010096 SetNextInstruction(inst->RelativeAt(displacement));
David Srbecky47ad3762018-10-31 12:43:40 +000097 inst = inst->RelativeAt(displacement);
98 return false; // Stop executing this opcode and continue in the exception handler.
99 }
100
David Srbecky5f250012018-11-08 14:16:38 +0000101 // Forwards the call to the NO_INLINE HandlePendingExceptionWithInstrumentationImpl.
102 ALWAYS_INLINE WARN_UNUSED bool HandlePendingExceptionWithInstrumentation(
103 const instrumentation::Instrumentation* instr)
104 REQUIRES_SHARED(Locks::mutator_lock_) {
105 // We need to help the compiler a bit to make the NO_INLINE call efficient.
106 // * All handler fields should be in registers, so we do not want to take the object
107 // address (for 'this' argument). Make a copy of the handler just for the slow path.
108 // * The modifiable fields should also be in registers, so we don't want to store their
109 // address even in the handler copy. Make a copy of them just for the call as well.
David Srbecky8867f3b2019-05-31 20:01:46 +0100110 const Instruction* inst2 = inst;
111 const Instruction* next2 = next;
112 bool exit2 = exit_interpreter_loop;
David Srbecky436f6c12019-05-22 13:28:42 +0100113 InstructionHandler<do_access_check, transaction_active, kFormat> handler_copy(
David Srbecky8867f3b2019-05-31 20:01:46 +0100114 ctx, instrumentation, self, shadow_frame, dex_pc, inst2, inst_data, next2, exit2);
David Srbecky5f250012018-11-08 14:16:38 +0000115 bool result = handler_copy.HandlePendingExceptionWithInstrumentationImpl(instr);
David Srbecky8867f3b2019-05-31 20:01:46 +0100116 inst = inst2;
117 next = next2;
118 exit_interpreter_loop = exit2;
David Srbecky5f250012018-11-08 14:16:38 +0000119 return result;
120 }
121
David Srbecky47ad3762018-10-31 12:43:40 +0000122 ALWAYS_INLINE WARN_UNUSED bool HandlePendingException()
123 REQUIRES_SHARED(Locks::mutator_lock_) {
124 return HandlePendingExceptionWithInstrumentation(instrumentation);
125 }
126
127 ALWAYS_INLINE WARN_UNUSED bool PossiblyHandlePendingExceptionOnInvokeImpl(
128 bool is_exception_pending,
129 const Instruction* next_inst)
130 REQUIRES_SHARED(Locks::mutator_lock_) {
131 if (UNLIKELY(shadow_frame.GetForceRetryInstruction())) {
132 /* Don't need to do anything except clear the flag and exception. We leave the */
133 /* instruction the same so it will be re-executed on the next go-around. */
134 DCHECK(inst->IsInvoke());
135 shadow_frame.SetForceRetryInstruction(false);
136 if (UNLIKELY(is_exception_pending)) {
137 DCHECK(self->IsExceptionPending());
138 if (kIsDebugBuild) {
139 LOG(WARNING) << "Suppressing exception for instruction-retry: "
140 << self->GetException()->Dump();
141 }
142 self->ClearException();
143 }
David Srbecky8867f3b2019-05-31 20:01:46 +0100144 SetNextInstruction(inst);
David Srbecky47ad3762018-10-31 12:43:40 +0000145 } else if (UNLIKELY(is_exception_pending)) {
146 /* Should have succeeded. */
147 DCHECK(!shadow_frame.GetForceRetryInstruction());
148 if (!HandlePendingException()) {
149 return false;
150 }
151 } else {
David Srbecky8867f3b2019-05-31 20:01:46 +0100152 SetNextInstruction(next_inst);
David Srbecky47ad3762018-10-31 12:43:40 +0000153 inst = next_inst;
154 }
155 return true;
156 }
157
158 ALWAYS_INLINE WARN_UNUSED bool PossiblyHandlePendingException(
159 bool is_exception_pending,
160 const Instruction* next_inst)
161 REQUIRES_SHARED(Locks::mutator_lock_) {
162 /* Should only be on invoke instructions. */
163 DCHECK(!shadow_frame.GetForceRetryInstruction());
164 if (UNLIKELY(is_exception_pending)) {
165 if (!HandlePendingException()) {
166 return false;
167 }
168 } else {
David Srbecky8867f3b2019-05-31 20:01:46 +0100169 SetNextInstruction(next_inst);
David Srbecky47ad3762018-10-31 12:43:40 +0000170 inst = next_inst;
171 }
172 return true;
173 }
174
175 ALWAYS_INLINE WARN_UNUSED bool HandleMonitorChecks()
176 REQUIRES_SHARED(Locks::mutator_lock_) {
177 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) {
178 if (!HandlePendingException()) {
179 return false;
180 }
181 }
182 return true;
183 }
184
185 // Code to run before each dex instruction.
David Srbeckya4a96af2018-10-31 16:34:58 +0000186 ALWAYS_INLINE WARN_UNUSED bool Preamble()
David Srbecky47ad3762018-10-31 12:43:40 +0000187 REQUIRES_SHARED(Locks::mutator_lock_) {
188 /* We need to put this before & after the instrumentation to avoid having to put in a */
189 /* post-script macro. */
190 if (!CheckForceReturn()) {
191 return false;
192 }
193 if (UNLIKELY(instrumentation->HasDexPcListeners())) {
David Srbeckya4a96af2018-10-31 16:34:58 +0000194 uint8_t opcode = inst->Opcode(inst_data);
195 bool is_move_result_object = (opcode == Instruction::MOVE_RESULT_OBJECT);
196 JValue* save_ref = is_move_result_object ? &ctx->result_register : nullptr;
David Srbecky47ad3762018-10-31 12:43:40 +0000197 if (UNLIKELY(!DoDexPcMoveEvent(self,
198 Accessor(),
199 shadow_frame,
200 dex_pc,
201 instrumentation,
202 save_ref))) {
203 if (!HandlePendingException()) {
204 return false;
205 }
206 }
207 if (!CheckForceReturn()) {
208 return false;
209 }
210 }
211 return true;
212 }
213
214 ALWAYS_INLINE WARN_UNUSED bool BranchInstrumentation(int32_t offset)
215 REQUIRES_SHARED(Locks::mutator_lock_) {
216 if (UNLIKELY(instrumentation->HasBranchListeners())) {
217 instrumentation->Branch(self, shadow_frame.GetMethod(), dex_pc, offset);
218 }
219 JValue result;
220 if (jit::Jit::MaybeDoOnStackReplacement(self,
221 shadow_frame.GetMethod(),
222 dex_pc,
223 offset,
224 &result)) {
225 if (ctx->interpret_one_instruction) {
226 /* OSR has completed execution of the method. Signal mterp to return to caller */
227 shadow_frame.SetDexPC(dex::kDexNoIndex);
228 }
229 ctx->result = result;
230 exit_interpreter_loop = true;
231 return false;
232 }
233 return true;
234 }
235
236 ALWAYS_INLINE void HotnessUpdate()
237 REQUIRES_SHARED(Locks::mutator_lock_) {
238 jit::Jit* jit = Runtime::Current()->GetJit();
239 if (jit != nullptr) {
240 jit->AddSamples(self, shadow_frame.GetMethod(), 1, /*with_backedges=*/ true);
241 }
242 }
243
244 ALWAYS_INLINE WARN_UNUSED bool HandleAsyncException()
245 REQUIRES_SHARED(Locks::mutator_lock_) {
246 if (UNLIKELY(self->ObserveAsyncException())) {
247 if (!HandlePendingException()) {
248 return false;
249 }
250 }
251 return true;
252 }
253
254 ALWAYS_INLINE void HandleBackwardBranch(int32_t offset)
255 REQUIRES_SHARED(Locks::mutator_lock_) {
256 if (IsBackwardBranch(offset)) {
257 HotnessUpdate();
258 /* Record new dex pc early to have consistent suspend point at loop header. */
259 shadow_frame.SetDexPC(inst->GetDexPc(Insns()));
260 self->AllowThreadSuspension();
261 }
262 }
263
264 // Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
265 // the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
266 // to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
267 // jvmti-agents while handling breakpoint or single step events. We had to move this into its own
268 // function because it was making ExecuteSwitchImpl have too large a stack.
269 NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
270 const CodeItemDataAccessor& accessor,
271 const ShadowFrame& shadow_frame,
272 uint32_t dex_pc,
273 const instrumentation::Instrumentation* instrumentation,
274 JValue* save_ref)
275 REQUIRES_SHARED(Locks::mutator_lock_) {
276 DCHECK(instrumentation->HasDexPcListeners());
277 StackHandleScope<2> hs(self);
278 Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
279 mirror::Object* null_obj = nullptr;
280 HandleWrapper<mirror::Object> h(
281 hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
282 self->ClearException();
283 instrumentation->DexPcMovedEvent(self,
284 shadow_frame.GetThisObject(accessor.InsSize()),
285 shadow_frame.GetMethod(),
286 dex_pc);
287 if (UNLIKELY(self->IsExceptionPending())) {
288 // We got a new exception in the dex-pc-moved event.
289 // We just let this exception replace the old one.
290 // TODO It would be good to add the old exception to the
291 // suppressed exceptions of the new one if possible.
292 return false;
293 } else {
294 if (UNLIKELY(!thr.IsNull())) {
295 self->SetException(thr.Get());
296 }
297 return true;
298 }
299 }
300
David Srbecky47ad3762018-10-31 12:43:40 +0000301#define BRANCH_INSTRUMENTATION(offset) \
302 if (!BranchInstrumentation(offset)) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100303 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000304 }
305
306#define HANDLE_PENDING_EXCEPTION() \
307 if (!HandlePendingException()) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100308 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000309 }
310
311#define POSSIBLY_HANDLE_PENDING_EXCEPTION(is_exception_pending, next_function) \
312 if (!PossiblyHandlePendingException(is_exception_pending, inst->next_function())) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100313 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000314 }
315
316#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(is_exception_pending) \
317 if (!PossiblyHandlePendingExceptionOnInvokeImpl(is_exception_pending, inst->Next_4xx())) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100318 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000319 }
320
321#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(is_exception_pending) \
322 if (!PossiblyHandlePendingExceptionOnInvokeImpl(is_exception_pending, inst->Next_3xx())) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100323 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000324 }
325
David Srbeckyee12e3a2019-06-03 15:18:57 +0100326 ALWAYS_INLINE WARN_UNUSED bool HandleReturn(JValue result) REQUIRES_SHARED(Locks::mutator_lock_) {
327 self->AllowThreadSuspension();
328 if (!HandleMonitorChecks()) {
329 return false;
330 }
331 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
332 !SendMethodExitEvents(self,
333 instrumentation,
334 shadow_frame,
335 shadow_frame.GetThisObject(Accessor().InsSize()),
336 shadow_frame.GetMethod(),
337 inst->GetDexPc(Insns()),
338 result))) {
339 if (!HandlePendingExceptionWithInstrumentation(nullptr)) {
340 return false;
341 }
342 }
343 if (ctx->interpret_one_instruction) {
344 /* Signal mterp to return to caller */
345 shadow_frame.SetDexPC(dex::kDexNoIndex);
346 }
347 ctx->result = result;
348 exit_interpreter_loop = true;
349 return true;
350 }
351
352 ALWAYS_INLINE WARN_UNUSED bool HandleGoto(int32_t offset) REQUIRES_SHARED(Locks::mutator_lock_) {
353 if (!HandleAsyncException()) {
354 return false;
355 }
356 BRANCH_INSTRUMENTATION(offset);
David Srbecky8867f3b2019-05-31 20:01:46 +0100357 SetNextInstruction(inst->RelativeAt(offset));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100358 inst = inst->RelativeAt(offset);
359 HandleBackwardBranch(offset);
360 return true;
361 }
362
363#pragma clang diagnostic push
364#pragma clang diagnostic ignored "-Wfloat-equal"
365
366 template<typename T>
367 ALWAYS_INLINE WARN_UNUSED bool HandleCmpl(T val1, T val2) REQUIRES_SHARED(Locks::mutator_lock_) {
368 int32_t result;
369 if (val1 > val2) {
370 result = 1;
371 } else if (val1 == val2) {
372 result = 0;
373 } else {
374 result = -1;
375 }
376 SetVReg(A(), result);
377 inst = inst->Next_2xx();
378 return true;
379 }
380
381 // Returns the same result as the function above. It only differs for NaN values.
382 template<typename T>
383 ALWAYS_INLINE WARN_UNUSED bool HandleCmpg(T val1, T val2) REQUIRES_SHARED(Locks::mutator_lock_) {
384 int32_t result;
385 if (val1 < val2) {
386 result = -1;
387 } else if (val1 == val2) {
388 result = 0;
389 } else {
390 result = 1;
391 }
392 SetVReg(A(), result);
393 inst = inst->Next_2xx();
394 return true;
395 }
396
397#pragma clang diagnostic pop
398
399 ALWAYS_INLINE WARN_UNUSED bool HandleIf(bool cond, int32_t offset)
400 REQUIRES_SHARED(Locks::mutator_lock_) {
401 if (cond) {
402 BRANCH_INSTRUMENTATION(offset);
David Srbecky8867f3b2019-05-31 20:01:46 +0100403 SetNextInstruction(inst->RelativeAt(offset));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100404 inst = inst->RelativeAt(offset);
405 HandleBackwardBranch(offset);
406 } else {
407 BRANCH_INSTRUMENTATION(2);
408 inst = inst->Next_2xx();
409 }
410 return true;
411 }
412
David Srbecky1332c262019-06-04 13:13:37 +0100413 template<typename ArrayType, typename SetVRegFn>
414 ALWAYS_INLINE bool HandleAGet(SetVRegFn setVReg) REQUIRES_SHARED(Locks::mutator_lock_) {
415 ObjPtr<mirror::Object> a = GetVRegReference(B());
416 if (UNLIKELY(a == nullptr)) {
417 ThrowNullPointerExceptionFromInterpreter();
418 HANDLE_PENDING_EXCEPTION();
419 }
420 int32_t index = GetVReg(C());
421 ObjPtr<ArrayType> array = ObjPtr<ArrayType>::DownCast(a);
422 if (UNLIKELY(!array->CheckIsValidIndex(index))) {
423 HANDLE_PENDING_EXCEPTION();
424 } else {
425 (this->*setVReg)(A(), array->GetWithoutChecks(index));
426 inst = inst->Next_2xx();
427 }
428 return true;
429 }
430
431 template<typename ArrayType, typename T>
432 ALWAYS_INLINE bool HandleAPut(T value) REQUIRES_SHARED(Locks::mutator_lock_) {
433 ObjPtr<mirror::Object> a = GetVRegReference(B());
434 if (UNLIKELY(a == nullptr)) {
435 ThrowNullPointerExceptionFromInterpreter();
436 HANDLE_PENDING_EXCEPTION();
437 }
438 int32_t index = GetVReg(C());
439 ObjPtr<ArrayType> array = ObjPtr<ArrayType>::DownCast(a);
440 if (UNLIKELY(!array->CheckIsValidIndex(index))) {
441 HANDLE_PENDING_EXCEPTION();
442 } else {
443 array->template SetWithoutChecks<transaction_active>(index, value);
444 inst = inst->Next_2xx();
445 }
446 return true;
447 }
448
David Srbeckyee12e3a2019-06-03 15:18:57 +0100449 template<FindFieldType find_type, Primitive::Type field_type>
450 ALWAYS_INLINE WARN_UNUSED bool HandleGet() REQUIRES_SHARED(Locks::mutator_lock_) {
451 bool success = DoFieldGet<find_type, field_type, do_access_check, transaction_active>(
452 self, shadow_frame, inst, inst_data);
453 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
454 return true;
455 }
456
457 template<Primitive::Type field_type>
458 ALWAYS_INLINE WARN_UNUSED bool HandleGetQuick() REQUIRES_SHARED(Locks::mutator_lock_) {
459 bool success = DoIGetQuick<field_type>(shadow_frame, inst, inst_data);
460 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
461 return true;
462 }
463
464 template<FindFieldType find_type, Primitive::Type field_type>
465 ALWAYS_INLINE WARN_UNUSED bool HandlePut() REQUIRES_SHARED(Locks::mutator_lock_) {
466 bool success = DoFieldPut<find_type, field_type, do_access_check, transaction_active>(
467 self, shadow_frame, inst, inst_data);
468 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
469 return true;
470 }
471
472 template<Primitive::Type field_type>
473 ALWAYS_INLINE WARN_UNUSED bool HandlePutQuick() REQUIRES_SHARED(Locks::mutator_lock_) {
474 bool success = DoIPutQuick<field_type, transaction_active>(
475 shadow_frame, inst, inst_data);
476 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
477 return true;
478 }
479
480 template<InvokeType type, bool is_range, bool is_quick = false>
481 ALWAYS_INLINE WARN_UNUSED bool HandleInvoke() REQUIRES_SHARED(Locks::mutator_lock_) {
482 bool success = DoInvoke<type, is_range, do_access_check, /*is_mterp=*/ false, is_quick>(
483 self, shadow_frame, inst, inst_data, ResultRegister());
484 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
485 return true;
486 }
487
488 ALWAYS_INLINE WARN_UNUSED bool HandleUnused() REQUIRES_SHARED(Locks::mutator_lock_) {
489 UnexpectedOpcode(inst, shadow_frame);
490 return true;
491 }
492
David Srbeckybd613ec2019-05-30 15:39:38 +0100493 ALWAYS_INLINE bool NOP() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100494 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100495 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100496 }
497
David Srbeckybd613ec2019-05-30 15:39:38 +0100498 ALWAYS_INLINE bool MOVE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100499 SetVReg(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100500 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100501 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100502 }
503
David Srbeckybd613ec2019-05-30 15:39:38 +0100504 ALWAYS_INLINE bool MOVE_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100505 SetVReg(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100506 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100507 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100508 }
509
David Srbeckybd613ec2019-05-30 15:39:38 +0100510 ALWAYS_INLINE bool MOVE_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100511 SetVReg(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100512 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100513 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100514 }
515
David Srbeckybd613ec2019-05-30 15:39:38 +0100516 ALWAYS_INLINE bool MOVE_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100517 SetVRegLong(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100518 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100519 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100520 }
521
David Srbeckybd613ec2019-05-30 15:39:38 +0100522 ALWAYS_INLINE bool MOVE_WIDE_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100523 SetVRegLong(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100524 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100525 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100526 }
527
David Srbeckybd613ec2019-05-30 15:39:38 +0100528 ALWAYS_INLINE bool MOVE_WIDE_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100529 SetVRegLong(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100530 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100531 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100532 }
533
David Srbeckybd613ec2019-05-30 15:39:38 +0100534 ALWAYS_INLINE bool MOVE_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100535 SetVRegReference(A(), GetVRegReference(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100536 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100537 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100538 }
539
David Srbeckybd613ec2019-05-30 15:39:38 +0100540 ALWAYS_INLINE bool MOVE_OBJECT_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100541 SetVRegReference(A(), GetVRegReference(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100542 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100543 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100544 }
545
David Srbeckybd613ec2019-05-30 15:39:38 +0100546 ALWAYS_INLINE bool MOVE_OBJECT_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100547 SetVRegReference(A(), GetVRegReference(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100548 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100549 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100550 }
551
David Srbeckybd613ec2019-05-30 15:39:38 +0100552 ALWAYS_INLINE bool MOVE_RESULT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100553 SetVReg(A(), ResultRegister()->GetI());
David Srbecky6da82472018-10-23 14:03:08 +0100554 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100555 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100556 }
557
David Srbeckybd613ec2019-05-30 15:39:38 +0100558 ALWAYS_INLINE bool MOVE_RESULT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100559 SetVRegLong(A(), ResultRegister()->GetJ());
David Srbecky6da82472018-10-23 14:03:08 +0100560 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100561 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100562 }
563
David Srbeckybd613ec2019-05-30 15:39:38 +0100564 ALWAYS_INLINE bool MOVE_RESULT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100565 SetVRegReference(A(), ResultRegister()->GetL());
David Srbecky6da82472018-10-23 14:03:08 +0100566 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100567 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100568 }
569
David Srbeckybd613ec2019-05-30 15:39:38 +0100570 ALWAYS_INLINE bool MOVE_EXCEPTION() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100571 ObjPtr<mirror::Throwable> exception = self->GetException();
572 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
David Srbecky6baf6442019-05-30 14:57:43 +0100573 SetVRegReference(A(), exception);
David Srbecky6da82472018-10-23 14:03:08 +0100574 self->ClearException();
575 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100576 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100577 }
578
David Srbeckybd613ec2019-05-30 15:39:38 +0100579 ALWAYS_INLINE bool RETURN_VOID_NO_BARRIER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100580 JValue result;
David Srbeckyee12e3a2019-06-03 15:18:57 +0100581 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100582 }
583
David Srbeckybd613ec2019-05-30 15:39:38 +0100584 ALWAYS_INLINE bool RETURN_VOID() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100585 QuasiAtomic::ThreadFenceForConstructor();
586 JValue result;
David Srbeckyee12e3a2019-06-03 15:18:57 +0100587 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100588 }
589
David Srbeckybd613ec2019-05-30 15:39:38 +0100590 ALWAYS_INLINE bool RETURN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100591 JValue result;
592 result.SetJ(0);
David Srbecky6baf6442019-05-30 14:57:43 +0100593 result.SetI(GetVReg(A()));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100594 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100595 }
596
David Srbeckybd613ec2019-05-30 15:39:38 +0100597 ALWAYS_INLINE bool RETURN_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100598 JValue result;
David Srbecky6baf6442019-05-30 14:57:43 +0100599 result.SetJ(GetVRegLong(A()));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100600 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100601 }
602
David Srbeckybd613ec2019-05-30 15:39:38 +0100603 ALWAYS_INLINE bool RETURN_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100604 JValue result;
605 self->AllowThreadSuspension();
David Srbecky47ad3762018-10-31 12:43:40 +0000606 if (!HandleMonitorChecks()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100607 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000608 }
David Srbeckyd6f579c2019-05-29 18:09:30 +0100609 const size_t ref_idx = A();
David Srbecky6baf6442019-05-30 14:57:43 +0100610 ObjPtr<mirror::Object> obj_result = GetVRegReference(ref_idx);
David Srbecky6da82472018-10-23 14:03:08 +0100611 if (do_assignability_check && obj_result != nullptr) {
612 ObjPtr<mirror::Class> return_type = shadow_frame.GetMethod()->ResolveReturnType();
613 // Re-load since it might have moved.
David Srbecky6baf6442019-05-30 14:57:43 +0100614 obj_result = GetVRegReference(ref_idx);
David Srbecky6da82472018-10-23 14:03:08 +0100615 if (return_type == nullptr) {
616 // Return the pending exception.
617 HANDLE_PENDING_EXCEPTION();
618 }
619 if (!obj_result->VerifierInstanceOf(return_type)) {
620 // This should never happen.
621 std::string temp1, temp2;
622 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
623 "Returning '%s' that is not instance of return type '%s'",
624 obj_result->GetClass()->GetDescriptor(&temp1),
625 return_type->GetDescriptor(&temp2));
626 HANDLE_PENDING_EXCEPTION();
627 }
628 }
Alex Lightb7c640d2019-03-20 15:52:13 -0700629 StackHandleScope<1> hs(self);
630 MutableHandle<mirror::Object> h_result(hs.NewHandle(obj_result));
David Srbecky6da82472018-10-23 14:03:08 +0100631 result.SetL(obj_result);
632 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
633 !SendMethodExitEvents(self,
634 instrumentation,
635 shadow_frame,
636 shadow_frame.GetThisObject(Accessor().InsSize()),
637 shadow_frame.GetMethod(),
638 inst->GetDexPc(Insns()),
Alex Lightb7c640d2019-03-20 15:52:13 -0700639 h_result))) {
David Srbecky47ad3762018-10-31 12:43:40 +0000640 if (!HandlePendingExceptionWithInstrumentation(nullptr)) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100641 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000642 }
David Srbecky6da82472018-10-23 14:03:08 +0100643 }
Alex Lightb7c640d2019-03-20 15:52:13 -0700644 // Re-load since it might have moved or been replaced during the MethodExitEvent.
645 result.SetL(h_result.Get());
David Srbecky6da82472018-10-23 14:03:08 +0100646 if (ctx->interpret_one_instruction) {
647 /* Signal mterp to return to caller */
648 shadow_frame.SetDexPC(dex::kDexNoIndex);
649 }
650 ctx->result = result;
651 exit_interpreter_loop = true;
David Srbeckybd613ec2019-05-30 15:39:38 +0100652 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100653 }
654
David Srbeckybd613ec2019-05-30 15:39:38 +0100655 ALWAYS_INLINE bool CONST_4() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100656 uint4_t dst = inst->VRegA_11n(inst_data);
657 int4_t val = inst->VRegB_11n(inst_data);
David Srbecky6baf6442019-05-30 14:57:43 +0100658 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100659 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100660 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100661 }
662 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100663 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100664 }
665
David Srbeckybd613ec2019-05-30 15:39:38 +0100666 ALWAYS_INLINE bool CONST_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100667 uint8_t dst = A();
668 int16_t val = B();
David Srbecky6baf6442019-05-30 14:57:43 +0100669 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100670 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100671 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100672 }
673 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100674 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100675 }
676
David Srbeckybd613ec2019-05-30 15:39:38 +0100677 ALWAYS_INLINE bool CONST() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100678 uint8_t dst = A();
679 int32_t val = B();
David Srbecky6baf6442019-05-30 14:57:43 +0100680 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100681 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100682 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100683 }
684 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100685 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100686 }
687
David Srbeckybd613ec2019-05-30 15:39:38 +0100688 ALWAYS_INLINE bool CONST_HIGH16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100689 uint8_t dst = A();
690 int32_t val = static_cast<int32_t>(B() << 16);
David Srbecky6baf6442019-05-30 14:57:43 +0100691 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100692 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100693 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100694 }
695 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100696 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100697 }
698
David Srbeckybd613ec2019-05-30 15:39:38 +0100699 ALWAYS_INLINE bool CONST_WIDE_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100700 SetVRegLong(A(), B());
David Srbecky6da82472018-10-23 14:03:08 +0100701 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100702 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100703 }
704
David Srbeckybd613ec2019-05-30 15:39:38 +0100705 ALWAYS_INLINE bool CONST_WIDE_32() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100706 SetVRegLong(A(), B());
David Srbecky6da82472018-10-23 14:03:08 +0100707 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100708 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100709 }
710
David Srbeckybd613ec2019-05-30 15:39:38 +0100711 ALWAYS_INLINE bool CONST_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100712 SetVRegLong(A(), inst->WideVRegB());
David Srbecky6da82472018-10-23 14:03:08 +0100713 inst = inst->Next_51l();
David Srbeckybd613ec2019-05-30 15:39:38 +0100714 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100715 }
716
David Srbeckybd613ec2019-05-30 15:39:38 +0100717 ALWAYS_INLINE bool CONST_WIDE_HIGH16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100718 SetVRegLong(A(), static_cast<uint64_t>(B()) << 48);
David Srbecky6da82472018-10-23 14:03:08 +0100719 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100720 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100721 }
722
David Srbeckybd613ec2019-05-30 15:39:38 +0100723 ALWAYS_INLINE bool CONST_STRING() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100724 ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, dex::StringIndex(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100725 if (UNLIKELY(s == nullptr)) {
726 HANDLE_PENDING_EXCEPTION();
727 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100728 SetVRegReference(A(), s);
David Srbecky6da82472018-10-23 14:03:08 +0100729 inst = inst->Next_2xx();
730 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100731 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100732 }
733
David Srbeckybd613ec2019-05-30 15:39:38 +0100734 ALWAYS_INLINE bool CONST_STRING_JUMBO() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100735 ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, dex::StringIndex(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100736 if (UNLIKELY(s == nullptr)) {
737 HANDLE_PENDING_EXCEPTION();
738 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100739 SetVRegReference(A(), s);
David Srbecky6da82472018-10-23 14:03:08 +0100740 inst = inst->Next_3xx();
741 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100742 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100743 }
744
David Srbeckybd613ec2019-05-30 15:39:38 +0100745 ALWAYS_INLINE bool CONST_CLASS() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100746 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100747 shadow_frame.GetMethod(),
748 self,
749 false,
750 do_access_check);
751 if (UNLIKELY(c == nullptr)) {
752 HANDLE_PENDING_EXCEPTION();
753 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100754 SetVRegReference(A(), c);
David Srbecky6da82472018-10-23 14:03:08 +0100755 inst = inst->Next_2xx();
756 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100757 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100758 }
759
David Srbeckybd613ec2019-05-30 15:39:38 +0100760 ALWAYS_INLINE bool CONST_METHOD_HANDLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100761 ClassLinker* cl = Runtime::Current()->GetClassLinker();
762 ObjPtr<mirror::MethodHandle> mh = cl->ResolveMethodHandle(self,
David Srbeckyd6f579c2019-05-29 18:09:30 +0100763 B(),
David Srbecky6da82472018-10-23 14:03:08 +0100764 shadow_frame.GetMethod());
765 if (UNLIKELY(mh == nullptr)) {
766 HANDLE_PENDING_EXCEPTION();
767 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100768 SetVRegReference(A(), mh);
David Srbecky6da82472018-10-23 14:03:08 +0100769 inst = inst->Next_2xx();
770 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100771 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100772 }
773
David Srbeckybd613ec2019-05-30 15:39:38 +0100774 ALWAYS_INLINE bool CONST_METHOD_TYPE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100775 ClassLinker* cl = Runtime::Current()->GetClassLinker();
776 ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(self,
David Srbeckyd6f579c2019-05-29 18:09:30 +0100777 dex::ProtoIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100778 shadow_frame.GetMethod());
779 if (UNLIKELY(mt == nullptr)) {
780 HANDLE_PENDING_EXCEPTION();
781 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100782 SetVRegReference(A(), mt);
David Srbecky6da82472018-10-23 14:03:08 +0100783 inst = inst->Next_2xx();
784 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100785 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100786 }
787
David Srbeckybd613ec2019-05-30 15:39:38 +0100788 ALWAYS_INLINE bool MONITOR_ENTER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000789 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100790 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000791 }
David Srbecky6baf6442019-05-30 14:57:43 +0100792 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100793 if (UNLIKELY(obj == nullptr)) {
794 ThrowNullPointerExceptionFromInterpreter();
795 HANDLE_PENDING_EXCEPTION();
796 } else {
797 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
798 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
799 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100800 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100801 }
802
David Srbeckybd613ec2019-05-30 15:39:38 +0100803 ALWAYS_INLINE bool MONITOR_EXIT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000804 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100805 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000806 }
David Srbecky6baf6442019-05-30 14:57:43 +0100807 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100808 if (UNLIKELY(obj == nullptr)) {
809 ThrowNullPointerExceptionFromInterpreter();
810 HANDLE_PENDING_EXCEPTION();
811 } else {
812 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
813 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
814 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100815 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100816 }
817
David Srbeckybd613ec2019-05-30 15:39:38 +0100818 ALWAYS_INLINE bool CHECK_CAST() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100819 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100820 shadow_frame.GetMethod(),
821 self,
822 false,
823 do_access_check);
824 if (UNLIKELY(c == nullptr)) {
825 HANDLE_PENDING_EXCEPTION();
826 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100827 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100828 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
829 ThrowClassCastException(c, obj->GetClass());
830 HANDLE_PENDING_EXCEPTION();
831 } else {
832 inst = inst->Next_2xx();
833 }
834 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100835 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100836 }
837
David Srbeckybd613ec2019-05-30 15:39:38 +0100838 ALWAYS_INLINE bool INSTANCE_OF() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100839 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(C()),
David Srbecky6da82472018-10-23 14:03:08 +0100840 shadow_frame.GetMethod(),
841 self,
842 false,
843 do_access_check);
844 if (UNLIKELY(c == nullptr)) {
845 HANDLE_PENDING_EXCEPTION();
846 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100847 ObjPtr<mirror::Object> obj = GetVRegReference(B());
848 SetVReg(A(), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
David Srbecky6da82472018-10-23 14:03:08 +0100849 inst = inst->Next_2xx();
850 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100851 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100852 }
853
David Srbeckybd613ec2019-05-30 15:39:38 +0100854 ALWAYS_INLINE bool ARRAY_LENGTH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100855 ObjPtr<mirror::Object> array = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +0100856 if (UNLIKELY(array == nullptr)) {
857 ThrowNullPointerExceptionFromInterpreter();
858 HANDLE_PENDING_EXCEPTION();
859 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100860 SetVReg(A(), array->AsArray()->GetLength());
David Srbecky6da82472018-10-23 14:03:08 +0100861 inst = inst->Next_1xx();
862 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100863 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100864 }
865
David Srbeckybd613ec2019-05-30 15:39:38 +0100866 ALWAYS_INLINE bool NEW_INSTANCE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100867 ObjPtr<mirror::Object> obj = nullptr;
David Srbeckyd6f579c2019-05-29 18:09:30 +0100868 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100869 shadow_frame.GetMethod(),
870 self,
871 false,
872 do_access_check);
873 if (LIKELY(c != nullptr)) {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100874 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
David Srbecky6da82472018-10-23 14:03:08 +0100875 if (UNLIKELY(c->IsStringClass())) {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100876 obj = mirror::String::AllocEmptyString(self, allocator_type);
David Srbecky6da82472018-10-23 14:03:08 +0100877 } else {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100878 obj = AllocObjectFromCode(c, self, allocator_type);
David Srbecky6da82472018-10-23 14:03:08 +0100879 }
880 }
881 if (UNLIKELY(obj == nullptr)) {
882 HANDLE_PENDING_EXCEPTION();
883 } else {
884 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
885 // Don't allow finalizable objects to be allocated during a transaction since these can't
886 // be finalized without a started runtime.
887 if (transaction_active && obj->GetClass()->IsFinalizable()) {
888 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
889 obj->PrettyTypeOf().c_str());
890 HANDLE_PENDING_EXCEPTION();
891 }
David Srbecky6baf6442019-05-30 14:57:43 +0100892 SetVRegReference(A(), obj);
David Srbecky6da82472018-10-23 14:03:08 +0100893 inst = inst->Next_2xx();
894 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100895 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100896 }
897
David Srbeckybd613ec2019-05-30 15:39:38 +0100898 ALWAYS_INLINE bool NEW_ARRAY() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100899 int32_t length = GetVReg(B());
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100900 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check>(
David Srbeckyd6f579c2019-05-29 18:09:30 +0100901 dex::TypeIndex(C()),
David Srbecky6da82472018-10-23 14:03:08 +0100902 length,
903 shadow_frame.GetMethod(),
904 self,
905 Runtime::Current()->GetHeap()->GetCurrentAllocator());
906 if (UNLIKELY(obj == nullptr)) {
907 HANDLE_PENDING_EXCEPTION();
908 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100909 SetVRegReference(A(), obj);
David Srbecky6da82472018-10-23 14:03:08 +0100910 inst = inst->Next_2xx();
911 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100912 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100913 }
914
David Srbeckybd613ec2019-05-30 15:39:38 +0100915 ALWAYS_INLINE bool FILLED_NEW_ARRAY() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100916 bool success =
917 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
918 ResultRegister());
919 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
David Srbeckybd613ec2019-05-30 15:39:38 +0100920 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100921 }
922
David Srbeckybd613ec2019-05-30 15:39:38 +0100923 ALWAYS_INLINE bool FILLED_NEW_ARRAY_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100924 bool success =
925 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
926 self, ResultRegister());
927 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
David Srbeckybd613ec2019-05-30 15:39:38 +0100928 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100929 }
930
David Srbeckybd613ec2019-05-30 15:39:38 +0100931 ALWAYS_INLINE bool FILL_ARRAY_DATA() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100932 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + B();
David Srbecky6da82472018-10-23 14:03:08 +0100933 const Instruction::ArrayDataPayload* payload =
934 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
David Srbecky6baf6442019-05-30 14:57:43 +0100935 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100936 bool success = FillArrayData(obj, payload);
937 if (!success) {
938 HANDLE_PENDING_EXCEPTION();
939 }
940 if (transaction_active) {
941 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
942 }
943 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100944 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100945 }
946
David Srbeckybd613ec2019-05-30 15:39:38 +0100947 ALWAYS_INLINE bool THROW() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000948 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100949 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000950 }
David Srbecky6baf6442019-05-30 14:57:43 +0100951 ObjPtr<mirror::Object> exception = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100952 if (UNLIKELY(exception == nullptr)) {
953 ThrowNullPointerException("throw with null exception");
954 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
955 // This should never happen.
956 std::string temp;
957 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
958 "Throwing '%s' that is not instance of Throwable",
959 exception->GetClass()->GetDescriptor(&temp));
960 } else {
961 self->SetException(exception->AsThrowable());
962 }
963 HANDLE_PENDING_EXCEPTION();
David Srbeckybd613ec2019-05-30 15:39:38 +0100964 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100965 }
966
David Srbeckybd613ec2019-05-30 15:39:38 +0100967 ALWAYS_INLINE bool GOTO() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100968 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +0100969 }
970
David Srbeckybd613ec2019-05-30 15:39:38 +0100971 ALWAYS_INLINE bool GOTO_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100972 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +0100973 }
974
David Srbeckybd613ec2019-05-30 15:39:38 +0100975 ALWAYS_INLINE bool GOTO_32() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100976 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +0100977 }
978
David Srbeckybd613ec2019-05-30 15:39:38 +0100979 ALWAYS_INLINE bool PACKED_SWITCH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100980 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
981 BRANCH_INSTRUMENTATION(offset);
David Srbecky8867f3b2019-05-31 20:01:46 +0100982 SetNextInstruction(inst->RelativeAt(offset));
David Srbecky6da82472018-10-23 14:03:08 +0100983 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +0000984 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +0100985 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100986 }
987
David Srbeckybd613ec2019-05-30 15:39:38 +0100988 ALWAYS_INLINE bool SPARSE_SWITCH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100989 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
990 BRANCH_INSTRUMENTATION(offset);
David Srbecky8867f3b2019-05-31 20:01:46 +0100991 SetNextInstruction(inst->RelativeAt(offset));
David Srbecky6da82472018-10-23 14:03:08 +0100992 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +0000993 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +0100994 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100995 }
996
David Srbeckybd613ec2019-05-30 15:39:38 +0100997 ALWAYS_INLINE bool CMPL_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100998 return HandleCmpl<float>(GetVRegFloat(B()), GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +0100999 }
1000
David Srbeckybd613ec2019-05-30 15:39:38 +01001001 ALWAYS_INLINE bool CMPG_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001002 return HandleCmpg<float>(GetVRegFloat(B()), GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001003 }
1004
David Srbeckybd613ec2019-05-30 15:39:38 +01001005 ALWAYS_INLINE bool CMPL_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001006 return HandleCmpl<double>(GetVRegDouble(B()), GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001007 }
1008
David Srbeckybd613ec2019-05-30 15:39:38 +01001009 ALWAYS_INLINE bool CMPG_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001010 return HandleCmpg<double>(GetVRegDouble(B()), GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001011 }
1012
David Srbeckybd613ec2019-05-30 15:39:38 +01001013 ALWAYS_INLINE bool CMP_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001014 return HandleCmpl<int64_t>(GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001015 }
1016
David Srbeckybd613ec2019-05-30 15:39:38 +01001017 ALWAYS_INLINE bool IF_EQ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001018 return HandleIf(GetVReg(A()) == GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001019 }
1020
David Srbeckybd613ec2019-05-30 15:39:38 +01001021 ALWAYS_INLINE bool IF_NE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001022 return HandleIf(GetVReg(A()) != GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001023 }
1024
David Srbeckybd613ec2019-05-30 15:39:38 +01001025 ALWAYS_INLINE bool IF_LT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001026 return HandleIf(GetVReg(A()) < GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001027 }
1028
David Srbeckybd613ec2019-05-30 15:39:38 +01001029 ALWAYS_INLINE bool IF_GE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001030 return HandleIf(GetVReg(A()) >= GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001031 }
1032
David Srbeckybd613ec2019-05-30 15:39:38 +01001033 ALWAYS_INLINE bool IF_GT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001034 return HandleIf(GetVReg(A()) > GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001035 }
1036
David Srbeckybd613ec2019-05-30 15:39:38 +01001037 ALWAYS_INLINE bool IF_LE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001038 return HandleIf(GetVReg(A()) <= GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001039 }
1040
David Srbeckybd613ec2019-05-30 15:39:38 +01001041 ALWAYS_INLINE bool IF_EQZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001042 return HandleIf(GetVReg(A()) == 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001043 }
1044
David Srbeckybd613ec2019-05-30 15:39:38 +01001045 ALWAYS_INLINE bool IF_NEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001046 return HandleIf(GetVReg(A()) != 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001047 }
1048
David Srbeckybd613ec2019-05-30 15:39:38 +01001049 ALWAYS_INLINE bool IF_LTZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001050 return HandleIf(GetVReg(A()) < 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001051 }
1052
David Srbeckybd613ec2019-05-30 15:39:38 +01001053 ALWAYS_INLINE bool IF_GEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001054 return HandleIf(GetVReg(A()) >= 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001055 }
1056
David Srbeckybd613ec2019-05-30 15:39:38 +01001057 ALWAYS_INLINE bool IF_GTZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001058 return HandleIf(GetVReg(A()) > 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001059 }
1060
David Srbeckybd613ec2019-05-30 15:39:38 +01001061 ALWAYS_INLINE bool IF_LEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001062 return HandleIf(GetVReg(A()) <= 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001063 }
1064
David Srbeckybd613ec2019-05-30 15:39:38 +01001065 ALWAYS_INLINE bool AGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001066 return HandleAGet<mirror::BooleanArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +01001067 }
1068
David Srbeckybd613ec2019-05-30 15:39:38 +01001069 ALWAYS_INLINE bool AGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001070 return HandleAGet<mirror::ByteArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +01001071 }
1072
David Srbeckybd613ec2019-05-30 15:39:38 +01001073 ALWAYS_INLINE bool AGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001074 return HandleAGet<mirror::CharArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +01001075 }
1076
David Srbeckybd613ec2019-05-30 15:39:38 +01001077 ALWAYS_INLINE bool AGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001078 return HandleAGet<mirror::ShortArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +01001079 }
1080
David Srbeckybd613ec2019-05-30 15:39:38 +01001081 ALWAYS_INLINE bool AGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001082 return HandleAGet<mirror::IntArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +01001083 }
1084
David Srbeckybd613ec2019-05-30 15:39:38 +01001085 ALWAYS_INLINE bool AGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001086 return HandleAGet<mirror::LongArray>(&InstructionHandler::SetVRegLong);
David Srbecky6da82472018-10-23 14:03:08 +01001087 }
1088
David Srbeckybd613ec2019-05-30 15:39:38 +01001089 ALWAYS_INLINE bool AGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001090 return HandleAGet<mirror::ObjectArray<mirror::Object>>(&InstructionHandler::SetVRegReference);
David Srbecky6da82472018-10-23 14:03:08 +01001091 }
1092
David Srbeckybd613ec2019-05-30 15:39:38 +01001093 ALWAYS_INLINE bool APUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001094 return HandleAPut<mirror::BooleanArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +01001095 }
1096
David Srbeckybd613ec2019-05-30 15:39:38 +01001097 ALWAYS_INLINE bool APUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001098 return HandleAPut<mirror::ByteArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +01001099 }
1100
David Srbeckybd613ec2019-05-30 15:39:38 +01001101 ALWAYS_INLINE bool APUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001102 return HandleAPut<mirror::CharArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +01001103 }
1104
David Srbeckybd613ec2019-05-30 15:39:38 +01001105 ALWAYS_INLINE bool APUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001106 return HandleAPut<mirror::ShortArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +01001107 }
1108
David Srbeckybd613ec2019-05-30 15:39:38 +01001109 ALWAYS_INLINE bool APUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001110 return HandleAPut<mirror::IntArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +01001111 }
1112
David Srbeckybd613ec2019-05-30 15:39:38 +01001113 ALWAYS_INLINE bool APUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001114 return HandleAPut<mirror::LongArray>(GetVRegLong(A()));
David Srbecky6da82472018-10-23 14:03:08 +01001115 }
1116
David Srbeckybd613ec2019-05-30 15:39:38 +01001117 ALWAYS_INLINE bool APUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001118 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001119 if (UNLIKELY(a == nullptr)) {
1120 ThrowNullPointerExceptionFromInterpreter();
1121 HANDLE_PENDING_EXCEPTION();
1122 }
David Srbecky6baf6442019-05-30 14:57:43 +01001123 int32_t index = GetVReg(C());
1124 ObjPtr<mirror::Object> val = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +01001125 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
1126 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
1127 array->SetWithoutChecks<transaction_active>(index, val);
1128 inst = inst->Next_2xx();
1129 } else {
1130 HANDLE_PENDING_EXCEPTION();
1131 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001132 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001133 }
1134
David Srbeckybd613ec2019-05-30 15:39:38 +01001135 ALWAYS_INLINE bool IGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001136 return HandleGet<InstancePrimitiveRead, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001137 }
1138
David Srbeckybd613ec2019-05-30 15:39:38 +01001139 ALWAYS_INLINE bool IGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001140 return HandleGet<InstancePrimitiveRead, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001141 }
1142
David Srbeckybd613ec2019-05-30 15:39:38 +01001143 ALWAYS_INLINE bool IGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001144 return HandleGet<InstancePrimitiveRead, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001145 }
1146
David Srbeckybd613ec2019-05-30 15:39:38 +01001147 ALWAYS_INLINE bool IGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001148 return HandleGet<InstancePrimitiveRead, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001149 }
1150
David Srbeckybd613ec2019-05-30 15:39:38 +01001151 ALWAYS_INLINE bool IGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001152 return HandleGet<InstancePrimitiveRead, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001153 }
1154
David Srbeckybd613ec2019-05-30 15:39:38 +01001155 ALWAYS_INLINE bool IGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001156 return HandleGet<InstancePrimitiveRead, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001157 }
1158
David Srbeckybd613ec2019-05-30 15:39:38 +01001159 ALWAYS_INLINE bool IGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001160 return HandleGet<InstanceObjectRead, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001161 }
1162
David Srbeckybd613ec2019-05-30 15:39:38 +01001163 ALWAYS_INLINE bool IGET_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001164 return HandleGetQuick<Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001165 }
1166
David Srbeckybd613ec2019-05-30 15:39:38 +01001167 ALWAYS_INLINE bool IGET_WIDE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001168 return HandleGetQuick<Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001169 }
1170
David Srbeckybd613ec2019-05-30 15:39:38 +01001171 ALWAYS_INLINE bool IGET_OBJECT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001172 return HandleGetQuick<Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001173 }
1174
David Srbeckybd613ec2019-05-30 15:39:38 +01001175 ALWAYS_INLINE bool IGET_BOOLEAN_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001176 return HandleGetQuick<Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001177 }
1178
David Srbeckybd613ec2019-05-30 15:39:38 +01001179 ALWAYS_INLINE bool IGET_BYTE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001180 return HandleGetQuick<Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001181 }
1182
David Srbeckybd613ec2019-05-30 15:39:38 +01001183 ALWAYS_INLINE bool IGET_CHAR_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001184 return HandleGetQuick<Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001185 }
1186
David Srbeckybd613ec2019-05-30 15:39:38 +01001187 ALWAYS_INLINE bool IGET_SHORT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001188 return HandleGetQuick<Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001189 }
1190
David Srbeckybd613ec2019-05-30 15:39:38 +01001191 ALWAYS_INLINE bool SGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001192 return HandleGet<StaticPrimitiveRead, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001193 }
1194
David Srbeckybd613ec2019-05-30 15:39:38 +01001195 ALWAYS_INLINE bool SGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001196 return HandleGet<StaticPrimitiveRead, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001197 }
1198
David Srbeckybd613ec2019-05-30 15:39:38 +01001199 ALWAYS_INLINE bool SGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001200 return HandleGet<StaticPrimitiveRead, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001201 }
1202
David Srbeckybd613ec2019-05-30 15:39:38 +01001203 ALWAYS_INLINE bool SGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001204 return HandleGet<StaticPrimitiveRead, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001205 }
1206
David Srbeckybd613ec2019-05-30 15:39:38 +01001207 ALWAYS_INLINE bool SGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001208 return HandleGet<StaticPrimitiveRead, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001209 }
1210
David Srbeckybd613ec2019-05-30 15:39:38 +01001211 ALWAYS_INLINE bool SGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001212 return HandleGet<StaticPrimitiveRead, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001213 }
1214
David Srbeckybd613ec2019-05-30 15:39:38 +01001215 ALWAYS_INLINE bool SGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001216 return HandleGet<StaticObjectRead, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001217 }
1218
David Srbeckybd613ec2019-05-30 15:39:38 +01001219 ALWAYS_INLINE bool IPUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001220 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001221 }
1222
David Srbeckybd613ec2019-05-30 15:39:38 +01001223 ALWAYS_INLINE bool IPUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001224 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001225 }
1226
David Srbeckybd613ec2019-05-30 15:39:38 +01001227 ALWAYS_INLINE bool IPUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001228 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001229 }
1230
David Srbeckybd613ec2019-05-30 15:39:38 +01001231 ALWAYS_INLINE bool IPUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001232 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001233 }
1234
David Srbeckybd613ec2019-05-30 15:39:38 +01001235 ALWAYS_INLINE bool IPUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001236 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001237 }
1238
David Srbeckybd613ec2019-05-30 15:39:38 +01001239 ALWAYS_INLINE bool IPUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001240 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001241 }
1242
David Srbeckybd613ec2019-05-30 15:39:38 +01001243 ALWAYS_INLINE bool IPUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001244 return HandlePut<InstanceObjectWrite, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001245 }
1246
David Srbeckybd613ec2019-05-30 15:39:38 +01001247 ALWAYS_INLINE bool IPUT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001248 return HandlePutQuick<Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001249 }
1250
David Srbeckybd613ec2019-05-30 15:39:38 +01001251 ALWAYS_INLINE bool IPUT_BOOLEAN_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001252 return HandlePutQuick<Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001253 }
1254
David Srbeckybd613ec2019-05-30 15:39:38 +01001255 ALWAYS_INLINE bool IPUT_BYTE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001256 return HandlePutQuick<Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001257 }
1258
David Srbeckybd613ec2019-05-30 15:39:38 +01001259 ALWAYS_INLINE bool IPUT_CHAR_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001260 return HandlePutQuick<Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001261 }
1262
David Srbeckybd613ec2019-05-30 15:39:38 +01001263 ALWAYS_INLINE bool IPUT_SHORT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001264 return HandlePutQuick<Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001265 }
1266
David Srbeckybd613ec2019-05-30 15:39:38 +01001267 ALWAYS_INLINE bool IPUT_WIDE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001268 return HandlePutQuick<Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001269 }
1270
David Srbeckybd613ec2019-05-30 15:39:38 +01001271 ALWAYS_INLINE bool IPUT_OBJECT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001272 return HandlePutQuick<Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001273 }
1274
David Srbeckybd613ec2019-05-30 15:39:38 +01001275 ALWAYS_INLINE bool SPUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001276 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001277 }
1278
David Srbeckybd613ec2019-05-30 15:39:38 +01001279 ALWAYS_INLINE bool SPUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001280 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001281 }
1282
David Srbeckybd613ec2019-05-30 15:39:38 +01001283 ALWAYS_INLINE bool SPUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001284 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001285 }
1286
David Srbeckybd613ec2019-05-30 15:39:38 +01001287 ALWAYS_INLINE bool SPUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001288 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001289 }
1290
David Srbeckybd613ec2019-05-30 15:39:38 +01001291 ALWAYS_INLINE bool SPUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001292 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001293 }
1294
David Srbeckybd613ec2019-05-30 15:39:38 +01001295 ALWAYS_INLINE bool SPUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001296 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001297 }
1298
David Srbeckybd613ec2019-05-30 15:39:38 +01001299 ALWAYS_INLINE bool SPUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001300 return HandlePut<StaticObjectWrite, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001301 }
1302
David Srbeckybd613ec2019-05-30 15:39:38 +01001303 ALWAYS_INLINE bool INVOKE_VIRTUAL() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001304 return HandleInvoke<kVirtual, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001305 }
1306
David Srbeckybd613ec2019-05-30 15:39:38 +01001307 ALWAYS_INLINE bool INVOKE_VIRTUAL_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001308 return HandleInvoke<kVirtual, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001309 }
1310
David Srbeckybd613ec2019-05-30 15:39:38 +01001311 ALWAYS_INLINE bool INVOKE_SUPER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001312 return HandleInvoke<kSuper, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001313 }
1314
David Srbeckybd613ec2019-05-30 15:39:38 +01001315 ALWAYS_INLINE bool INVOKE_SUPER_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001316 return HandleInvoke<kSuper, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001317 }
1318
David Srbeckybd613ec2019-05-30 15:39:38 +01001319 ALWAYS_INLINE bool INVOKE_DIRECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001320 return HandleInvoke<kDirect, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001321 }
1322
David Srbeckybd613ec2019-05-30 15:39:38 +01001323 ALWAYS_INLINE bool INVOKE_DIRECT_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001324 return HandleInvoke<kDirect, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001325 }
1326
David Srbeckybd613ec2019-05-30 15:39:38 +01001327 ALWAYS_INLINE bool INVOKE_INTERFACE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001328 return HandleInvoke<kInterface, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001329 }
1330
David Srbeckybd613ec2019-05-30 15:39:38 +01001331 ALWAYS_INLINE bool INVOKE_INTERFACE_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001332 return HandleInvoke<kInterface, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001333 }
1334
David Srbeckybd613ec2019-05-30 15:39:38 +01001335 ALWAYS_INLINE bool INVOKE_STATIC() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001336 return HandleInvoke<kStatic, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001337 }
1338
David Srbeckybd613ec2019-05-30 15:39:38 +01001339 ALWAYS_INLINE bool INVOKE_STATIC_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001340 return HandleInvoke<kStatic, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001341 }
1342
David Srbeckybd613ec2019-05-30 15:39:38 +01001343 ALWAYS_INLINE bool INVOKE_VIRTUAL_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001344 return HandleInvoke<kVirtual, /*is_range=*/ false, /*is_quick=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001345 }
1346
David Srbeckybd613ec2019-05-30 15:39:38 +01001347 ALWAYS_INLINE bool INVOKE_VIRTUAL_RANGE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001348 return HandleInvoke<kVirtual, /*is_range=*/ true, /*is_quick=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001349 }
1350
David Srbeckybd613ec2019-05-30 15:39:38 +01001351 ALWAYS_INLINE bool INVOKE_POLYMORPHIC() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001352 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1353 bool success = DoInvokePolymorphic</* is_range= */ false>(
1354 self, shadow_frame, inst, inst_data, ResultRegister());
1355 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001356 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001357 }
1358
David Srbeckybd613ec2019-05-30 15:39:38 +01001359 ALWAYS_INLINE bool INVOKE_POLYMORPHIC_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001360 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1361 bool success = DoInvokePolymorphic</* is_range= */ true>(
1362 self, shadow_frame, inst, inst_data, ResultRegister());
1363 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001364 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001365 }
1366
David Srbeckybd613ec2019-05-30 15:39:38 +01001367 ALWAYS_INLINE bool INVOKE_CUSTOM() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001368 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1369 bool success = DoInvokeCustom</* is_range= */ false>(
1370 self, shadow_frame, inst, inst_data, ResultRegister());
1371 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001372 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001373 }
1374
David Srbeckybd613ec2019-05-30 15:39:38 +01001375 ALWAYS_INLINE bool INVOKE_CUSTOM_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001376 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1377 bool success = DoInvokeCustom</* is_range= */ true>(
1378 self, shadow_frame, inst, inst_data, ResultRegister());
1379 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001380 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001381 }
1382
David Srbeckybd613ec2019-05-30 15:39:38 +01001383 ALWAYS_INLINE bool NEG_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001384 SetVReg(A(), -GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001385 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001386 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001387 }
1388
David Srbeckybd613ec2019-05-30 15:39:38 +01001389 ALWAYS_INLINE bool NOT_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001390 SetVReg(A(), ~GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001391 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001392 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001393 }
1394
David Srbeckybd613ec2019-05-30 15:39:38 +01001395 ALWAYS_INLINE bool NEG_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001396 SetVRegLong(A(), -GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001397 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001398 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001399 }
1400
David Srbeckybd613ec2019-05-30 15:39:38 +01001401 ALWAYS_INLINE bool NOT_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001402 SetVRegLong(A(), ~GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001403 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001404 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001405 }
1406
David Srbeckybd613ec2019-05-30 15:39:38 +01001407 ALWAYS_INLINE bool NEG_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001408 SetVRegFloat(A(), -GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001409 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001410 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001411 }
1412
David Srbeckybd613ec2019-05-30 15:39:38 +01001413 ALWAYS_INLINE bool NEG_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001414 SetVRegDouble(A(), -GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001415 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001416 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001417 }
1418
David Srbeckybd613ec2019-05-30 15:39:38 +01001419 ALWAYS_INLINE bool INT_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001420 SetVRegLong(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001421 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001422 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001423 }
1424
David Srbeckybd613ec2019-05-30 15:39:38 +01001425 ALWAYS_INLINE bool INT_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001426 SetVRegFloat(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001427 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001428 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001429 }
1430
David Srbeckybd613ec2019-05-30 15:39:38 +01001431 ALWAYS_INLINE bool INT_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001432 SetVRegDouble(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001433 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001434 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001435 }
1436
David Srbeckybd613ec2019-05-30 15:39:38 +01001437 ALWAYS_INLINE bool LONG_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001438 SetVReg(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001439 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001440 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001441 }
1442
David Srbeckybd613ec2019-05-30 15:39:38 +01001443 ALWAYS_INLINE bool LONG_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001444 SetVRegFloat(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001445 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001446 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001447 }
1448
David Srbeckybd613ec2019-05-30 15:39:38 +01001449 ALWAYS_INLINE bool LONG_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001450 SetVRegDouble(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001451 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001452 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001453 }
1454
David Srbeckybd613ec2019-05-30 15:39:38 +01001455 ALWAYS_INLINE bool FLOAT_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001456 float val = GetVRegFloat(B());
David Srbecky6da82472018-10-23 14:03:08 +01001457 int32_t result = art_float_to_integral<int32_t, float>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001458 SetVReg(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001459 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001460 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001461 }
1462
David Srbeckybd613ec2019-05-30 15:39:38 +01001463 ALWAYS_INLINE bool FLOAT_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001464 float val = GetVRegFloat(B());
David Srbecky6da82472018-10-23 14:03:08 +01001465 int64_t result = art_float_to_integral<int64_t, float>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001466 SetVRegLong(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001467 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001468 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001469 }
1470
David Srbeckybd613ec2019-05-30 15:39:38 +01001471 ALWAYS_INLINE bool FLOAT_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001472 SetVRegDouble(A(), GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001473 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001474 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001475 }
1476
David Srbeckybd613ec2019-05-30 15:39:38 +01001477 ALWAYS_INLINE bool DOUBLE_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001478 double val = GetVRegDouble(B());
David Srbecky6da82472018-10-23 14:03:08 +01001479 int32_t result = art_float_to_integral<int32_t, double>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001480 SetVReg(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001481 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001482 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001483 }
1484
David Srbeckybd613ec2019-05-30 15:39:38 +01001485 ALWAYS_INLINE bool DOUBLE_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001486 double val = GetVRegDouble(B());
David Srbecky6da82472018-10-23 14:03:08 +01001487 int64_t result = art_float_to_integral<int64_t, double>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001488 SetVRegLong(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001489 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001490 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001491 }
1492
David Srbeckybd613ec2019-05-30 15:39:38 +01001493 ALWAYS_INLINE bool DOUBLE_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001494 SetVRegFloat(A(), GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001495 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001496 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001497 }
1498
David Srbeckybd613ec2019-05-30 15:39:38 +01001499 ALWAYS_INLINE bool INT_TO_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001500 SetVReg(A(), static_cast<int8_t>(GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001501 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001502 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001503 }
1504
David Srbeckybd613ec2019-05-30 15:39:38 +01001505 ALWAYS_INLINE bool INT_TO_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001506 SetVReg(A(), static_cast<uint16_t>(GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001507 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001508 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001509 }
1510
David Srbeckybd613ec2019-05-30 15:39:38 +01001511 ALWAYS_INLINE bool INT_TO_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001512 SetVReg(A(), static_cast<int16_t>(GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001513 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001514 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001515 }
1516
David Srbeckybd613ec2019-05-30 15:39:38 +01001517 ALWAYS_INLINE bool ADD_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001518 SetVReg(A(), SafeAdd(GetVReg(B()), GetVReg(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001519 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001520 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001521 }
1522
David Srbeckybd613ec2019-05-30 15:39:38 +01001523 ALWAYS_INLINE bool SUB_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001524 SetVReg(A(), SafeSub(GetVReg(B()), GetVReg(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001525 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001526 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001527 }
1528
David Srbeckybd613ec2019-05-30 15:39:38 +01001529 ALWAYS_INLINE bool MUL_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001530 SetVReg(A(), SafeMul(GetVReg(B()), GetVReg(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001531 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001532 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001533 }
1534
David Srbeckybd613ec2019-05-30 15:39:38 +01001535 ALWAYS_INLINE bool DIV_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001536 bool success = DoIntDivide(shadow_frame, A(), GetVReg(B()), GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001537 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001538 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001539 }
1540
David Srbeckybd613ec2019-05-30 15:39:38 +01001541 ALWAYS_INLINE bool REM_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001542 bool success = DoIntRemainder(shadow_frame, A(), GetVReg(B()), GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001543 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001544 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001545 }
1546
David Srbeckybd613ec2019-05-30 15:39:38 +01001547 ALWAYS_INLINE bool SHL_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001548 SetVReg(A(), GetVReg(B()) << (GetVReg(C()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001549 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001550 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001551 }
1552
David Srbeckybd613ec2019-05-30 15:39:38 +01001553 ALWAYS_INLINE bool SHR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001554 SetVReg(A(), GetVReg(B()) >> (GetVReg(C()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001555 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001556 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001557 }
1558
David Srbeckybd613ec2019-05-30 15:39:38 +01001559 ALWAYS_INLINE bool USHR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001560 SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (GetVReg(C()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001561 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001562 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001563 }
1564
David Srbeckybd613ec2019-05-30 15:39:38 +01001565 ALWAYS_INLINE bool AND_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001566 SetVReg(A(), GetVReg(B()) & GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001567 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001568 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001569 }
1570
David Srbeckybd613ec2019-05-30 15:39:38 +01001571 ALWAYS_INLINE bool OR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001572 SetVReg(A(), GetVReg(B()) | GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001573 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001574 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001575 }
1576
David Srbeckybd613ec2019-05-30 15:39:38 +01001577 ALWAYS_INLINE bool XOR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001578 SetVReg(A(), GetVReg(B()) ^ GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001579 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001580 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001581 }
1582
David Srbeckybd613ec2019-05-30 15:39:38 +01001583 ALWAYS_INLINE bool ADD_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001584 SetVRegLong(A(), SafeAdd(GetVRegLong(B()), GetVRegLong(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001585 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001586 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001587 }
1588
David Srbeckybd613ec2019-05-30 15:39:38 +01001589 ALWAYS_INLINE bool SUB_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001590 SetVRegLong(A(), SafeSub(GetVRegLong(B()), GetVRegLong(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001591 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001592 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001593 }
1594
David Srbeckybd613ec2019-05-30 15:39:38 +01001595 ALWAYS_INLINE bool MUL_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001596 SetVRegLong(A(), SafeMul(GetVRegLong(B()), GetVRegLong(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001597 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001598 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001599 }
1600
David Srbeckybd613ec2019-05-30 15:39:38 +01001601 ALWAYS_INLINE bool DIV_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001602 DoLongDivide(shadow_frame, A(), GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001603 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001604 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001605 }
1606
David Srbeckybd613ec2019-05-30 15:39:38 +01001607 ALWAYS_INLINE bool REM_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001608 DoLongRemainder(shadow_frame, A(), GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001609 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001610 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001611 }
1612
David Srbeckybd613ec2019-05-30 15:39:38 +01001613 ALWAYS_INLINE bool AND_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001614 SetVRegLong(A(), GetVRegLong(B()) & GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001615 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001616 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001617 }
1618
David Srbeckybd613ec2019-05-30 15:39:38 +01001619 ALWAYS_INLINE bool OR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001620 SetVRegLong(A(), GetVRegLong(B()) | GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001621 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001622 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001623 }
1624
David Srbeckybd613ec2019-05-30 15:39:38 +01001625 ALWAYS_INLINE bool XOR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001626 SetVRegLong(A(), GetVRegLong(B()) ^ GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001627 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001628 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001629 }
1630
David Srbeckybd613ec2019-05-30 15:39:38 +01001631 ALWAYS_INLINE bool SHL_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001632 SetVRegLong(A(), GetVRegLong(B()) << (GetVReg(C()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001633 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001634 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001635 }
1636
David Srbeckybd613ec2019-05-30 15:39:38 +01001637 ALWAYS_INLINE bool SHR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001638 SetVRegLong(A(), GetVRegLong(B()) >> (GetVReg(C()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001639 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001640 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001641 }
1642
David Srbeckybd613ec2019-05-30 15:39:38 +01001643 ALWAYS_INLINE bool USHR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001644 SetVRegLong(A(), static_cast<uint64_t>(GetVRegLong(B())) >> (GetVReg(C()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001645 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001646 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001647 }
1648
David Srbeckybd613ec2019-05-30 15:39:38 +01001649 ALWAYS_INLINE bool ADD_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001650 SetVRegFloat(A(), GetVRegFloat(B()) + GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001651 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001652 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001653 }
1654
David Srbeckybd613ec2019-05-30 15:39:38 +01001655 ALWAYS_INLINE bool SUB_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001656 SetVRegFloat(A(), GetVRegFloat(B()) - GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001657 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001658 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001659 }
1660
David Srbeckybd613ec2019-05-30 15:39:38 +01001661 ALWAYS_INLINE bool MUL_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001662 SetVRegFloat(A(), GetVRegFloat(B()) * GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001663 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001664 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001665 }
1666
David Srbeckybd613ec2019-05-30 15:39:38 +01001667 ALWAYS_INLINE bool DIV_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001668 SetVRegFloat(A(), GetVRegFloat(B()) / GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001669 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001670 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001671 }
1672
David Srbeckybd613ec2019-05-30 15:39:38 +01001673 ALWAYS_INLINE bool REM_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001674 SetVRegFloat(A(), fmodf(GetVRegFloat(B()), GetVRegFloat(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001675 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001676 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001677 }
1678
David Srbeckybd613ec2019-05-30 15:39:38 +01001679 ALWAYS_INLINE bool ADD_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001680 SetVRegDouble(A(), GetVRegDouble(B()) + GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001681 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001682 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001683 }
1684
David Srbeckybd613ec2019-05-30 15:39:38 +01001685 ALWAYS_INLINE bool SUB_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001686 SetVRegDouble(A(), GetVRegDouble(B()) - GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001687 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001688 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001689 }
1690
David Srbeckybd613ec2019-05-30 15:39:38 +01001691 ALWAYS_INLINE bool MUL_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001692 SetVRegDouble(A(), GetVRegDouble(B()) * GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001693 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001694 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001695 }
1696
David Srbeckybd613ec2019-05-30 15:39:38 +01001697 ALWAYS_INLINE bool DIV_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001698 SetVRegDouble(A(), GetVRegDouble(B()) / GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001699 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001700 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001701 }
1702
David Srbeckybd613ec2019-05-30 15:39:38 +01001703 ALWAYS_INLINE bool REM_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001704 SetVRegDouble(A(), fmod(GetVRegDouble(B()), GetVRegDouble(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001705 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001706 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001707 }
1708
David Srbeckybd613ec2019-05-30 15:39:38 +01001709 ALWAYS_INLINE bool ADD_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001710 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001711 SetVReg(vregA, SafeAdd(GetVReg(vregA), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001712 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001713 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001714 }
1715
David Srbeckybd613ec2019-05-30 15:39:38 +01001716 ALWAYS_INLINE bool SUB_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001717 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001718 SetVReg(vregA, SafeSub(GetVReg(vregA), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001719 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001720 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001721 }
1722
David Srbeckybd613ec2019-05-30 15:39:38 +01001723 ALWAYS_INLINE bool MUL_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001724 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001725 SetVReg(vregA, SafeMul(GetVReg(vregA), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001726 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001727 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001728 }
1729
David Srbeckybd613ec2019-05-30 15:39:38 +01001730 ALWAYS_INLINE bool DIV_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001731 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001732 bool success = DoIntDivide(shadow_frame, vregA, GetVReg(vregA), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001733 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001734 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001735 }
1736
David Srbeckybd613ec2019-05-30 15:39:38 +01001737 ALWAYS_INLINE bool REM_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001738 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001739 bool success = DoIntRemainder(shadow_frame, vregA, GetVReg(vregA), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001740 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001741 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001742 }
1743
David Srbeckybd613ec2019-05-30 15:39:38 +01001744 ALWAYS_INLINE bool SHL_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001745 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001746 SetVReg(vregA, GetVReg(vregA) << (GetVReg(B()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001747 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001748 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001749 }
1750
David Srbeckybd613ec2019-05-30 15:39:38 +01001751 ALWAYS_INLINE bool SHR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001752 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001753 SetVReg(vregA, GetVReg(vregA) >> (GetVReg(B()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001754 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001755 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001756 }
1757
David Srbeckybd613ec2019-05-30 15:39:38 +01001758 ALWAYS_INLINE bool USHR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001759 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001760 SetVReg(vregA, static_cast<uint32_t>(GetVReg(vregA)) >> (GetVReg(B()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001761 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001762 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001763 }
1764
David Srbeckybd613ec2019-05-30 15:39:38 +01001765 ALWAYS_INLINE bool AND_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001766 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001767 SetVReg(vregA, GetVReg(vregA) & GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001768 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001769 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001770 }
1771
David Srbeckybd613ec2019-05-30 15:39:38 +01001772 ALWAYS_INLINE bool OR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001773 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001774 SetVReg(vregA, GetVReg(vregA) | GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001775 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001776 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001777 }
1778
David Srbeckybd613ec2019-05-30 15:39:38 +01001779 ALWAYS_INLINE bool XOR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001780 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001781 SetVReg(vregA, GetVReg(vregA) ^ GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001782 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001783 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001784 }
1785
David Srbeckybd613ec2019-05-30 15:39:38 +01001786 ALWAYS_INLINE bool ADD_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001787 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001788 SetVRegLong(vregA, SafeAdd(GetVRegLong(vregA), GetVRegLong(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001789 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001790 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001791 }
1792
David Srbeckybd613ec2019-05-30 15:39:38 +01001793 ALWAYS_INLINE bool SUB_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001794 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001795 SetVRegLong(vregA, SafeSub(GetVRegLong(vregA), GetVRegLong(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001796 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001797 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001798 }
1799
David Srbeckybd613ec2019-05-30 15:39:38 +01001800 ALWAYS_INLINE bool MUL_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001801 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001802 SetVRegLong(vregA, SafeMul(GetVRegLong(vregA), GetVRegLong(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001803 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001804 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001805 }
1806
David Srbeckybd613ec2019-05-30 15:39:38 +01001807 ALWAYS_INLINE bool DIV_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001808 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001809 DoLongDivide(shadow_frame, vregA, GetVRegLong(vregA), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001810 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001811 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001812 }
1813
David Srbeckybd613ec2019-05-30 15:39:38 +01001814 ALWAYS_INLINE bool REM_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001815 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001816 DoLongRemainder(shadow_frame, vregA, GetVRegLong(vregA), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001817 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001818 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001819 }
1820
David Srbeckybd613ec2019-05-30 15:39:38 +01001821 ALWAYS_INLINE bool AND_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001822 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001823 SetVRegLong(vregA, GetVRegLong(vregA) & GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001824 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001825 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001826 }
1827
David Srbeckybd613ec2019-05-30 15:39:38 +01001828 ALWAYS_INLINE bool OR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001829 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001830 SetVRegLong(vregA, GetVRegLong(vregA) | GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001831 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001832 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001833 }
1834
David Srbeckybd613ec2019-05-30 15:39:38 +01001835 ALWAYS_INLINE bool XOR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001836 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001837 SetVRegLong(vregA, GetVRegLong(vregA) ^ GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001838 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001839 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001840 }
1841
David Srbeckybd613ec2019-05-30 15:39:38 +01001842 ALWAYS_INLINE bool SHL_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001843 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001844 SetVRegLong(vregA, GetVRegLong(vregA) << (GetVReg(B()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001845 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001846 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001847 }
1848
David Srbeckybd613ec2019-05-30 15:39:38 +01001849 ALWAYS_INLINE bool SHR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001850 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001851 SetVRegLong(vregA, GetVRegLong(vregA) >> (GetVReg(B()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001852 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001853 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001854 }
1855
David Srbeckybd613ec2019-05-30 15:39:38 +01001856 ALWAYS_INLINE bool USHR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001857 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001858 SetVRegLong(vregA, static_cast<uint64_t>(GetVRegLong(vregA)) >> (GetVReg(B()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001859 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001860 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001861 }
1862
David Srbeckybd613ec2019-05-30 15:39:38 +01001863 ALWAYS_INLINE bool ADD_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001864 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001865 SetVRegFloat(vregA, GetVRegFloat(vregA) + GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001866 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001867 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001868 }
1869
David Srbeckybd613ec2019-05-30 15:39:38 +01001870 ALWAYS_INLINE bool SUB_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001871 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001872 SetVRegFloat(vregA, GetVRegFloat(vregA) - GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001873 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001874 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001875 }
1876
David Srbeckybd613ec2019-05-30 15:39:38 +01001877 ALWAYS_INLINE bool MUL_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001878 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001879 SetVRegFloat(vregA, GetVRegFloat(vregA) * GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001880 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001881 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001882 }
1883
David Srbeckybd613ec2019-05-30 15:39:38 +01001884 ALWAYS_INLINE bool DIV_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001885 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001886 SetVRegFloat(vregA, GetVRegFloat(vregA) / GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001887 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001888 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001889 }
1890
David Srbeckybd613ec2019-05-30 15:39:38 +01001891 ALWAYS_INLINE bool REM_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001892 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001893 SetVRegFloat(vregA, fmodf(GetVRegFloat(vregA), GetVRegFloat(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001894 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001895 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001896 }
1897
David Srbeckybd613ec2019-05-30 15:39:38 +01001898 ALWAYS_INLINE bool ADD_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001899 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001900 SetVRegDouble(vregA, GetVRegDouble(vregA) + GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001901 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001902 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001903 }
1904
David Srbeckybd613ec2019-05-30 15:39:38 +01001905 ALWAYS_INLINE bool SUB_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001906 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001907 SetVRegDouble(vregA, GetVRegDouble(vregA) - GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001908 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001909 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001910 }
1911
David Srbeckybd613ec2019-05-30 15:39:38 +01001912 ALWAYS_INLINE bool MUL_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001913 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001914 SetVRegDouble(vregA, GetVRegDouble(vregA) * GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001915 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001916 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001917 }
1918
David Srbeckybd613ec2019-05-30 15:39:38 +01001919 ALWAYS_INLINE bool DIV_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001920 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001921 SetVRegDouble(vregA, GetVRegDouble(vregA) / GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001922 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001923 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001924 }
1925
David Srbeckybd613ec2019-05-30 15:39:38 +01001926 ALWAYS_INLINE bool REM_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001927 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001928 SetVRegDouble(vregA, fmod(GetVRegDouble(vregA), GetVRegDouble(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001929 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001930 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001931 }
1932
David Srbeckybd613ec2019-05-30 15:39:38 +01001933 ALWAYS_INLINE bool ADD_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001934 SetVReg(A(), SafeAdd(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01001935 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001936 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001937 }
1938
David Srbeckybd613ec2019-05-30 15:39:38 +01001939 ALWAYS_INLINE bool RSUB_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001940 SetVReg(A(), SafeSub(C(), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001941 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001942 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001943 }
1944
David Srbeckybd613ec2019-05-30 15:39:38 +01001945 ALWAYS_INLINE bool MUL_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001946 SetVReg(A(), SafeMul(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01001947 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001948 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001949 }
1950
David Srbeckybd613ec2019-05-30 15:39:38 +01001951 ALWAYS_INLINE bool DIV_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001952 bool success = DoIntDivide(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001953 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001954 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001955 }
1956
David Srbeckybd613ec2019-05-30 15:39:38 +01001957 ALWAYS_INLINE bool REM_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001958 bool success = DoIntRemainder(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001959 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001960 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001961 }
1962
David Srbeckybd613ec2019-05-30 15:39:38 +01001963 ALWAYS_INLINE bool AND_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001964 SetVReg(A(), GetVReg(B()) & C());
David Srbecky6da82472018-10-23 14:03:08 +01001965 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001966 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001967 }
1968
David Srbeckybd613ec2019-05-30 15:39:38 +01001969 ALWAYS_INLINE bool OR_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001970 SetVReg(A(), GetVReg(B()) | C());
David Srbecky6da82472018-10-23 14:03:08 +01001971 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001972 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001973 }
1974
David Srbeckybd613ec2019-05-30 15:39:38 +01001975 ALWAYS_INLINE bool XOR_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001976 SetVReg(A(), GetVReg(B()) ^ C());
David Srbecky6da82472018-10-23 14:03:08 +01001977 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001978 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001979 }
1980
David Srbeckybd613ec2019-05-30 15:39:38 +01001981 ALWAYS_INLINE bool ADD_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001982 SetVReg(A(), SafeAdd(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01001983 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001984 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001985 }
1986
David Srbeckybd613ec2019-05-30 15:39:38 +01001987 ALWAYS_INLINE bool RSUB_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001988 SetVReg(A(), SafeSub(C(), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001989 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001990 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001991 }
1992
David Srbeckybd613ec2019-05-30 15:39:38 +01001993 ALWAYS_INLINE bool MUL_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001994 SetVReg(A(), SafeMul(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01001995 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001996 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001997 }
1998
David Srbeckybd613ec2019-05-30 15:39:38 +01001999 ALWAYS_INLINE bool DIV_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002000 bool success = DoIntDivide(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01002001 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002002 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002003 }
2004
David Srbeckybd613ec2019-05-30 15:39:38 +01002005 ALWAYS_INLINE bool REM_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002006 bool success = DoIntRemainder(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01002007 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002008 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002009 }
2010
David Srbeckybd613ec2019-05-30 15:39:38 +01002011 ALWAYS_INLINE bool AND_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002012 SetVReg(A(), GetVReg(B()) & C());
David Srbecky6da82472018-10-23 14:03:08 +01002013 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002014 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002015 }
2016
David Srbeckybd613ec2019-05-30 15:39:38 +01002017 ALWAYS_INLINE bool OR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002018 SetVReg(A(), GetVReg(B()) | C());
David Srbecky6da82472018-10-23 14:03:08 +01002019 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002020 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002021 }
2022
David Srbeckybd613ec2019-05-30 15:39:38 +01002023 ALWAYS_INLINE bool XOR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002024 SetVReg(A(), GetVReg(B()) ^ C());
David Srbecky6da82472018-10-23 14:03:08 +01002025 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002026 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002027 }
2028
David Srbeckybd613ec2019-05-30 15:39:38 +01002029 ALWAYS_INLINE bool SHL_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002030 SetVReg(A(), GetVReg(B()) << (C() & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002031 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002032 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002033 }
2034
David Srbeckybd613ec2019-05-30 15:39:38 +01002035 ALWAYS_INLINE bool SHR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002036 SetVReg(A(), GetVReg(B()) >> (C() & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002037 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002038 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002039 }
2040
David Srbeckybd613ec2019-05-30 15:39:38 +01002041 ALWAYS_INLINE bool USHR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002042 SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (C() & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002043 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002044 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002045 }
2046
David Srbeckybd613ec2019-05-30 15:39:38 +01002047 ALWAYS_INLINE bool UNUSED_3E() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002048 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002049 }
2050
David Srbeckybd613ec2019-05-30 15:39:38 +01002051 ALWAYS_INLINE bool UNUSED_3F() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002052 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002053 }
2054
David Srbeckybd613ec2019-05-30 15:39:38 +01002055 ALWAYS_INLINE bool UNUSED_40() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002056 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002057 }
2058
David Srbeckybd613ec2019-05-30 15:39:38 +01002059 ALWAYS_INLINE bool UNUSED_41() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002060 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002061 }
2062
David Srbeckybd613ec2019-05-30 15:39:38 +01002063 ALWAYS_INLINE bool UNUSED_42() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002064 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002065 }
2066
David Srbeckybd613ec2019-05-30 15:39:38 +01002067 ALWAYS_INLINE bool UNUSED_43() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002068 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002069 }
2070
David Srbeckybd613ec2019-05-30 15:39:38 +01002071 ALWAYS_INLINE bool UNUSED_79() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002072 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002073 }
2074
David Srbeckybd613ec2019-05-30 15:39:38 +01002075 ALWAYS_INLINE bool UNUSED_7A() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002076 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002077 }
2078
David Srbeckybd613ec2019-05-30 15:39:38 +01002079 ALWAYS_INLINE bool UNUSED_F3() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002080 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002081 }
2082
David Srbeckybd613ec2019-05-30 15:39:38 +01002083 ALWAYS_INLINE bool UNUSED_F4() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002084 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002085 }
2086
David Srbeckybd613ec2019-05-30 15:39:38 +01002087 ALWAYS_INLINE bool UNUSED_F5() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002088 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002089 }
2090
David Srbeckybd613ec2019-05-30 15:39:38 +01002091 ALWAYS_INLINE bool UNUSED_F6() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002092 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002093 }
2094
David Srbeckybd613ec2019-05-30 15:39:38 +01002095 ALWAYS_INLINE bool UNUSED_F7() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002096 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002097 }
2098
David Srbeckybd613ec2019-05-30 15:39:38 +01002099 ALWAYS_INLINE bool UNUSED_F8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002100 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002101 }
2102
David Srbeckybd613ec2019-05-30 15:39:38 +01002103 ALWAYS_INLINE bool UNUSED_F9() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002104 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002105 }
2106
2107 ALWAYS_INLINE InstructionHandler(SwitchImplContext* ctx,
2108 const instrumentation::Instrumentation* instrumentation,
2109 Thread* self,
2110 ShadowFrame& shadow_frame,
2111 uint16_t dex_pc,
2112 const Instruction*& inst,
2113 uint16_t inst_data,
David Srbecky8867f3b2019-05-31 20:01:46 +01002114 const Instruction*& next,
David Srbecky6da82472018-10-23 14:03:08 +01002115 bool& exit_interpreter_loop)
2116 : ctx(ctx),
2117 instrumentation(instrumentation),
2118 self(self),
2119 shadow_frame(shadow_frame),
2120 dex_pc(dex_pc),
2121 inst(inst),
2122 inst_data(inst_data),
David Srbecky8867f3b2019-05-31 20:01:46 +01002123 next(next),
David Srbecky6da82472018-10-23 14:03:08 +01002124 exit_interpreter_loop(exit_interpreter_loop) {
2125 }
2126
2127 private:
2128 static constexpr bool do_assignability_check = do_access_check;
Alex Lightb7c640d2019-03-20 15:52:13 -07002129 static constexpr MonitorState kMonitorState =
2130 do_assignability_check ? MonitorState::kCountingMonitors : MonitorState::kNormalMonitors;
David Srbecky6da82472018-10-23 14:03:08 +01002131
2132 const CodeItemDataAccessor& Accessor() { return ctx->accessor; }
2133 const uint16_t* Insns() { return ctx->accessor.Insns(); }
2134 JValue* ResultRegister() { return &ctx->result_register; }
2135
David Srbecky436f6c12019-05-22 13:28:42 +01002136 ALWAYS_INLINE int32_t A() { return inst->VRegA(kFormat, inst_data); }
2137 ALWAYS_INLINE int32_t B() { return inst->VRegB(kFormat, inst_data); }
2138 ALWAYS_INLINE int32_t C() { return inst->VRegC(kFormat); }
2139
David Srbecky6baf6442019-05-30 14:57:43 +01002140 int32_t GetVReg(size_t i) const { return shadow_frame.GetVReg(i); }
2141 int64_t GetVRegLong(size_t i) const { return shadow_frame.GetVRegLong(i); }
2142 float GetVRegFloat(size_t i) const { return shadow_frame.GetVRegFloat(i); }
2143 double GetVRegDouble(size_t i) const { return shadow_frame.GetVRegDouble(i); }
2144 ObjPtr<mirror::Object> GetVRegReference(size_t i) const REQUIRES_SHARED(Locks::mutator_lock_) {
2145 return shadow_frame.GetVRegReference(i);
2146 }
2147
2148 void SetVReg(size_t i, int32_t val) { shadow_frame.SetVReg(i, val); }
2149 void SetVRegLong(size_t i, int64_t val) { shadow_frame.SetVRegLong(i, val); }
2150 void SetVRegFloat(size_t i, float val) { shadow_frame.SetVRegFloat(i, val); }
2151 void SetVRegDouble(size_t i, double val) { shadow_frame.SetVRegDouble(i, val); }
2152 void SetVRegReference(size_t i, ObjPtr<mirror::Object> val)
2153 REQUIRES_SHARED(Locks::mutator_lock_) {
2154 shadow_frame.SetVRegReference(i, val);
2155 }
2156
David Srbecky8867f3b2019-05-31 20:01:46 +01002157 // Set the next instruction to be executed. It is the 'fall-through' instruction by default.
2158 ALWAYS_INLINE void SetNextInstruction(const Instruction* next_inst) {
2159 DCHECK_LT(next_inst->GetDexPc(Insns()), Accessor().InsnsSizeInCodeUnits());
2160 next = next_inst;
2161 }
2162
David Srbecky6da82472018-10-23 14:03:08 +01002163 SwitchImplContext* const ctx;
2164 const instrumentation::Instrumentation* const instrumentation;
2165 Thread* const self;
2166 ShadowFrame& shadow_frame;
2167 uint32_t const dex_pc;
2168 const Instruction*& inst;
2169 uint16_t const inst_data;
David Srbecky8867f3b2019-05-31 20:01:46 +01002170 const Instruction*& next;
2171
David Srbecky6da82472018-10-23 14:03:08 +01002172 bool& exit_interpreter_loop;
2173};
2174
David Srbecky6da82472018-10-23 14:03:08 +01002175#undef BRANCH_INSTRUMENTATION
David Srbecky6da82472018-10-23 14:03:08 +01002176#undef POSSIBLY_HANDLE_PENDING_EXCEPTION
2177#undef POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE
2178#undef POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC
David Srbecky6da82472018-10-23 14:03:08 +01002179#undef HANDLE_PENDING_EXCEPTION
David Srbecky6da82472018-10-23 14:03:08 +01002180
Alex Light6f22e062018-10-05 15:05:12 -07002181// TODO On ASAN builds this function gets a huge stack frame. Since normally we run in the mterp
2182// this shouldn't cause any problems for stack overflow detection. Remove this once b/117341496 is
2183// fixed.
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002184template<bool do_access_check, bool transaction_active>
Alex Light6f22e062018-10-05 15:05:12 -07002185ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
David Srbecky946bb092018-03-09 17:23:01 +00002186 Thread* self = ctx->self;
2187 const CodeItemDataAccessor& accessor = ctx->accessor;
2188 ShadowFrame& shadow_frame = ctx->shadow_frame;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002189 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
2190 LOG(FATAL) << "Invalid shadow frame for interpreter use";
David Srbecky946bb092018-03-09 17:23:01 +00002191 ctx->result = JValue();
2192 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002193 }
2194 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002195
2196 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002197 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002198 const uint16_t* const insns = accessor.Insns();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002199 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002200 uint16_t inst_data;
Igor Murashkin6918bf12015-09-27 19:19:06 -07002201
Alex Light0aa7a5a2018-10-10 15:58:14 +00002202 DCHECK(!shadow_frame.GetForceRetryInstruction())
2203 << "Entered interpreter from invoke without retry instruction being handled!";
2204
David Srbecky6da82472018-10-23 14:03:08 +01002205 bool const interpret_one_instruction = ctx->interpret_one_instruction;
2206 while (true) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002207 dex_pc = inst->GetDexPc(insns);
2208 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -08002209 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002210 inst_data = inst->Fetch16(0);
David Srbeckya4a96af2018-10-31 16:34:58 +00002211 {
David Srbecky8867f3b2019-05-31 20:01:46 +01002212 const Instruction* next = nullptr;
David Srbeckya4a96af2018-10-31 16:34:58 +00002213 bool exit_loop = false;
David Srbecky436f6c12019-05-22 13:28:42 +01002214 InstructionHandler<do_access_check, transaction_active, Instruction::kInvalidFormat> handler(
David Srbecky8867f3b2019-05-31 20:01:46 +01002215 ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit_loop);
David Srbeckya4a96af2018-10-31 16:34:58 +00002216 if (!handler.Preamble()) {
2217 if (UNLIKELY(exit_loop)) {
2218 return;
2219 }
2220 if (UNLIKELY(interpret_one_instruction)) {
2221 break;
2222 }
2223 continue;
2224 }
2225 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002226 switch (inst->Opcode(inst_data)) {
David Srbecky8867f3b2019-05-31 20:01:46 +01002227#define OPCODE_CASE(OPCODE, OPCODE_NAME, NAME, FORMAT, i, a, e, v) \
David Srbecky6da82472018-10-23 14:03:08 +01002228 case OPCODE: { \
David Srbecky8867f3b2019-05-31 20:01:46 +01002229 size_t inst_size = Instruction::SizeInCodeUnits(Instruction::FORMAT); \
2230 const Instruction* next = inst->RelativeAt(inst_size); \
David Srbecky6da82472018-10-23 14:03:08 +01002231 bool exit_loop = false; \
David Srbecky436f6c12019-05-22 13:28:42 +01002232 InstructionHandler<do_access_check, transaction_active, Instruction::FORMAT> handler( \
David Srbecky8867f3b2019-05-31 20:01:46 +01002233 ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit_loop); \
David Srbeckya4a96af2018-10-31 16:34:58 +00002234 handler.OPCODE_NAME(); \
David Srbecky6da82472018-10-23 14:03:08 +01002235 if (UNLIKELY(exit_loop)) { \
2236 return; \
2237 } \
David Srbecky8867f3b2019-05-31 20:01:46 +01002238 DCHECK_EQ(next, inst) << NAME; \
David Srbecky6da82472018-10-23 14:03:08 +01002239 break; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002240 }
David Srbecky6da82472018-10-23 14:03:08 +01002241DEX_INSTRUCTION_LIST(OPCODE_CASE)
2242#undef OPCODE_CASE
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002243 }
David Srbecky6da82472018-10-23 14:03:08 +01002244 if (UNLIKELY(interpret_one_instruction)) {
David Srbeckya4a96af2018-10-31 16:34:58 +00002245 break;
David Srbecky6da82472018-10-23 14:03:08 +01002246 }
2247 }
David Srbeckya4a96af2018-10-31 16:34:58 +00002248 // Record where we stopped.
2249 shadow_frame.SetDexPC(inst->GetDexPc(insns));
2250 ctx->result = ctx->result_register;
2251 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002252} // NOLINT(readability/fn_size)
2253
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002254} // namespace interpreter
2255} // namespace art
David Srbecky2ee09ff2018-10-24 13:24:22 +01002256
2257#endif // ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_