blob: 00d8b9d0ff23a7efb0915482fe40d5c25f73553f [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 Light0aa7a5a2018-10-10 15:58:14 +000036#include "nth_caller_visitor.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070037#include "safe_math.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010038#include "shadow_frame-inl.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000039#include "thread.h"
Alex Light49af7042019-05-29 18:30:33 -070040#include "verifier/method_verifier.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020041
42namespace art {
43namespace interpreter {
44
David Srbecky6da82472018-10-23 14:03:08 +010045// Short-lived helper class which executes single DEX bytecode. It is inlined by compiler.
46//
47// The function names must match the names from dex_instruction_list.h and have no arguments.
48//
49// Any relevant execution information is stored in the fields - it should be kept to minimum.
50//
David Srbecky47ad3762018-10-31 12:43:40 +000051// Helper methods may return boolean value - in which case 'false' always means
52// "stop executing current opcode" (which does not necessarily exit the interpreter loop).
53//
David Srbecky436f6c12019-05-22 13:28:42 +010054template<bool do_access_check, bool transaction_active, Instruction::Format kFormat>
David Srbecky6da82472018-10-23 14:03:08 +010055class InstructionHandler {
56 public:
Alex Light49af7042019-05-29 18:30:33 -070057 template <bool kMonitorCounting>
58 static NO_INLINE void UnlockHeldMonitors(Thread* self, ShadowFrame* shadow_frame)
59 REQUIRES_SHARED(Locks::mutator_lock_) {
60 DCHECK(shadow_frame->GetForcePopFrame());
61 // Unlock all monitors.
62 if (kMonitorCounting && shadow_frame->GetMethod()->MustCountLocks()) {
63 // Get the monitors from the shadow-frame monitor-count data.
64 shadow_frame->GetLockCountData().VisitMonitors(
65 [&](mirror::Object** obj) REQUIRES_SHARED(Locks::mutator_lock_) {
66 // Since we don't use the 'obj' pointer after the DoMonitorExit everything should be fine
67 // WRT suspension.
68 DoMonitorExit<do_assignability_check>(self, shadow_frame, *obj);
69 });
70 } else {
71 std::vector<verifier::MethodVerifier::DexLockInfo> locks;
72 verifier::MethodVerifier::FindLocksAtDexPc(shadow_frame->GetMethod(),
73 shadow_frame->GetDexPC(),
74 &locks,
75 Runtime::Current()->GetTargetSdkVersion());
76 for (const auto& reg : locks) {
77 if (UNLIKELY(reg.dex_registers.empty())) {
78 LOG(ERROR) << "Unable to determine reference locked by "
79 << shadow_frame->GetMethod()->PrettyMethod() << " at pc "
80 << shadow_frame->GetDexPC();
81 } else {
82 DoMonitorExit<do_assignability_check>(
83 self, shadow_frame, shadow_frame->GetVRegReference(*reg.dex_registers.begin()));
84 }
85 }
86 }
87 }
88
David Srbecky47ad3762018-10-31 12:43:40 +000089 ALWAYS_INLINE WARN_UNUSED bool CheckForceReturn()
90 REQUIRES_SHARED(Locks::mutator_lock_) {
91 if (UNLIKELY(shadow_frame.GetForcePopFrame())) {
92 DCHECK(PrevFrameWillRetry(self, shadow_frame))
93 << "Pop frame forced without previous frame ready to retry instruction!";
94 DCHECK(Runtime::Current()->AreNonStandardExitsEnabled());
Alex Light49af7042019-05-29 18:30:33 -070095 UnlockHeldMonitors<do_assignability_check>(self, &shadow_frame);
96 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame);
David Srbecky47ad3762018-10-31 12:43:40 +000097 if (UNLIKELY(NeedsMethodExitEvent(instrumentation))) {
98 SendMethodExitEvents(self,
99 instrumentation,
100 shadow_frame,
101 shadow_frame.GetThisObject(Accessor().InsSize()),
102 shadow_frame.GetMethod(),
103 inst->GetDexPc(Insns()),
104 JValue());
105 }
106 ctx->result = JValue(); /* Handled in caller. */
107 exit_interpreter_loop = true;
108 return false;
109 }
110 return true;
111 }
112
David Srbecky5f250012018-11-08 14:16:38 +0000113 NO_INLINE WARN_UNUSED bool HandlePendingExceptionWithInstrumentationImpl(
David Srbecky47ad3762018-10-31 12:43:40 +0000114 const instrumentation::Instrumentation* instr)
115 REQUIRES_SHARED(Locks::mutator_lock_) {
116 DCHECK(self->IsExceptionPending());
117 self->AllowThreadSuspension();
118 if (!CheckForceReturn()) {
119 return false;
120 }
121 if (!MoveToExceptionHandler(self, shadow_frame, instr)) {
122 /* Structured locking is to be enforced for abnormal termination, too. */
123 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame);
124 if (ctx->interpret_one_instruction) {
125 /* Signal mterp to return to caller */
126 shadow_frame.SetDexPC(dex::kDexNoIndex);
127 }
128 ctx->result = JValue(); /* Handled in caller. */
129 exit_interpreter_loop = true;
130 return false; // Return to caller.
131 }
132 if (!CheckForceReturn()) {
133 return false;
134 }
135 int32_t displacement =
136 static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc);
137 inst = inst->RelativeAt(displacement);
138 return false; // Stop executing this opcode and continue in the exception handler.
139 }
140
David Srbecky5f250012018-11-08 14:16:38 +0000141 // Forwards the call to the NO_INLINE HandlePendingExceptionWithInstrumentationImpl.
142 ALWAYS_INLINE WARN_UNUSED bool HandlePendingExceptionWithInstrumentation(
143 const instrumentation::Instrumentation* instr)
144 REQUIRES_SHARED(Locks::mutator_lock_) {
145 // We need to help the compiler a bit to make the NO_INLINE call efficient.
146 // * All handler fields should be in registers, so we do not want to take the object
147 // address (for 'this' argument). Make a copy of the handler just for the slow path.
148 // * The modifiable fields should also be in registers, so we don't want to store their
149 // address even in the handler copy. Make a copy of them just for the call as well.
150 const Instruction* inst_copy = inst;
151 bool exit_loop_copy = exit_interpreter_loop;
David Srbecky436f6c12019-05-22 13:28:42 +0100152 InstructionHandler<do_access_check, transaction_active, kFormat> handler_copy(
David Srbecky5f250012018-11-08 14:16:38 +0000153 ctx, instrumentation, self, shadow_frame, dex_pc, inst_copy, inst_data, exit_loop_copy);
154 bool result = handler_copy.HandlePendingExceptionWithInstrumentationImpl(instr);
155 inst = inst_copy;
156 exit_interpreter_loop = exit_loop_copy;
157 return result;
158 }
159
David Srbecky47ad3762018-10-31 12:43:40 +0000160 ALWAYS_INLINE WARN_UNUSED bool HandlePendingException()
161 REQUIRES_SHARED(Locks::mutator_lock_) {
162 return HandlePendingExceptionWithInstrumentation(instrumentation);
163 }
164
165 ALWAYS_INLINE WARN_UNUSED bool PossiblyHandlePendingExceptionOnInvokeImpl(
166 bool is_exception_pending,
167 const Instruction* next_inst)
168 REQUIRES_SHARED(Locks::mutator_lock_) {
169 if (UNLIKELY(shadow_frame.GetForceRetryInstruction())) {
170 /* Don't need to do anything except clear the flag and exception. We leave the */
171 /* instruction the same so it will be re-executed on the next go-around. */
172 DCHECK(inst->IsInvoke());
173 shadow_frame.SetForceRetryInstruction(false);
174 if (UNLIKELY(is_exception_pending)) {
175 DCHECK(self->IsExceptionPending());
176 if (kIsDebugBuild) {
177 LOG(WARNING) << "Suppressing exception for instruction-retry: "
178 << self->GetException()->Dump();
179 }
180 self->ClearException();
181 }
182 } else if (UNLIKELY(is_exception_pending)) {
183 /* Should have succeeded. */
184 DCHECK(!shadow_frame.GetForceRetryInstruction());
185 if (!HandlePendingException()) {
186 return false;
187 }
188 } else {
189 inst = next_inst;
190 }
191 return true;
192 }
193
194 ALWAYS_INLINE WARN_UNUSED bool PossiblyHandlePendingException(
195 bool is_exception_pending,
196 const Instruction* next_inst)
197 REQUIRES_SHARED(Locks::mutator_lock_) {
198 /* Should only be on invoke instructions. */
199 DCHECK(!shadow_frame.GetForceRetryInstruction());
200 if (UNLIKELY(is_exception_pending)) {
201 if (!HandlePendingException()) {
202 return false;
203 }
204 } else {
205 inst = next_inst;
206 }
207 return true;
208 }
209
210 ALWAYS_INLINE WARN_UNUSED bool HandleMonitorChecks()
211 REQUIRES_SHARED(Locks::mutator_lock_) {
212 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) {
213 if (!HandlePendingException()) {
214 return false;
215 }
216 }
217 return true;
218 }
219
220 // Code to run before each dex instruction.
David Srbeckya4a96af2018-10-31 16:34:58 +0000221 ALWAYS_INLINE WARN_UNUSED bool Preamble()
David Srbecky47ad3762018-10-31 12:43:40 +0000222 REQUIRES_SHARED(Locks::mutator_lock_) {
223 /* We need to put this before & after the instrumentation to avoid having to put in a */
224 /* post-script macro. */
225 if (!CheckForceReturn()) {
226 return false;
227 }
228 if (UNLIKELY(instrumentation->HasDexPcListeners())) {
David Srbeckya4a96af2018-10-31 16:34:58 +0000229 uint8_t opcode = inst->Opcode(inst_data);
230 bool is_move_result_object = (opcode == Instruction::MOVE_RESULT_OBJECT);
231 JValue* save_ref = is_move_result_object ? &ctx->result_register : nullptr;
David Srbecky47ad3762018-10-31 12:43:40 +0000232 if (UNLIKELY(!DoDexPcMoveEvent(self,
233 Accessor(),
234 shadow_frame,
235 dex_pc,
236 instrumentation,
237 save_ref))) {
238 if (!HandlePendingException()) {
239 return false;
240 }
241 }
242 if (!CheckForceReturn()) {
243 return false;
244 }
245 }
246 return true;
247 }
248
249 ALWAYS_INLINE WARN_UNUSED bool BranchInstrumentation(int32_t offset)
250 REQUIRES_SHARED(Locks::mutator_lock_) {
251 if (UNLIKELY(instrumentation->HasBranchListeners())) {
252 instrumentation->Branch(self, shadow_frame.GetMethod(), dex_pc, offset);
253 }
254 JValue result;
255 if (jit::Jit::MaybeDoOnStackReplacement(self,
256 shadow_frame.GetMethod(),
257 dex_pc,
258 offset,
259 &result)) {
260 if (ctx->interpret_one_instruction) {
261 /* OSR has completed execution of the method. Signal mterp to return to caller */
262 shadow_frame.SetDexPC(dex::kDexNoIndex);
263 }
264 ctx->result = result;
265 exit_interpreter_loop = true;
266 return false;
267 }
268 return true;
269 }
270
271 ALWAYS_INLINE void HotnessUpdate()
272 REQUIRES_SHARED(Locks::mutator_lock_) {
273 jit::Jit* jit = Runtime::Current()->GetJit();
274 if (jit != nullptr) {
275 jit->AddSamples(self, shadow_frame.GetMethod(), 1, /*with_backedges=*/ true);
276 }
277 }
278
279 ALWAYS_INLINE WARN_UNUSED bool HandleAsyncException()
280 REQUIRES_SHARED(Locks::mutator_lock_) {
281 if (UNLIKELY(self->ObserveAsyncException())) {
282 if (!HandlePendingException()) {
283 return false;
284 }
285 }
286 return true;
287 }
288
289 ALWAYS_INLINE void HandleBackwardBranch(int32_t offset)
290 REQUIRES_SHARED(Locks::mutator_lock_) {
291 if (IsBackwardBranch(offset)) {
292 HotnessUpdate();
293 /* Record new dex pc early to have consistent suspend point at loop header. */
294 shadow_frame.SetDexPC(inst->GetDexPc(Insns()));
295 self->AllowThreadSuspension();
296 }
297 }
298
299 // Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
300 // the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
301 // to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
302 // jvmti-agents while handling breakpoint or single step events. We had to move this into its own
303 // function because it was making ExecuteSwitchImpl have too large a stack.
304 NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
305 const CodeItemDataAccessor& accessor,
306 const ShadowFrame& shadow_frame,
307 uint32_t dex_pc,
308 const instrumentation::Instrumentation* instrumentation,
309 JValue* save_ref)
310 REQUIRES_SHARED(Locks::mutator_lock_) {
311 DCHECK(instrumentation->HasDexPcListeners());
312 StackHandleScope<2> hs(self);
313 Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
314 mirror::Object* null_obj = nullptr;
315 HandleWrapper<mirror::Object> h(
316 hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
317 self->ClearException();
318 instrumentation->DexPcMovedEvent(self,
319 shadow_frame.GetThisObject(accessor.InsSize()),
320 shadow_frame.GetMethod(),
321 dex_pc);
322 if (UNLIKELY(self->IsExceptionPending())) {
323 // We got a new exception in the dex-pc-moved event.
324 // We just let this exception replace the old one.
325 // TODO It would be good to add the old exception to the
326 // suppressed exceptions of the new one if possible.
327 return false;
328 } else {
329 if (UNLIKELY(!thr.IsNull())) {
330 self->SetException(thr.Get());
331 }
332 return true;
333 }
334 }
335
336 static bool NeedsMethodExitEvent(const instrumentation::Instrumentation* ins)
337 REQUIRES_SHARED(Locks::mutator_lock_) {
338 return ins->HasMethodExitListeners() || ins->HasWatchedFramePopListeners();
339 }
340
341 // Sends the normal method exit event.
342 // Returns true if the events succeeded and false if there is a pending exception.
343 NO_INLINE static bool SendMethodExitEvents(
344 Thread* self,
345 const instrumentation::Instrumentation* instrumentation,
346 const ShadowFrame& frame,
347 ObjPtr<mirror::Object> thiz,
348 ArtMethod* method,
349 uint32_t dex_pc,
350 const JValue& result)
351 REQUIRES_SHARED(Locks::mutator_lock_) {
352 bool had_event = false;
353 // We don't send method-exit if it's a pop-frame. We still send frame_popped though.
354 if (UNLIKELY(instrumentation->HasMethodExitListeners() && !frame.GetForcePopFrame())) {
355 had_event = true;
Vladimir Marko19711d42019-04-12 14:05:34 +0100356 instrumentation->MethodExitEvent(self, thiz, method, dex_pc, result);
David Srbecky47ad3762018-10-31 12:43:40 +0000357 }
358 if (UNLIKELY(frame.NeedsNotifyPop() && instrumentation->HasWatchedFramePopListeners())) {
359 had_event = true;
360 instrumentation->WatchedFramePopped(self, frame);
361 }
362 if (UNLIKELY(had_event)) {
363 return !self->IsExceptionPending();
364 } else {
365 return true;
366 }
367 }
368
369#define BRANCH_INSTRUMENTATION(offset) \
370 if (!BranchInstrumentation(offset)) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100371 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000372 }
373
374#define HANDLE_PENDING_EXCEPTION() \
375 if (!HandlePendingException()) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100376 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000377 }
378
379#define POSSIBLY_HANDLE_PENDING_EXCEPTION(is_exception_pending, next_function) \
380 if (!PossiblyHandlePendingException(is_exception_pending, inst->next_function())) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100381 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000382 }
383
384#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(is_exception_pending) \
385 if (!PossiblyHandlePendingExceptionOnInvokeImpl(is_exception_pending, inst->Next_4xx())) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100386 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000387 }
388
389#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(is_exception_pending) \
390 if (!PossiblyHandlePendingExceptionOnInvokeImpl(is_exception_pending, inst->Next_3xx())) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100391 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000392 }
393
David Srbeckyee12e3a2019-06-03 15:18:57 +0100394 ALWAYS_INLINE WARN_UNUSED bool HandleReturn(JValue result) REQUIRES_SHARED(Locks::mutator_lock_) {
395 self->AllowThreadSuspension();
396 if (!HandleMonitorChecks()) {
397 return false;
398 }
399 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
400 !SendMethodExitEvents(self,
401 instrumentation,
402 shadow_frame,
403 shadow_frame.GetThisObject(Accessor().InsSize()),
404 shadow_frame.GetMethod(),
405 inst->GetDexPc(Insns()),
406 result))) {
407 if (!HandlePendingExceptionWithInstrumentation(nullptr)) {
408 return false;
409 }
410 }
411 if (ctx->interpret_one_instruction) {
412 /* Signal mterp to return to caller */
413 shadow_frame.SetDexPC(dex::kDexNoIndex);
414 }
415 ctx->result = result;
416 exit_interpreter_loop = true;
417 return true;
418 }
419
420 ALWAYS_INLINE WARN_UNUSED bool HandleGoto(int32_t offset) REQUIRES_SHARED(Locks::mutator_lock_) {
421 if (!HandleAsyncException()) {
422 return false;
423 }
424 BRANCH_INSTRUMENTATION(offset);
425 inst = inst->RelativeAt(offset);
426 HandleBackwardBranch(offset);
427 return true;
428 }
429
430#pragma clang diagnostic push
431#pragma clang diagnostic ignored "-Wfloat-equal"
432
433 template<typename T>
434 ALWAYS_INLINE WARN_UNUSED bool HandleCmpl(T val1, T val2) REQUIRES_SHARED(Locks::mutator_lock_) {
435 int32_t result;
436 if (val1 > val2) {
437 result = 1;
438 } else if (val1 == val2) {
439 result = 0;
440 } else {
441 result = -1;
442 }
443 SetVReg(A(), result);
444 inst = inst->Next_2xx();
445 return true;
446 }
447
448 // Returns the same result as the function above. It only differs for NaN values.
449 template<typename T>
450 ALWAYS_INLINE WARN_UNUSED bool HandleCmpg(T val1, T val2) REQUIRES_SHARED(Locks::mutator_lock_) {
451 int32_t result;
452 if (val1 < val2) {
453 result = -1;
454 } else if (val1 == val2) {
455 result = 0;
456 } else {
457 result = 1;
458 }
459 SetVReg(A(), result);
460 inst = inst->Next_2xx();
461 return true;
462 }
463
464#pragma clang diagnostic pop
465
466 ALWAYS_INLINE WARN_UNUSED bool HandleIf(bool cond, int32_t offset)
467 REQUIRES_SHARED(Locks::mutator_lock_) {
468 if (cond) {
469 BRANCH_INSTRUMENTATION(offset);
470 inst = inst->RelativeAt(offset);
471 HandleBackwardBranch(offset);
472 } else {
473 BRANCH_INSTRUMENTATION(2);
474 inst = inst->Next_2xx();
475 }
476 return true;
477 }
478
David Srbecky1332c262019-06-04 13:13:37 +0100479 template<typename ArrayType, typename SetVRegFn>
480 ALWAYS_INLINE bool HandleAGet(SetVRegFn setVReg) REQUIRES_SHARED(Locks::mutator_lock_) {
481 ObjPtr<mirror::Object> a = GetVRegReference(B());
482 if (UNLIKELY(a == nullptr)) {
483 ThrowNullPointerExceptionFromInterpreter();
484 HANDLE_PENDING_EXCEPTION();
485 }
486 int32_t index = GetVReg(C());
487 ObjPtr<ArrayType> array = ObjPtr<ArrayType>::DownCast(a);
488 if (UNLIKELY(!array->CheckIsValidIndex(index))) {
489 HANDLE_PENDING_EXCEPTION();
490 } else {
491 (this->*setVReg)(A(), array->GetWithoutChecks(index));
492 inst = inst->Next_2xx();
493 }
494 return true;
495 }
496
497 template<typename ArrayType, typename T>
498 ALWAYS_INLINE bool HandleAPut(T value) REQUIRES_SHARED(Locks::mutator_lock_) {
499 ObjPtr<mirror::Object> a = GetVRegReference(B());
500 if (UNLIKELY(a == nullptr)) {
501 ThrowNullPointerExceptionFromInterpreter();
502 HANDLE_PENDING_EXCEPTION();
503 }
504 int32_t index = GetVReg(C());
505 ObjPtr<ArrayType> array = ObjPtr<ArrayType>::DownCast(a);
506 if (UNLIKELY(!array->CheckIsValidIndex(index))) {
507 HANDLE_PENDING_EXCEPTION();
508 } else {
509 array->template SetWithoutChecks<transaction_active>(index, value);
510 inst = inst->Next_2xx();
511 }
512 return true;
513 }
514
David Srbeckyee12e3a2019-06-03 15:18:57 +0100515 template<FindFieldType find_type, Primitive::Type field_type>
516 ALWAYS_INLINE WARN_UNUSED bool HandleGet() REQUIRES_SHARED(Locks::mutator_lock_) {
517 bool success = DoFieldGet<find_type, field_type, do_access_check, transaction_active>(
518 self, shadow_frame, inst, inst_data);
519 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
520 return true;
521 }
522
523 template<Primitive::Type field_type>
524 ALWAYS_INLINE WARN_UNUSED bool HandleGetQuick() REQUIRES_SHARED(Locks::mutator_lock_) {
525 bool success = DoIGetQuick<field_type>(shadow_frame, inst, inst_data);
526 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
527 return true;
528 }
529
530 template<FindFieldType find_type, Primitive::Type field_type>
531 ALWAYS_INLINE WARN_UNUSED bool HandlePut() REQUIRES_SHARED(Locks::mutator_lock_) {
532 bool success = DoFieldPut<find_type, field_type, do_access_check, transaction_active>(
533 self, shadow_frame, inst, inst_data);
534 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
535 return true;
536 }
537
538 template<Primitive::Type field_type>
539 ALWAYS_INLINE WARN_UNUSED bool HandlePutQuick() REQUIRES_SHARED(Locks::mutator_lock_) {
540 bool success = DoIPutQuick<field_type, transaction_active>(
541 shadow_frame, inst, inst_data);
542 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
543 return true;
544 }
545
546 template<InvokeType type, bool is_range, bool is_quick = false>
547 ALWAYS_INLINE WARN_UNUSED bool HandleInvoke() REQUIRES_SHARED(Locks::mutator_lock_) {
548 bool success = DoInvoke<type, is_range, do_access_check, /*is_mterp=*/ false, is_quick>(
549 self, shadow_frame, inst, inst_data, ResultRegister());
550 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
551 return true;
552 }
553
554 ALWAYS_INLINE WARN_UNUSED bool HandleUnused() REQUIRES_SHARED(Locks::mutator_lock_) {
555 UnexpectedOpcode(inst, shadow_frame);
556 return true;
557 }
558
David Srbeckybd613ec2019-05-30 15:39:38 +0100559 ALWAYS_INLINE bool NOP() REQUIRES_SHARED(Locks::mutator_lock_) {
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() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100565 SetVReg(A(), GetVReg(B()));
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_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100571 SetVReg(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100572 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100573 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100574 }
575
David Srbeckybd613ec2019-05-30 15:39:38 +0100576 ALWAYS_INLINE bool MOVE_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100577 SetVReg(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100578 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100579 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100580 }
581
David Srbeckybd613ec2019-05-30 15:39:38 +0100582 ALWAYS_INLINE bool MOVE_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100583 SetVRegLong(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100584 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100585 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100586 }
587
David Srbeckybd613ec2019-05-30 15:39:38 +0100588 ALWAYS_INLINE bool MOVE_WIDE_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100589 SetVRegLong(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100590 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100591 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100592 }
593
David Srbeckybd613ec2019-05-30 15:39:38 +0100594 ALWAYS_INLINE bool MOVE_WIDE_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100595 SetVRegLong(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100596 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100597 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100598 }
599
David Srbeckybd613ec2019-05-30 15:39:38 +0100600 ALWAYS_INLINE bool MOVE_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100601 SetVRegReference(A(), GetVRegReference(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100602 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100603 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100604 }
605
David Srbeckybd613ec2019-05-30 15:39:38 +0100606 ALWAYS_INLINE bool MOVE_OBJECT_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100607 SetVRegReference(A(), GetVRegReference(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100608 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100609 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100610 }
611
David Srbeckybd613ec2019-05-30 15:39:38 +0100612 ALWAYS_INLINE bool MOVE_OBJECT_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100613 SetVRegReference(A(), GetVRegReference(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100614 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100615 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100616 }
617
David Srbeckybd613ec2019-05-30 15:39:38 +0100618 ALWAYS_INLINE bool MOVE_RESULT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100619 SetVReg(A(), ResultRegister()->GetI());
David Srbecky6da82472018-10-23 14:03:08 +0100620 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100621 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100622 }
623
David Srbeckybd613ec2019-05-30 15:39:38 +0100624 ALWAYS_INLINE bool MOVE_RESULT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100625 SetVRegLong(A(), ResultRegister()->GetJ());
David Srbecky6da82472018-10-23 14:03:08 +0100626 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100627 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100628 }
629
David Srbeckybd613ec2019-05-30 15:39:38 +0100630 ALWAYS_INLINE bool MOVE_RESULT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100631 SetVRegReference(A(), ResultRegister()->GetL());
David Srbecky6da82472018-10-23 14:03:08 +0100632 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100633 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100634 }
635
David Srbeckybd613ec2019-05-30 15:39:38 +0100636 ALWAYS_INLINE bool MOVE_EXCEPTION() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100637 ObjPtr<mirror::Throwable> exception = self->GetException();
638 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
David Srbecky6baf6442019-05-30 14:57:43 +0100639 SetVRegReference(A(), exception);
David Srbecky6da82472018-10-23 14:03:08 +0100640 self->ClearException();
641 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100642 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100643 }
644
David Srbeckybd613ec2019-05-30 15:39:38 +0100645 ALWAYS_INLINE bool RETURN_VOID_NO_BARRIER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100646 JValue result;
David Srbeckyee12e3a2019-06-03 15:18:57 +0100647 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100648 }
649
David Srbeckybd613ec2019-05-30 15:39:38 +0100650 ALWAYS_INLINE bool RETURN_VOID() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100651 QuasiAtomic::ThreadFenceForConstructor();
652 JValue result;
David Srbeckyee12e3a2019-06-03 15:18:57 +0100653 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100654 }
655
David Srbeckybd613ec2019-05-30 15:39:38 +0100656 ALWAYS_INLINE bool RETURN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100657 JValue result;
658 result.SetJ(0);
David Srbecky6baf6442019-05-30 14:57:43 +0100659 result.SetI(GetVReg(A()));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100660 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100661 }
662
David Srbeckybd613ec2019-05-30 15:39:38 +0100663 ALWAYS_INLINE bool RETURN_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100664 JValue result;
David Srbecky6baf6442019-05-30 14:57:43 +0100665 result.SetJ(GetVRegLong(A()));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100666 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100667 }
668
David Srbeckybd613ec2019-05-30 15:39:38 +0100669 ALWAYS_INLINE bool RETURN_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100670 JValue result;
671 self->AllowThreadSuspension();
David Srbecky47ad3762018-10-31 12:43:40 +0000672 if (!HandleMonitorChecks()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100673 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000674 }
David Srbeckyd6f579c2019-05-29 18:09:30 +0100675 const size_t ref_idx = A();
David Srbecky6baf6442019-05-30 14:57:43 +0100676 ObjPtr<mirror::Object> obj_result = GetVRegReference(ref_idx);
David Srbecky6da82472018-10-23 14:03:08 +0100677 if (do_assignability_check && obj_result != nullptr) {
678 ObjPtr<mirror::Class> return_type = shadow_frame.GetMethod()->ResolveReturnType();
679 // Re-load since it might have moved.
David Srbecky6baf6442019-05-30 14:57:43 +0100680 obj_result = GetVRegReference(ref_idx);
David Srbecky6da82472018-10-23 14:03:08 +0100681 if (return_type == nullptr) {
682 // Return the pending exception.
683 HANDLE_PENDING_EXCEPTION();
684 }
685 if (!obj_result->VerifierInstanceOf(return_type)) {
686 // This should never happen.
687 std::string temp1, temp2;
688 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
689 "Returning '%s' that is not instance of return type '%s'",
690 obj_result->GetClass()->GetDescriptor(&temp1),
691 return_type->GetDescriptor(&temp2));
692 HANDLE_PENDING_EXCEPTION();
693 }
694 }
695 result.SetL(obj_result);
696 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
697 !SendMethodExitEvents(self,
698 instrumentation,
699 shadow_frame,
700 shadow_frame.GetThisObject(Accessor().InsSize()),
701 shadow_frame.GetMethod(),
702 inst->GetDexPc(Insns()),
703 result))) {
David Srbecky47ad3762018-10-31 12:43:40 +0000704 if (!HandlePendingExceptionWithInstrumentation(nullptr)) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100705 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000706 }
David Srbecky6da82472018-10-23 14:03:08 +0100707 }
708 // Re-load since it might have moved during the MethodExitEvent.
David Srbecky6baf6442019-05-30 14:57:43 +0100709 result.SetL(GetVRegReference(ref_idx));
David Srbecky6da82472018-10-23 14:03:08 +0100710 if (ctx->interpret_one_instruction) {
711 /* Signal mterp to return to caller */
712 shadow_frame.SetDexPC(dex::kDexNoIndex);
713 }
714 ctx->result = result;
715 exit_interpreter_loop = true;
David Srbeckybd613ec2019-05-30 15:39:38 +0100716 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100717 }
718
David Srbeckybd613ec2019-05-30 15:39:38 +0100719 ALWAYS_INLINE bool CONST_4() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100720 uint4_t dst = inst->VRegA_11n(inst_data);
721 int4_t val = inst->VRegB_11n(inst_data);
David Srbecky6baf6442019-05-30 14:57:43 +0100722 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100723 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100724 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100725 }
726 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100727 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100728 }
729
David Srbeckybd613ec2019-05-30 15:39:38 +0100730 ALWAYS_INLINE bool CONST_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100731 uint8_t dst = A();
732 int16_t val = B();
David Srbecky6baf6442019-05-30 14:57:43 +0100733 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100734 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100735 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100736 }
737 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100738 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100739 }
740
David Srbeckybd613ec2019-05-30 15:39:38 +0100741 ALWAYS_INLINE bool CONST() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100742 uint8_t dst = A();
743 int32_t val = B();
David Srbecky6baf6442019-05-30 14:57:43 +0100744 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100745 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100746 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100747 }
748 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100749 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100750 }
751
David Srbeckybd613ec2019-05-30 15:39:38 +0100752 ALWAYS_INLINE bool CONST_HIGH16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100753 uint8_t dst = A();
754 int32_t val = static_cast<int32_t>(B() << 16);
David Srbecky6baf6442019-05-30 14:57:43 +0100755 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100756 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100757 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100758 }
759 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100760 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100761 }
762
David Srbeckybd613ec2019-05-30 15:39:38 +0100763 ALWAYS_INLINE bool CONST_WIDE_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100764 SetVRegLong(A(), B());
David Srbecky6da82472018-10-23 14:03:08 +0100765 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100766 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100767 }
768
David Srbeckybd613ec2019-05-30 15:39:38 +0100769 ALWAYS_INLINE bool CONST_WIDE_32() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100770 SetVRegLong(A(), B());
David Srbecky6da82472018-10-23 14:03:08 +0100771 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100772 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100773 }
774
David Srbeckybd613ec2019-05-30 15:39:38 +0100775 ALWAYS_INLINE bool CONST_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100776 SetVRegLong(A(), inst->WideVRegB());
David Srbecky6da82472018-10-23 14:03:08 +0100777 inst = inst->Next_51l();
David Srbeckybd613ec2019-05-30 15:39:38 +0100778 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100779 }
780
David Srbeckybd613ec2019-05-30 15:39:38 +0100781 ALWAYS_INLINE bool CONST_WIDE_HIGH16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100782 SetVRegLong(A(), static_cast<uint64_t>(B()) << 48);
David Srbecky6da82472018-10-23 14:03:08 +0100783 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100784 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100785 }
786
David Srbeckybd613ec2019-05-30 15:39:38 +0100787 ALWAYS_INLINE bool CONST_STRING() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100788 ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, dex::StringIndex(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100789 if (UNLIKELY(s == nullptr)) {
790 HANDLE_PENDING_EXCEPTION();
791 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100792 SetVRegReference(A(), s);
David Srbecky6da82472018-10-23 14:03:08 +0100793 inst = inst->Next_2xx();
794 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100795 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100796 }
797
David Srbeckybd613ec2019-05-30 15:39:38 +0100798 ALWAYS_INLINE bool CONST_STRING_JUMBO() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100799 ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, dex::StringIndex(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100800 if (UNLIKELY(s == nullptr)) {
801 HANDLE_PENDING_EXCEPTION();
802 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100803 SetVRegReference(A(), s);
David Srbecky6da82472018-10-23 14:03:08 +0100804 inst = inst->Next_3xx();
805 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100806 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100807 }
808
David Srbeckybd613ec2019-05-30 15:39:38 +0100809 ALWAYS_INLINE bool CONST_CLASS() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100810 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100811 shadow_frame.GetMethod(),
812 self,
813 false,
814 do_access_check);
815 if (UNLIKELY(c == nullptr)) {
816 HANDLE_PENDING_EXCEPTION();
817 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100818 SetVRegReference(A(), c);
David Srbecky6da82472018-10-23 14:03:08 +0100819 inst = inst->Next_2xx();
820 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100821 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100822 }
823
David Srbeckybd613ec2019-05-30 15:39:38 +0100824 ALWAYS_INLINE bool CONST_METHOD_HANDLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100825 ClassLinker* cl = Runtime::Current()->GetClassLinker();
826 ObjPtr<mirror::MethodHandle> mh = cl->ResolveMethodHandle(self,
David Srbeckyd6f579c2019-05-29 18:09:30 +0100827 B(),
David Srbecky6da82472018-10-23 14:03:08 +0100828 shadow_frame.GetMethod());
829 if (UNLIKELY(mh == nullptr)) {
830 HANDLE_PENDING_EXCEPTION();
831 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100832 SetVRegReference(A(), mh);
David Srbecky6da82472018-10-23 14:03:08 +0100833 inst = inst->Next_2xx();
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 CONST_METHOD_TYPE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100839 ClassLinker* cl = Runtime::Current()->GetClassLinker();
840 ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(self,
David Srbeckyd6f579c2019-05-29 18:09:30 +0100841 dex::ProtoIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100842 shadow_frame.GetMethod());
843 if (UNLIKELY(mt == nullptr)) {
844 HANDLE_PENDING_EXCEPTION();
845 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100846 SetVRegReference(A(), mt);
David Srbecky6da82472018-10-23 14:03:08 +0100847 inst = inst->Next_2xx();
848 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100849 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100850 }
851
David Srbeckybd613ec2019-05-30 15:39:38 +0100852 ALWAYS_INLINE bool MONITOR_ENTER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000853 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100854 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000855 }
David Srbecky6baf6442019-05-30 14:57:43 +0100856 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100857 if (UNLIKELY(obj == nullptr)) {
858 ThrowNullPointerExceptionFromInterpreter();
859 HANDLE_PENDING_EXCEPTION();
860 } else {
861 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
862 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
863 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100864 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100865 }
866
David Srbeckybd613ec2019-05-30 15:39:38 +0100867 ALWAYS_INLINE bool MONITOR_EXIT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000868 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100869 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000870 }
David Srbecky6baf6442019-05-30 14:57:43 +0100871 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100872 if (UNLIKELY(obj == nullptr)) {
873 ThrowNullPointerExceptionFromInterpreter();
874 HANDLE_PENDING_EXCEPTION();
875 } else {
876 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
877 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
878 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100879 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100880 }
881
David Srbeckybd613ec2019-05-30 15:39:38 +0100882 ALWAYS_INLINE bool CHECK_CAST() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100883 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100884 shadow_frame.GetMethod(),
885 self,
886 false,
887 do_access_check);
888 if (UNLIKELY(c == nullptr)) {
889 HANDLE_PENDING_EXCEPTION();
890 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100891 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100892 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
893 ThrowClassCastException(c, obj->GetClass());
894 HANDLE_PENDING_EXCEPTION();
895 } else {
896 inst = inst->Next_2xx();
897 }
898 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100899 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100900 }
901
David Srbeckybd613ec2019-05-30 15:39:38 +0100902 ALWAYS_INLINE bool INSTANCE_OF() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100903 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(C()),
David Srbecky6da82472018-10-23 14:03:08 +0100904 shadow_frame.GetMethod(),
905 self,
906 false,
907 do_access_check);
908 if (UNLIKELY(c == nullptr)) {
909 HANDLE_PENDING_EXCEPTION();
910 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100911 ObjPtr<mirror::Object> obj = GetVRegReference(B());
912 SetVReg(A(), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
David Srbecky6da82472018-10-23 14:03:08 +0100913 inst = inst->Next_2xx();
914 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100915 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100916 }
917
David Srbeckybd613ec2019-05-30 15:39:38 +0100918 ALWAYS_INLINE bool ARRAY_LENGTH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100919 ObjPtr<mirror::Object> array = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +0100920 if (UNLIKELY(array == nullptr)) {
921 ThrowNullPointerExceptionFromInterpreter();
922 HANDLE_PENDING_EXCEPTION();
923 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100924 SetVReg(A(), array->AsArray()->GetLength());
David Srbecky6da82472018-10-23 14:03:08 +0100925 inst = inst->Next_1xx();
926 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100927 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100928 }
929
David Srbeckybd613ec2019-05-30 15:39:38 +0100930 ALWAYS_INLINE bool NEW_INSTANCE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100931 ObjPtr<mirror::Object> obj = nullptr;
David Srbeckyd6f579c2019-05-29 18:09:30 +0100932 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100933 shadow_frame.GetMethod(),
934 self,
935 false,
936 do_access_check);
937 if (LIKELY(c != nullptr)) {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100938 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
David Srbecky6da82472018-10-23 14:03:08 +0100939 if (UNLIKELY(c->IsStringClass())) {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100940 obj = mirror::String::AllocEmptyString(self, allocator_type);
David Srbecky6da82472018-10-23 14:03:08 +0100941 } else {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100942 obj = AllocObjectFromCode(c, self, allocator_type);
David Srbecky6da82472018-10-23 14:03:08 +0100943 }
944 }
945 if (UNLIKELY(obj == nullptr)) {
946 HANDLE_PENDING_EXCEPTION();
947 } else {
948 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
949 // Don't allow finalizable objects to be allocated during a transaction since these can't
950 // be finalized without a started runtime.
951 if (transaction_active && obj->GetClass()->IsFinalizable()) {
952 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
953 obj->PrettyTypeOf().c_str());
954 HANDLE_PENDING_EXCEPTION();
955 }
David Srbecky6baf6442019-05-30 14:57:43 +0100956 SetVRegReference(A(), obj);
David Srbecky6da82472018-10-23 14:03:08 +0100957 inst = inst->Next_2xx();
958 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100959 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100960 }
961
David Srbeckybd613ec2019-05-30 15:39:38 +0100962 ALWAYS_INLINE bool NEW_ARRAY() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100963 int32_t length = GetVReg(B());
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100964 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check>(
David Srbeckyd6f579c2019-05-29 18:09:30 +0100965 dex::TypeIndex(C()),
David Srbecky6da82472018-10-23 14:03:08 +0100966 length,
967 shadow_frame.GetMethod(),
968 self,
969 Runtime::Current()->GetHeap()->GetCurrentAllocator());
970 if (UNLIKELY(obj == nullptr)) {
971 HANDLE_PENDING_EXCEPTION();
972 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100973 SetVRegReference(A(), obj);
David Srbecky6da82472018-10-23 14:03:08 +0100974 inst = inst->Next_2xx();
975 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100976 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100977 }
978
David Srbeckybd613ec2019-05-30 15:39:38 +0100979 ALWAYS_INLINE bool FILLED_NEW_ARRAY() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100980 bool success =
981 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
982 ResultRegister());
983 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
David Srbeckybd613ec2019-05-30 15:39:38 +0100984 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100985 }
986
David Srbeckybd613ec2019-05-30 15:39:38 +0100987 ALWAYS_INLINE bool FILLED_NEW_ARRAY_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100988 bool success =
989 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
990 self, ResultRegister());
991 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
David Srbeckybd613ec2019-05-30 15:39:38 +0100992 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100993 }
994
David Srbeckybd613ec2019-05-30 15:39:38 +0100995 ALWAYS_INLINE bool FILL_ARRAY_DATA() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100996 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + B();
David Srbecky6da82472018-10-23 14:03:08 +0100997 const Instruction::ArrayDataPayload* payload =
998 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
David Srbecky6baf6442019-05-30 14:57:43 +0100999 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +01001000 bool success = FillArrayData(obj, payload);
1001 if (!success) {
1002 HANDLE_PENDING_EXCEPTION();
1003 }
1004 if (transaction_active) {
1005 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
1006 }
1007 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001008 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001009 }
1010
David Srbeckybd613ec2019-05-30 15:39:38 +01001011 ALWAYS_INLINE bool THROW() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +00001012 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +01001013 return false;
David Srbecky47ad3762018-10-31 12:43:40 +00001014 }
David Srbecky6baf6442019-05-30 14:57:43 +01001015 ObjPtr<mirror::Object> exception = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +01001016 if (UNLIKELY(exception == nullptr)) {
1017 ThrowNullPointerException("throw with null exception");
1018 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
1019 // This should never happen.
1020 std::string temp;
1021 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
1022 "Throwing '%s' that is not instance of Throwable",
1023 exception->GetClass()->GetDescriptor(&temp));
1024 } else {
1025 self->SetException(exception->AsThrowable());
1026 }
1027 HANDLE_PENDING_EXCEPTION();
David Srbeckybd613ec2019-05-30 15:39:38 +01001028 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001029 }
1030
David Srbeckybd613ec2019-05-30 15:39:38 +01001031 ALWAYS_INLINE bool GOTO() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001032 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +01001033 }
1034
David Srbeckybd613ec2019-05-30 15:39:38 +01001035 ALWAYS_INLINE bool GOTO_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001036 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +01001037 }
1038
David Srbeckybd613ec2019-05-30 15:39:38 +01001039 ALWAYS_INLINE bool GOTO_32() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001040 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +01001041 }
1042
David Srbeckybd613ec2019-05-30 15:39:38 +01001043 ALWAYS_INLINE bool PACKED_SWITCH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001044 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
1045 BRANCH_INSTRUMENTATION(offset);
1046 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001047 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +01001048 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001049 }
1050
David Srbeckybd613ec2019-05-30 15:39:38 +01001051 ALWAYS_INLINE bool SPARSE_SWITCH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001052 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
1053 BRANCH_INSTRUMENTATION(offset);
1054 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001055 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +01001056 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001057 }
1058
David Srbeckybd613ec2019-05-30 15:39:38 +01001059 ALWAYS_INLINE bool CMPL_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001060 return HandleCmpl<float>(GetVRegFloat(B()), GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001061 }
1062
David Srbeckybd613ec2019-05-30 15:39:38 +01001063 ALWAYS_INLINE bool CMPG_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001064 return HandleCmpg<float>(GetVRegFloat(B()), GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001065 }
1066
David Srbeckybd613ec2019-05-30 15:39:38 +01001067 ALWAYS_INLINE bool CMPL_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001068 return HandleCmpl<double>(GetVRegDouble(B()), GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001069 }
1070
David Srbeckybd613ec2019-05-30 15:39:38 +01001071 ALWAYS_INLINE bool CMPG_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001072 return HandleCmpg<double>(GetVRegDouble(B()), GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001073 }
1074
David Srbeckybd613ec2019-05-30 15:39:38 +01001075 ALWAYS_INLINE bool CMP_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001076 return HandleCmpl<int64_t>(GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001077 }
1078
David Srbeckybd613ec2019-05-30 15:39:38 +01001079 ALWAYS_INLINE bool IF_EQ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001080 return HandleIf(GetVReg(A()) == GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001081 }
1082
David Srbeckybd613ec2019-05-30 15:39:38 +01001083 ALWAYS_INLINE bool IF_NE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001084 return HandleIf(GetVReg(A()) != GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001085 }
1086
David Srbeckybd613ec2019-05-30 15:39:38 +01001087 ALWAYS_INLINE bool IF_LT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001088 return HandleIf(GetVReg(A()) < GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001089 }
1090
David Srbeckybd613ec2019-05-30 15:39:38 +01001091 ALWAYS_INLINE bool IF_GE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001092 return HandleIf(GetVReg(A()) >= GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001093 }
1094
David Srbeckybd613ec2019-05-30 15:39:38 +01001095 ALWAYS_INLINE bool IF_GT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001096 return HandleIf(GetVReg(A()) > GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001097 }
1098
David Srbeckybd613ec2019-05-30 15:39:38 +01001099 ALWAYS_INLINE bool IF_LE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001100 return HandleIf(GetVReg(A()) <= GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001101 }
1102
David Srbeckybd613ec2019-05-30 15:39:38 +01001103 ALWAYS_INLINE bool IF_EQZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001104 return HandleIf(GetVReg(A()) == 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001105 }
1106
David Srbeckybd613ec2019-05-30 15:39:38 +01001107 ALWAYS_INLINE bool IF_NEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001108 return HandleIf(GetVReg(A()) != 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001109 }
1110
David Srbeckybd613ec2019-05-30 15:39:38 +01001111 ALWAYS_INLINE bool IF_LTZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001112 return HandleIf(GetVReg(A()) < 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001113 }
1114
David Srbeckybd613ec2019-05-30 15:39:38 +01001115 ALWAYS_INLINE bool IF_GEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001116 return HandleIf(GetVReg(A()) >= 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001117 }
1118
David Srbeckybd613ec2019-05-30 15:39:38 +01001119 ALWAYS_INLINE bool IF_GTZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001120 return HandleIf(GetVReg(A()) > 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001121 }
1122
David Srbeckybd613ec2019-05-30 15:39:38 +01001123 ALWAYS_INLINE bool IF_LEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001124 return HandleIf(GetVReg(A()) <= 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001125 }
1126
David Srbeckybd613ec2019-05-30 15:39:38 +01001127 ALWAYS_INLINE bool AGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001128 return HandleAGet<mirror::BooleanArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +01001129 }
1130
David Srbeckybd613ec2019-05-30 15:39:38 +01001131 ALWAYS_INLINE bool AGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001132 return HandleAGet<mirror::ByteArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +01001133 }
1134
David Srbeckybd613ec2019-05-30 15:39:38 +01001135 ALWAYS_INLINE bool AGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001136 return HandleAGet<mirror::CharArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +01001137 }
1138
David Srbeckybd613ec2019-05-30 15:39:38 +01001139 ALWAYS_INLINE bool AGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001140 return HandleAGet<mirror::ShortArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +01001141 }
1142
David Srbeckybd613ec2019-05-30 15:39:38 +01001143 ALWAYS_INLINE bool AGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001144 return HandleAGet<mirror::IntArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +01001145 }
1146
David Srbeckybd613ec2019-05-30 15:39:38 +01001147 ALWAYS_INLINE bool AGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001148 return HandleAGet<mirror::LongArray>(&InstructionHandler::SetVRegLong);
David Srbecky6da82472018-10-23 14:03:08 +01001149 }
1150
David Srbeckybd613ec2019-05-30 15:39:38 +01001151 ALWAYS_INLINE bool AGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001152 return HandleAGet<mirror::ObjectArray<mirror::Object>>(&InstructionHandler::SetVRegReference);
David Srbecky6da82472018-10-23 14:03:08 +01001153 }
1154
David Srbeckybd613ec2019-05-30 15:39:38 +01001155 ALWAYS_INLINE bool APUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001156 return HandleAPut<mirror::BooleanArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +01001157 }
1158
David Srbeckybd613ec2019-05-30 15:39:38 +01001159 ALWAYS_INLINE bool APUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001160 return HandleAPut<mirror::ByteArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +01001161 }
1162
David Srbeckybd613ec2019-05-30 15:39:38 +01001163 ALWAYS_INLINE bool APUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001164 return HandleAPut<mirror::CharArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +01001165 }
1166
David Srbeckybd613ec2019-05-30 15:39:38 +01001167 ALWAYS_INLINE bool APUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001168 return HandleAPut<mirror::ShortArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +01001169 }
1170
David Srbeckybd613ec2019-05-30 15:39:38 +01001171 ALWAYS_INLINE bool APUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001172 return HandleAPut<mirror::IntArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +01001173 }
1174
David Srbeckybd613ec2019-05-30 15:39:38 +01001175 ALWAYS_INLINE bool APUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +01001176 return HandleAPut<mirror::LongArray>(GetVRegLong(A()));
David Srbecky6da82472018-10-23 14:03:08 +01001177 }
1178
David Srbeckybd613ec2019-05-30 15:39:38 +01001179 ALWAYS_INLINE bool APUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001180 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001181 if (UNLIKELY(a == nullptr)) {
1182 ThrowNullPointerExceptionFromInterpreter();
1183 HANDLE_PENDING_EXCEPTION();
1184 }
David Srbecky6baf6442019-05-30 14:57:43 +01001185 int32_t index = GetVReg(C());
1186 ObjPtr<mirror::Object> val = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +01001187 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
1188 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
1189 array->SetWithoutChecks<transaction_active>(index, val);
1190 inst = inst->Next_2xx();
1191 } else {
1192 HANDLE_PENDING_EXCEPTION();
1193 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001194 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001195 }
1196
David Srbeckybd613ec2019-05-30 15:39:38 +01001197 ALWAYS_INLINE bool IGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001198 return HandleGet<InstancePrimitiveRead, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001199 }
1200
David Srbeckybd613ec2019-05-30 15:39:38 +01001201 ALWAYS_INLINE bool IGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001202 return HandleGet<InstancePrimitiveRead, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001203 }
1204
David Srbeckybd613ec2019-05-30 15:39:38 +01001205 ALWAYS_INLINE bool IGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001206 return HandleGet<InstancePrimitiveRead, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001207 }
1208
David Srbeckybd613ec2019-05-30 15:39:38 +01001209 ALWAYS_INLINE bool IGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001210 return HandleGet<InstancePrimitiveRead, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001211 }
1212
David Srbeckybd613ec2019-05-30 15:39:38 +01001213 ALWAYS_INLINE bool IGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001214 return HandleGet<InstancePrimitiveRead, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001215 }
1216
David Srbeckybd613ec2019-05-30 15:39:38 +01001217 ALWAYS_INLINE bool IGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001218 return HandleGet<InstancePrimitiveRead, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001219 }
1220
David Srbeckybd613ec2019-05-30 15:39:38 +01001221 ALWAYS_INLINE bool IGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001222 return HandleGet<InstanceObjectRead, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001223 }
1224
David Srbeckybd613ec2019-05-30 15:39:38 +01001225 ALWAYS_INLINE bool IGET_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001226 return HandleGetQuick<Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001227 }
1228
David Srbeckybd613ec2019-05-30 15:39:38 +01001229 ALWAYS_INLINE bool IGET_WIDE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001230 return HandleGetQuick<Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001231 }
1232
David Srbeckybd613ec2019-05-30 15:39:38 +01001233 ALWAYS_INLINE bool IGET_OBJECT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001234 return HandleGetQuick<Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001235 }
1236
David Srbeckybd613ec2019-05-30 15:39:38 +01001237 ALWAYS_INLINE bool IGET_BOOLEAN_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001238 return HandleGetQuick<Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001239 }
1240
David Srbeckybd613ec2019-05-30 15:39:38 +01001241 ALWAYS_INLINE bool IGET_BYTE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001242 return HandleGetQuick<Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001243 }
1244
David Srbeckybd613ec2019-05-30 15:39:38 +01001245 ALWAYS_INLINE bool IGET_CHAR_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001246 return HandleGetQuick<Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001247 }
1248
David Srbeckybd613ec2019-05-30 15:39:38 +01001249 ALWAYS_INLINE bool IGET_SHORT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001250 return HandleGetQuick<Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001251 }
1252
David Srbeckybd613ec2019-05-30 15:39:38 +01001253 ALWAYS_INLINE bool SGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001254 return HandleGet<StaticPrimitiveRead, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001255 }
1256
David Srbeckybd613ec2019-05-30 15:39:38 +01001257 ALWAYS_INLINE bool SGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001258 return HandleGet<StaticPrimitiveRead, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001259 }
1260
David Srbeckybd613ec2019-05-30 15:39:38 +01001261 ALWAYS_INLINE bool SGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001262 return HandleGet<StaticPrimitiveRead, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001263 }
1264
David Srbeckybd613ec2019-05-30 15:39:38 +01001265 ALWAYS_INLINE bool SGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001266 return HandleGet<StaticPrimitiveRead, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001267 }
1268
David Srbeckybd613ec2019-05-30 15:39:38 +01001269 ALWAYS_INLINE bool SGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001270 return HandleGet<StaticPrimitiveRead, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001271 }
1272
David Srbeckybd613ec2019-05-30 15:39:38 +01001273 ALWAYS_INLINE bool SGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001274 return HandleGet<StaticPrimitiveRead, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001275 }
1276
David Srbeckybd613ec2019-05-30 15:39:38 +01001277 ALWAYS_INLINE bool SGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001278 return HandleGet<StaticObjectRead, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001279 }
1280
David Srbeckybd613ec2019-05-30 15:39:38 +01001281 ALWAYS_INLINE bool IPUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001282 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001283 }
1284
David Srbeckybd613ec2019-05-30 15:39:38 +01001285 ALWAYS_INLINE bool IPUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001286 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001287 }
1288
David Srbeckybd613ec2019-05-30 15:39:38 +01001289 ALWAYS_INLINE bool IPUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001290 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001291 }
1292
David Srbeckybd613ec2019-05-30 15:39:38 +01001293 ALWAYS_INLINE bool IPUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001294 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001295 }
1296
David Srbeckybd613ec2019-05-30 15:39:38 +01001297 ALWAYS_INLINE bool IPUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001298 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001299 }
1300
David Srbeckybd613ec2019-05-30 15:39:38 +01001301 ALWAYS_INLINE bool IPUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001302 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001303 }
1304
David Srbeckybd613ec2019-05-30 15:39:38 +01001305 ALWAYS_INLINE bool IPUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001306 return HandlePut<InstanceObjectWrite, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001307 }
1308
David Srbeckybd613ec2019-05-30 15:39:38 +01001309 ALWAYS_INLINE bool IPUT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001310 return HandlePutQuick<Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001311 }
1312
David Srbeckybd613ec2019-05-30 15:39:38 +01001313 ALWAYS_INLINE bool IPUT_BOOLEAN_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001314 return HandlePutQuick<Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001315 }
1316
David Srbeckybd613ec2019-05-30 15:39:38 +01001317 ALWAYS_INLINE bool IPUT_BYTE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001318 return HandlePutQuick<Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001319 }
1320
David Srbeckybd613ec2019-05-30 15:39:38 +01001321 ALWAYS_INLINE bool IPUT_CHAR_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001322 return HandlePutQuick<Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001323 }
1324
David Srbeckybd613ec2019-05-30 15:39:38 +01001325 ALWAYS_INLINE bool IPUT_SHORT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001326 return HandlePutQuick<Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001327 }
1328
David Srbeckybd613ec2019-05-30 15:39:38 +01001329 ALWAYS_INLINE bool IPUT_WIDE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001330 return HandlePutQuick<Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001331 }
1332
David Srbeckybd613ec2019-05-30 15:39:38 +01001333 ALWAYS_INLINE bool IPUT_OBJECT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001334 return HandlePutQuick<Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001335 }
1336
David Srbeckybd613ec2019-05-30 15:39:38 +01001337 ALWAYS_INLINE bool SPUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001338 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001339 }
1340
David Srbeckybd613ec2019-05-30 15:39:38 +01001341 ALWAYS_INLINE bool SPUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001342 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001343 }
1344
David Srbeckybd613ec2019-05-30 15:39:38 +01001345 ALWAYS_INLINE bool SPUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001346 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001347 }
1348
David Srbeckybd613ec2019-05-30 15:39:38 +01001349 ALWAYS_INLINE bool SPUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001350 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001351 }
1352
David Srbeckybd613ec2019-05-30 15:39:38 +01001353 ALWAYS_INLINE bool SPUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001354 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001355 }
1356
David Srbeckybd613ec2019-05-30 15:39:38 +01001357 ALWAYS_INLINE bool SPUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001358 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001359 }
1360
David Srbeckybd613ec2019-05-30 15:39:38 +01001361 ALWAYS_INLINE bool SPUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001362 return HandlePut<StaticObjectWrite, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001363 }
1364
David Srbeckybd613ec2019-05-30 15:39:38 +01001365 ALWAYS_INLINE bool INVOKE_VIRTUAL() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001366 return HandleInvoke<kVirtual, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001367 }
1368
David Srbeckybd613ec2019-05-30 15:39:38 +01001369 ALWAYS_INLINE bool INVOKE_VIRTUAL_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001370 return HandleInvoke<kVirtual, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001371 }
1372
David Srbeckybd613ec2019-05-30 15:39:38 +01001373 ALWAYS_INLINE bool INVOKE_SUPER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001374 return HandleInvoke<kSuper, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001375 }
1376
David Srbeckybd613ec2019-05-30 15:39:38 +01001377 ALWAYS_INLINE bool INVOKE_SUPER_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001378 return HandleInvoke<kSuper, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001379 }
1380
David Srbeckybd613ec2019-05-30 15:39:38 +01001381 ALWAYS_INLINE bool INVOKE_DIRECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001382 return HandleInvoke<kDirect, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001383 }
1384
David Srbeckybd613ec2019-05-30 15:39:38 +01001385 ALWAYS_INLINE bool INVOKE_DIRECT_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001386 return HandleInvoke<kDirect, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001387 }
1388
David Srbeckybd613ec2019-05-30 15:39:38 +01001389 ALWAYS_INLINE bool INVOKE_INTERFACE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001390 return HandleInvoke<kInterface, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001391 }
1392
David Srbeckybd613ec2019-05-30 15:39:38 +01001393 ALWAYS_INLINE bool INVOKE_INTERFACE_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001394 return HandleInvoke<kInterface, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001395 }
1396
David Srbeckybd613ec2019-05-30 15:39:38 +01001397 ALWAYS_INLINE bool INVOKE_STATIC() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001398 return HandleInvoke<kStatic, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001399 }
1400
David Srbeckybd613ec2019-05-30 15:39:38 +01001401 ALWAYS_INLINE bool INVOKE_STATIC_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001402 return HandleInvoke<kStatic, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001403 }
1404
David Srbeckybd613ec2019-05-30 15:39:38 +01001405 ALWAYS_INLINE bool INVOKE_VIRTUAL_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001406 return HandleInvoke<kVirtual, /*is_range=*/ false, /*is_quick=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001407 }
1408
David Srbeckybd613ec2019-05-30 15:39:38 +01001409 ALWAYS_INLINE bool INVOKE_VIRTUAL_RANGE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001410 return HandleInvoke<kVirtual, /*is_range=*/ true, /*is_quick=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001411 }
1412
David Srbeckybd613ec2019-05-30 15:39:38 +01001413 ALWAYS_INLINE bool INVOKE_POLYMORPHIC() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001414 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1415 bool success = DoInvokePolymorphic</* is_range= */ false>(
1416 self, shadow_frame, inst, inst_data, ResultRegister());
1417 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001418 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001419 }
1420
David Srbeckybd613ec2019-05-30 15:39:38 +01001421 ALWAYS_INLINE bool INVOKE_POLYMORPHIC_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001422 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1423 bool success = DoInvokePolymorphic</* is_range= */ true>(
1424 self, shadow_frame, inst, inst_data, ResultRegister());
1425 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001426 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001427 }
1428
David Srbeckybd613ec2019-05-30 15:39:38 +01001429 ALWAYS_INLINE bool INVOKE_CUSTOM() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001430 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1431 bool success = DoInvokeCustom</* is_range= */ false>(
1432 self, shadow_frame, inst, inst_data, ResultRegister());
1433 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
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 INVOKE_CUSTOM_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001438 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1439 bool success = DoInvokeCustom</* is_range= */ true>(
1440 self, shadow_frame, inst, inst_data, ResultRegister());
1441 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001442 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001443 }
1444
David Srbeckybd613ec2019-05-30 15:39:38 +01001445 ALWAYS_INLINE bool NEG_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001446 SetVReg(A(), -GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001447 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001448 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001449 }
1450
David Srbeckybd613ec2019-05-30 15:39:38 +01001451 ALWAYS_INLINE bool NOT_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001452 SetVReg(A(), ~GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001453 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001454 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001455 }
1456
David Srbeckybd613ec2019-05-30 15:39:38 +01001457 ALWAYS_INLINE bool NEG_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001458 SetVRegLong(A(), -GetVRegLong(B()));
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 NOT_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001464 SetVRegLong(A(), ~GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001465 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001466 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001467 }
1468
David Srbeckybd613ec2019-05-30 15:39:38 +01001469 ALWAYS_INLINE bool NEG_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001470 SetVRegFloat(A(), -GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001471 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001472 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001473 }
1474
David Srbeckybd613ec2019-05-30 15:39:38 +01001475 ALWAYS_INLINE bool NEG_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001476 SetVRegDouble(A(), -GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001477 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001478 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001479 }
1480
David Srbeckybd613ec2019-05-30 15:39:38 +01001481 ALWAYS_INLINE bool INT_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001482 SetVRegLong(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001483 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001484 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001485 }
1486
David Srbeckybd613ec2019-05-30 15:39:38 +01001487 ALWAYS_INLINE bool INT_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001488 SetVRegFloat(A(), GetVReg(B()));
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 INT_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001494 SetVRegDouble(A(), GetVReg(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 LONG_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001500 SetVReg(A(), GetVRegLong(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 LONG_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001506 SetVRegFloat(A(), GetVRegLong(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 LONG_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001512 SetVRegDouble(A(), GetVRegLong(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 FLOAT_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001518 float val = GetVRegFloat(B());
David Srbecky6da82472018-10-23 14:03:08 +01001519 int32_t result = art_float_to_integral<int32_t, float>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001520 SetVReg(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001521 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001522 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001523 }
1524
David Srbeckybd613ec2019-05-30 15:39:38 +01001525 ALWAYS_INLINE bool FLOAT_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001526 float val = GetVRegFloat(B());
David Srbecky6da82472018-10-23 14:03:08 +01001527 int64_t result = art_float_to_integral<int64_t, float>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001528 SetVRegLong(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001529 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001530 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001531 }
1532
David Srbeckybd613ec2019-05-30 15:39:38 +01001533 ALWAYS_INLINE bool FLOAT_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001534 SetVRegDouble(A(), GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001535 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001536 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001537 }
1538
David Srbeckybd613ec2019-05-30 15:39:38 +01001539 ALWAYS_INLINE bool DOUBLE_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001540 double val = GetVRegDouble(B());
David Srbecky6da82472018-10-23 14:03:08 +01001541 int32_t result = art_float_to_integral<int32_t, double>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001542 SetVReg(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001543 inst = inst->Next_1xx();
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 DOUBLE_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001548 double val = GetVRegDouble(B());
David Srbecky6da82472018-10-23 14:03:08 +01001549 int64_t result = art_float_to_integral<int64_t, double>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001550 SetVRegLong(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001551 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001552 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001553 }
1554
David Srbeckybd613ec2019-05-30 15:39:38 +01001555 ALWAYS_INLINE bool DOUBLE_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001556 SetVRegFloat(A(), GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001557 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001558 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001559 }
1560
David Srbeckybd613ec2019-05-30 15:39:38 +01001561 ALWAYS_INLINE bool INT_TO_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001562 SetVReg(A(), static_cast<int8_t>(GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001563 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001564 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001565 }
1566
David Srbeckybd613ec2019-05-30 15:39:38 +01001567 ALWAYS_INLINE bool INT_TO_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001568 SetVReg(A(), static_cast<uint16_t>(GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001569 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001570 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001571 }
1572
David Srbeckybd613ec2019-05-30 15:39:38 +01001573 ALWAYS_INLINE bool INT_TO_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001574 SetVReg(A(), static_cast<int16_t>(GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001575 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001576 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001577 }
1578
David Srbeckybd613ec2019-05-30 15:39:38 +01001579 ALWAYS_INLINE bool ADD_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001580 SetVReg(A(), SafeAdd(GetVReg(B()), GetVReg(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001581 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001582 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001583 }
1584
David Srbeckybd613ec2019-05-30 15:39:38 +01001585 ALWAYS_INLINE bool SUB_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001586 SetVReg(A(), SafeSub(GetVReg(B()), GetVReg(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001587 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001588 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001589 }
1590
David Srbeckybd613ec2019-05-30 15:39:38 +01001591 ALWAYS_INLINE bool MUL_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001592 SetVReg(A(), SafeMul(GetVReg(B()), GetVReg(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001593 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001594 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001595 }
1596
David Srbeckybd613ec2019-05-30 15:39:38 +01001597 ALWAYS_INLINE bool DIV_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001598 bool success = DoIntDivide(shadow_frame, A(), GetVReg(B()), GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001599 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001600 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001601 }
1602
David Srbeckybd613ec2019-05-30 15:39:38 +01001603 ALWAYS_INLINE bool REM_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001604 bool success = DoIntRemainder(shadow_frame, A(), GetVReg(B()), GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001605 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001606 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001607 }
1608
David Srbeckybd613ec2019-05-30 15:39:38 +01001609 ALWAYS_INLINE bool SHL_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001610 SetVReg(A(), GetVReg(B()) << (GetVReg(C()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001611 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001612 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001613 }
1614
David Srbeckybd613ec2019-05-30 15:39:38 +01001615 ALWAYS_INLINE bool SHR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001616 SetVReg(A(), GetVReg(B()) >> (GetVReg(C()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001617 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001618 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001619 }
1620
David Srbeckybd613ec2019-05-30 15:39:38 +01001621 ALWAYS_INLINE bool USHR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001622 SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (GetVReg(C()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001623 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001624 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001625 }
1626
David Srbeckybd613ec2019-05-30 15:39:38 +01001627 ALWAYS_INLINE bool AND_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001628 SetVReg(A(), GetVReg(B()) & GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001629 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001630 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001631 }
1632
David Srbeckybd613ec2019-05-30 15:39:38 +01001633 ALWAYS_INLINE bool OR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001634 SetVReg(A(), GetVReg(B()) | GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001635 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001636 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001637 }
1638
David Srbeckybd613ec2019-05-30 15:39:38 +01001639 ALWAYS_INLINE bool XOR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001640 SetVReg(A(), GetVReg(B()) ^ GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001641 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001642 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001643 }
1644
David Srbeckybd613ec2019-05-30 15:39:38 +01001645 ALWAYS_INLINE bool ADD_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001646 SetVRegLong(A(), SafeAdd(GetVRegLong(B()), GetVRegLong(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001647 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001648 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001649 }
1650
David Srbeckybd613ec2019-05-30 15:39:38 +01001651 ALWAYS_INLINE bool SUB_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001652 SetVRegLong(A(), SafeSub(GetVRegLong(B()), GetVRegLong(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001653 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001654 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001655 }
1656
David Srbeckybd613ec2019-05-30 15:39:38 +01001657 ALWAYS_INLINE bool MUL_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001658 SetVRegLong(A(), SafeMul(GetVRegLong(B()), GetVRegLong(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001659 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001660 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001661 }
1662
David Srbeckybd613ec2019-05-30 15:39:38 +01001663 ALWAYS_INLINE bool DIV_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001664 DoLongDivide(shadow_frame, A(), GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001665 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001666 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001667 }
1668
David Srbeckybd613ec2019-05-30 15:39:38 +01001669 ALWAYS_INLINE bool REM_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001670 DoLongRemainder(shadow_frame, A(), GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001671 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001672 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001673 }
1674
David Srbeckybd613ec2019-05-30 15:39:38 +01001675 ALWAYS_INLINE bool AND_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001676 SetVRegLong(A(), GetVRegLong(B()) & GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001677 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001678 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001679 }
1680
David Srbeckybd613ec2019-05-30 15:39:38 +01001681 ALWAYS_INLINE bool OR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001682 SetVRegLong(A(), GetVRegLong(B()) | GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001683 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001684 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001685 }
1686
David Srbeckybd613ec2019-05-30 15:39:38 +01001687 ALWAYS_INLINE bool XOR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001688 SetVRegLong(A(), GetVRegLong(B()) ^ GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001689 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001690 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001691 }
1692
David Srbeckybd613ec2019-05-30 15:39:38 +01001693 ALWAYS_INLINE bool SHL_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001694 SetVRegLong(A(), GetVRegLong(B()) << (GetVReg(C()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001695 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001696 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001697 }
1698
David Srbeckybd613ec2019-05-30 15:39:38 +01001699 ALWAYS_INLINE bool SHR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001700 SetVRegLong(A(), GetVRegLong(B()) >> (GetVReg(C()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001701 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001702 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001703 }
1704
David Srbeckybd613ec2019-05-30 15:39:38 +01001705 ALWAYS_INLINE bool USHR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001706 SetVRegLong(A(), static_cast<uint64_t>(GetVRegLong(B())) >> (GetVReg(C()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001707 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001708 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001709 }
1710
David Srbeckybd613ec2019-05-30 15:39:38 +01001711 ALWAYS_INLINE bool ADD_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001712 SetVRegFloat(A(), GetVRegFloat(B()) + GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001713 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001714 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001715 }
1716
David Srbeckybd613ec2019-05-30 15:39:38 +01001717 ALWAYS_INLINE bool SUB_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001718 SetVRegFloat(A(), GetVRegFloat(B()) - GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001719 inst = inst->Next_2xx();
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_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001724 SetVRegFloat(A(), GetVRegFloat(B()) * GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001725 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001726 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001727 }
1728
David Srbeckybd613ec2019-05-30 15:39:38 +01001729 ALWAYS_INLINE bool DIV_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001730 SetVRegFloat(A(), GetVRegFloat(B()) / GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001731 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001732 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001733 }
1734
David Srbeckybd613ec2019-05-30 15:39:38 +01001735 ALWAYS_INLINE bool REM_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001736 SetVRegFloat(A(), fmodf(GetVRegFloat(B()), GetVRegFloat(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001737 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001738 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001739 }
1740
David Srbeckybd613ec2019-05-30 15:39:38 +01001741 ALWAYS_INLINE bool ADD_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001742 SetVRegDouble(A(), GetVRegDouble(B()) + GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001743 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001744 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001745 }
1746
David Srbeckybd613ec2019-05-30 15:39:38 +01001747 ALWAYS_INLINE bool SUB_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001748 SetVRegDouble(A(), GetVRegDouble(B()) - GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001749 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001750 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001751 }
1752
David Srbeckybd613ec2019-05-30 15:39:38 +01001753 ALWAYS_INLINE bool MUL_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001754 SetVRegDouble(A(), GetVRegDouble(B()) * GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001755 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001756 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001757 }
1758
David Srbeckybd613ec2019-05-30 15:39:38 +01001759 ALWAYS_INLINE bool DIV_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001760 SetVRegDouble(A(), GetVRegDouble(B()) / GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001761 inst = inst->Next_2xx();
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 REM_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001766 SetVRegDouble(A(), fmod(GetVRegDouble(B()), GetVRegDouble(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001767 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001768 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001769 }
1770
David Srbeckybd613ec2019-05-30 15:39:38 +01001771 ALWAYS_INLINE bool ADD_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001772 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001773 SetVReg(vregA, SafeAdd(GetVReg(vregA), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001774 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001775 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001776 }
1777
David Srbeckybd613ec2019-05-30 15:39:38 +01001778 ALWAYS_INLINE bool SUB_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001779 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001780 SetVReg(vregA, SafeSub(GetVReg(vregA), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001781 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001782 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001783 }
1784
David Srbeckybd613ec2019-05-30 15:39:38 +01001785 ALWAYS_INLINE bool MUL_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001786 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001787 SetVReg(vregA, SafeMul(GetVReg(vregA), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001788 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001789 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001790 }
1791
David Srbeckybd613ec2019-05-30 15:39:38 +01001792 ALWAYS_INLINE bool DIV_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001793 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001794 bool success = DoIntDivide(shadow_frame, vregA, GetVReg(vregA), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001795 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001796 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001797 }
1798
David Srbeckybd613ec2019-05-30 15:39:38 +01001799 ALWAYS_INLINE bool REM_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001800 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001801 bool success = DoIntRemainder(shadow_frame, vregA, GetVReg(vregA), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001802 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001803 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001804 }
1805
David Srbeckybd613ec2019-05-30 15:39:38 +01001806 ALWAYS_INLINE bool SHL_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001807 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001808 SetVReg(vregA, GetVReg(vregA) << (GetVReg(B()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001809 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001810 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001811 }
1812
David Srbeckybd613ec2019-05-30 15:39:38 +01001813 ALWAYS_INLINE bool SHR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001814 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001815 SetVReg(vregA, GetVReg(vregA) >> (GetVReg(B()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001816 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001817 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001818 }
1819
David Srbeckybd613ec2019-05-30 15:39:38 +01001820 ALWAYS_INLINE bool USHR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001821 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001822 SetVReg(vregA, static_cast<uint32_t>(GetVReg(vregA)) >> (GetVReg(B()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001823 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001824 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001825 }
1826
David Srbeckybd613ec2019-05-30 15:39:38 +01001827 ALWAYS_INLINE bool AND_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001828 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001829 SetVReg(vregA, GetVReg(vregA) & GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001830 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001831 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001832 }
1833
David Srbeckybd613ec2019-05-30 15:39:38 +01001834 ALWAYS_INLINE bool OR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001835 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001836 SetVReg(vregA, GetVReg(vregA) | GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001837 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001838 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001839 }
1840
David Srbeckybd613ec2019-05-30 15:39:38 +01001841 ALWAYS_INLINE bool XOR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001842 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001843 SetVReg(vregA, GetVReg(vregA) ^ GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001844 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001845 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001846 }
1847
David Srbeckybd613ec2019-05-30 15:39:38 +01001848 ALWAYS_INLINE bool ADD_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001849 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001850 SetVRegLong(vregA, SafeAdd(GetVRegLong(vregA), GetVRegLong(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001851 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001852 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001853 }
1854
David Srbeckybd613ec2019-05-30 15:39:38 +01001855 ALWAYS_INLINE bool SUB_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001856 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001857 SetVRegLong(vregA, SafeSub(GetVRegLong(vregA), GetVRegLong(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001858 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001859 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001860 }
1861
David Srbeckybd613ec2019-05-30 15:39:38 +01001862 ALWAYS_INLINE bool MUL_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001863 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001864 SetVRegLong(vregA, SafeMul(GetVRegLong(vregA), GetVRegLong(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001865 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001866 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001867 }
1868
David Srbeckybd613ec2019-05-30 15:39:38 +01001869 ALWAYS_INLINE bool DIV_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001870 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001871 DoLongDivide(shadow_frame, vregA, GetVRegLong(vregA), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001872 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001873 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001874 }
1875
David Srbeckybd613ec2019-05-30 15:39:38 +01001876 ALWAYS_INLINE bool REM_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001877 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001878 DoLongRemainder(shadow_frame, vregA, GetVRegLong(vregA), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001879 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001880 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001881 }
1882
David Srbeckybd613ec2019-05-30 15:39:38 +01001883 ALWAYS_INLINE bool AND_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001884 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001885 SetVRegLong(vregA, GetVRegLong(vregA) & GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001886 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001887 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001888 }
1889
David Srbeckybd613ec2019-05-30 15:39:38 +01001890 ALWAYS_INLINE bool OR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001891 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001892 SetVRegLong(vregA, GetVRegLong(vregA) | GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001893 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001894 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001895 }
1896
David Srbeckybd613ec2019-05-30 15:39:38 +01001897 ALWAYS_INLINE bool XOR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001898 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001899 SetVRegLong(vregA, GetVRegLong(vregA) ^ GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001900 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001901 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001902 }
1903
David Srbeckybd613ec2019-05-30 15:39:38 +01001904 ALWAYS_INLINE bool SHL_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001905 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001906 SetVRegLong(vregA, GetVRegLong(vregA) << (GetVReg(B()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001907 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001908 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001909 }
1910
David Srbeckybd613ec2019-05-30 15:39:38 +01001911 ALWAYS_INLINE bool SHR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001912 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001913 SetVRegLong(vregA, GetVRegLong(vregA) >> (GetVReg(B()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001914 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001915 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001916 }
1917
David Srbeckybd613ec2019-05-30 15:39:38 +01001918 ALWAYS_INLINE bool USHR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001919 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001920 SetVRegLong(vregA, static_cast<uint64_t>(GetVRegLong(vregA)) >> (GetVReg(B()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001921 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001922 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001923 }
1924
David Srbeckybd613ec2019-05-30 15:39:38 +01001925 ALWAYS_INLINE bool ADD_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001926 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001927 SetVRegFloat(vregA, GetVRegFloat(vregA) + GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001928 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001929 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001930 }
1931
David Srbeckybd613ec2019-05-30 15:39:38 +01001932 ALWAYS_INLINE bool SUB_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001933 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001934 SetVRegFloat(vregA, GetVRegFloat(vregA) - GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001935 inst = inst->Next_1xx();
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 MUL_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001940 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001941 SetVRegFloat(vregA, GetVRegFloat(vregA) * GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001942 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001943 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001944 }
1945
David Srbeckybd613ec2019-05-30 15:39:38 +01001946 ALWAYS_INLINE bool DIV_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001947 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001948 SetVRegFloat(vregA, GetVRegFloat(vregA) / GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001949 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001950 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001951 }
1952
David Srbeckybd613ec2019-05-30 15:39:38 +01001953 ALWAYS_INLINE bool REM_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001954 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001955 SetVRegFloat(vregA, fmodf(GetVRegFloat(vregA), GetVRegFloat(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001956 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001957 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001958 }
1959
David Srbeckybd613ec2019-05-30 15:39:38 +01001960 ALWAYS_INLINE bool ADD_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001961 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001962 SetVRegDouble(vregA, GetVRegDouble(vregA) + GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001963 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001964 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001965 }
1966
David Srbeckybd613ec2019-05-30 15:39:38 +01001967 ALWAYS_INLINE bool SUB_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001968 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001969 SetVRegDouble(vregA, GetVRegDouble(vregA) - GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001970 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001971 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001972 }
1973
David Srbeckybd613ec2019-05-30 15:39:38 +01001974 ALWAYS_INLINE bool MUL_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001975 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001976 SetVRegDouble(vregA, GetVRegDouble(vregA) * GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001977 inst = inst->Next_1xx();
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 DIV_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001982 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001983 SetVRegDouble(vregA, GetVRegDouble(vregA) / GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001984 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001985 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001986 }
1987
David Srbeckybd613ec2019-05-30 15:39:38 +01001988 ALWAYS_INLINE bool REM_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001989 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001990 SetVRegDouble(vregA, fmod(GetVRegDouble(vregA), GetVRegDouble(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001991 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001992 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001993 }
1994
David Srbeckybd613ec2019-05-30 15:39:38 +01001995 ALWAYS_INLINE bool ADD_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001996 SetVReg(A(), SafeAdd(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01001997 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001998 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001999 }
2000
David Srbeckybd613ec2019-05-30 15:39:38 +01002001 ALWAYS_INLINE bool RSUB_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002002 SetVReg(A(), SafeSub(C(), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002003 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002004 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002005 }
2006
David Srbeckybd613ec2019-05-30 15:39:38 +01002007 ALWAYS_INLINE bool MUL_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002008 SetVReg(A(), SafeMul(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01002009 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002010 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002011 }
2012
David Srbeckybd613ec2019-05-30 15:39:38 +01002013 ALWAYS_INLINE bool DIV_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002014 bool success = DoIntDivide(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01002015 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002016 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002017 }
2018
David Srbeckybd613ec2019-05-30 15:39:38 +01002019 ALWAYS_INLINE bool REM_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002020 bool success = DoIntRemainder(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01002021 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002022 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002023 }
2024
David Srbeckybd613ec2019-05-30 15:39:38 +01002025 ALWAYS_INLINE bool AND_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002026 SetVReg(A(), GetVReg(B()) & C());
David Srbecky6da82472018-10-23 14:03:08 +01002027 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002028 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002029 }
2030
David Srbeckybd613ec2019-05-30 15:39:38 +01002031 ALWAYS_INLINE bool OR_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002032 SetVReg(A(), GetVReg(B()) | C());
David Srbecky6da82472018-10-23 14:03:08 +01002033 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002034 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002035 }
2036
David Srbeckybd613ec2019-05-30 15:39:38 +01002037 ALWAYS_INLINE bool XOR_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002038 SetVReg(A(), GetVReg(B()) ^ C());
David Srbecky6da82472018-10-23 14:03:08 +01002039 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002040 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002041 }
2042
David Srbeckybd613ec2019-05-30 15:39:38 +01002043 ALWAYS_INLINE bool ADD_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002044 SetVReg(A(), SafeAdd(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01002045 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002046 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002047 }
2048
David Srbeckybd613ec2019-05-30 15:39:38 +01002049 ALWAYS_INLINE bool RSUB_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002050 SetVReg(A(), SafeSub(C(), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002051 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002052 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002053 }
2054
David Srbeckybd613ec2019-05-30 15:39:38 +01002055 ALWAYS_INLINE bool MUL_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002056 SetVReg(A(), SafeMul(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01002057 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002058 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002059 }
2060
David Srbeckybd613ec2019-05-30 15:39:38 +01002061 ALWAYS_INLINE bool DIV_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002062 bool success = DoIntDivide(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01002063 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002064 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002065 }
2066
David Srbeckybd613ec2019-05-30 15:39:38 +01002067 ALWAYS_INLINE bool REM_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002068 bool success = DoIntRemainder(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01002069 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002070 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002071 }
2072
David Srbeckybd613ec2019-05-30 15:39:38 +01002073 ALWAYS_INLINE bool AND_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002074 SetVReg(A(), GetVReg(B()) & C());
David Srbecky6da82472018-10-23 14:03:08 +01002075 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002076 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002077 }
2078
David Srbeckybd613ec2019-05-30 15:39:38 +01002079 ALWAYS_INLINE bool OR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002080 SetVReg(A(), GetVReg(B()) | C());
David Srbecky6da82472018-10-23 14:03:08 +01002081 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002082 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002083 }
2084
David Srbeckybd613ec2019-05-30 15:39:38 +01002085 ALWAYS_INLINE bool XOR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002086 SetVReg(A(), GetVReg(B()) ^ C());
David Srbecky6da82472018-10-23 14:03:08 +01002087 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002088 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002089 }
2090
David Srbeckybd613ec2019-05-30 15:39:38 +01002091 ALWAYS_INLINE bool SHL_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002092 SetVReg(A(), GetVReg(B()) << (C() & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002093 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002094 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002095 }
2096
David Srbeckybd613ec2019-05-30 15:39:38 +01002097 ALWAYS_INLINE bool SHR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002098 SetVReg(A(), GetVReg(B()) >> (C() & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002099 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002100 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002101 }
2102
David Srbeckybd613ec2019-05-30 15:39:38 +01002103 ALWAYS_INLINE bool USHR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002104 SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (C() & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002105 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002106 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002107 }
2108
David Srbeckybd613ec2019-05-30 15:39:38 +01002109 ALWAYS_INLINE bool UNUSED_3E() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002110 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002111 }
2112
David Srbeckybd613ec2019-05-30 15:39:38 +01002113 ALWAYS_INLINE bool UNUSED_3F() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002114 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002115 }
2116
David Srbeckybd613ec2019-05-30 15:39:38 +01002117 ALWAYS_INLINE bool UNUSED_40() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002118 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002119 }
2120
David Srbeckybd613ec2019-05-30 15:39:38 +01002121 ALWAYS_INLINE bool UNUSED_41() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002122 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002123 }
2124
David Srbeckybd613ec2019-05-30 15:39:38 +01002125 ALWAYS_INLINE bool UNUSED_42() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002126 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002127 }
2128
David Srbeckybd613ec2019-05-30 15:39:38 +01002129 ALWAYS_INLINE bool UNUSED_43() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002130 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002131 }
2132
David Srbeckybd613ec2019-05-30 15:39:38 +01002133 ALWAYS_INLINE bool UNUSED_79() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002134 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002135 }
2136
David Srbeckybd613ec2019-05-30 15:39:38 +01002137 ALWAYS_INLINE bool UNUSED_7A() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002138 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002139 }
2140
David Srbeckybd613ec2019-05-30 15:39:38 +01002141 ALWAYS_INLINE bool UNUSED_F3() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002142 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002143 }
2144
David Srbeckybd613ec2019-05-30 15:39:38 +01002145 ALWAYS_INLINE bool UNUSED_F4() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002146 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002147 }
2148
David Srbeckybd613ec2019-05-30 15:39:38 +01002149 ALWAYS_INLINE bool UNUSED_F5() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002150 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002151 }
2152
David Srbeckybd613ec2019-05-30 15:39:38 +01002153 ALWAYS_INLINE bool UNUSED_F6() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002154 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002155 }
2156
David Srbeckybd613ec2019-05-30 15:39:38 +01002157 ALWAYS_INLINE bool UNUSED_F7() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002158 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002159 }
2160
David Srbeckybd613ec2019-05-30 15:39:38 +01002161 ALWAYS_INLINE bool UNUSED_F8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002162 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002163 }
2164
David Srbeckybd613ec2019-05-30 15:39:38 +01002165 ALWAYS_INLINE bool UNUSED_F9() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002166 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002167 }
2168
2169 ALWAYS_INLINE InstructionHandler(SwitchImplContext* ctx,
2170 const instrumentation::Instrumentation* instrumentation,
2171 Thread* self,
2172 ShadowFrame& shadow_frame,
2173 uint16_t dex_pc,
2174 const Instruction*& inst,
2175 uint16_t inst_data,
2176 bool& exit_interpreter_loop)
2177 : ctx(ctx),
2178 instrumentation(instrumentation),
2179 self(self),
2180 shadow_frame(shadow_frame),
2181 dex_pc(dex_pc),
2182 inst(inst),
2183 inst_data(inst_data),
2184 exit_interpreter_loop(exit_interpreter_loop) {
2185 }
2186
2187 private:
2188 static constexpr bool do_assignability_check = do_access_check;
2189
2190 const CodeItemDataAccessor& Accessor() { return ctx->accessor; }
2191 const uint16_t* Insns() { return ctx->accessor.Insns(); }
2192 JValue* ResultRegister() { return &ctx->result_register; }
2193
David Srbecky436f6c12019-05-22 13:28:42 +01002194 ALWAYS_INLINE int32_t A() { return inst->VRegA(kFormat, inst_data); }
2195 ALWAYS_INLINE int32_t B() { return inst->VRegB(kFormat, inst_data); }
2196 ALWAYS_INLINE int32_t C() { return inst->VRegC(kFormat); }
2197
David Srbecky6baf6442019-05-30 14:57:43 +01002198 int32_t GetVReg(size_t i) const { return shadow_frame.GetVReg(i); }
2199 int64_t GetVRegLong(size_t i) const { return shadow_frame.GetVRegLong(i); }
2200 float GetVRegFloat(size_t i) const { return shadow_frame.GetVRegFloat(i); }
2201 double GetVRegDouble(size_t i) const { return shadow_frame.GetVRegDouble(i); }
2202 ObjPtr<mirror::Object> GetVRegReference(size_t i) const REQUIRES_SHARED(Locks::mutator_lock_) {
2203 return shadow_frame.GetVRegReference(i);
2204 }
2205
2206 void SetVReg(size_t i, int32_t val) { shadow_frame.SetVReg(i, val); }
2207 void SetVRegLong(size_t i, int64_t val) { shadow_frame.SetVRegLong(i, val); }
2208 void SetVRegFloat(size_t i, float val) { shadow_frame.SetVRegFloat(i, val); }
2209 void SetVRegDouble(size_t i, double val) { shadow_frame.SetVRegDouble(i, val); }
2210 void SetVRegReference(size_t i, ObjPtr<mirror::Object> val)
2211 REQUIRES_SHARED(Locks::mutator_lock_) {
2212 shadow_frame.SetVRegReference(i, val);
2213 }
2214
David Srbecky6da82472018-10-23 14:03:08 +01002215 SwitchImplContext* const ctx;
2216 const instrumentation::Instrumentation* const instrumentation;
2217 Thread* const self;
2218 ShadowFrame& shadow_frame;
2219 uint32_t const dex_pc;
2220 const Instruction*& inst;
2221 uint16_t const inst_data;
2222 bool& exit_interpreter_loop;
2223};
2224
David Srbecky6da82472018-10-23 14:03:08 +01002225#undef BRANCH_INSTRUMENTATION
David Srbecky6da82472018-10-23 14:03:08 +01002226#undef POSSIBLY_HANDLE_PENDING_EXCEPTION
2227#undef POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE
2228#undef POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC
David Srbecky6da82472018-10-23 14:03:08 +01002229#undef HANDLE_PENDING_EXCEPTION
David Srbecky6da82472018-10-23 14:03:08 +01002230
Alex Light6f22e062018-10-05 15:05:12 -07002231// TODO On ASAN builds this function gets a huge stack frame. Since normally we run in the mterp
2232// this shouldn't cause any problems for stack overflow detection. Remove this once b/117341496 is
2233// fixed.
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002234template<bool do_access_check, bool transaction_active>
Alex Light6f22e062018-10-05 15:05:12 -07002235ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
David Srbecky946bb092018-03-09 17:23:01 +00002236 Thread* self = ctx->self;
2237 const CodeItemDataAccessor& accessor = ctx->accessor;
2238 ShadowFrame& shadow_frame = ctx->shadow_frame;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002239 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
2240 LOG(FATAL) << "Invalid shadow frame for interpreter use";
David Srbecky946bb092018-03-09 17:23:01 +00002241 ctx->result = JValue();
2242 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002243 }
2244 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002245
2246 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002247 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002248 const uint16_t* const insns = accessor.Insns();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002249 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002250 uint16_t inst_data;
Igor Murashkin6918bf12015-09-27 19:19:06 -07002251
Alex Light0aa7a5a2018-10-10 15:58:14 +00002252 DCHECK(!shadow_frame.GetForceRetryInstruction())
2253 << "Entered interpreter from invoke without retry instruction being handled!";
2254
David Srbecky6da82472018-10-23 14:03:08 +01002255 bool const interpret_one_instruction = ctx->interpret_one_instruction;
2256 while (true) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002257 dex_pc = inst->GetDexPc(insns);
2258 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -08002259 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002260 inst_data = inst->Fetch16(0);
David Srbeckya4a96af2018-10-31 16:34:58 +00002261 {
2262 bool exit_loop = false;
David Srbecky436f6c12019-05-22 13:28:42 +01002263 InstructionHandler<do_access_check, transaction_active, Instruction::kInvalidFormat> handler(
David Srbeckya4a96af2018-10-31 16:34:58 +00002264 ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, exit_loop);
2265 if (!handler.Preamble()) {
2266 if (UNLIKELY(exit_loop)) {
2267 return;
2268 }
2269 if (UNLIKELY(interpret_one_instruction)) {
2270 break;
2271 }
2272 continue;
2273 }
2274 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002275 switch (inst->Opcode(inst_data)) {
David Srbecky436f6c12019-05-22 13:28:42 +01002276#define OPCODE_CASE(OPCODE, OPCODE_NAME, pname, FORMAT, i, a, e, v) \
David Srbecky6da82472018-10-23 14:03:08 +01002277 case OPCODE: { \
2278 bool exit_loop = false; \
David Srbecky436f6c12019-05-22 13:28:42 +01002279 InstructionHandler<do_access_check, transaction_active, Instruction::FORMAT> handler( \
David Srbecky6da82472018-10-23 14:03:08 +01002280 ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, exit_loop); \
David Srbeckya4a96af2018-10-31 16:34:58 +00002281 handler.OPCODE_NAME(); \
David Srbecky6da82472018-10-23 14:03:08 +01002282 /* TODO: Advance 'inst' here, instead of explicitly in each handler */ \
2283 if (UNLIKELY(exit_loop)) { \
2284 return; \
2285 } \
2286 break; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002287 }
David Srbecky6da82472018-10-23 14:03:08 +01002288DEX_INSTRUCTION_LIST(OPCODE_CASE)
2289#undef OPCODE_CASE
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002290 }
David Srbecky6da82472018-10-23 14:03:08 +01002291 if (UNLIKELY(interpret_one_instruction)) {
David Srbeckya4a96af2018-10-31 16:34:58 +00002292 break;
David Srbecky6da82472018-10-23 14:03:08 +01002293 }
2294 }
David Srbeckya4a96af2018-10-31 16:34:58 +00002295 // Record where we stopped.
2296 shadow_frame.SetDexPC(inst->GetDexPc(insns));
2297 ctx->result = ctx->result_register;
2298 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002299} // NOLINT(readability/fn_size)
2300
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002301} // namespace interpreter
2302} // namespace art
David Srbecky2ee09ff2018-10-24 13:24:22 +01002303
2304#endif // ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_