blob: c952ccb3dd4e859bb8e977e483cdda3f2cb54eed [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
479 template<FindFieldType find_type, Primitive::Type field_type>
480 ALWAYS_INLINE WARN_UNUSED bool HandleGet() REQUIRES_SHARED(Locks::mutator_lock_) {
481 bool success = DoFieldGet<find_type, field_type, do_access_check, transaction_active>(
482 self, shadow_frame, inst, inst_data);
483 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
484 return true;
485 }
486
487 template<Primitive::Type field_type>
488 ALWAYS_INLINE WARN_UNUSED bool HandleGetQuick() REQUIRES_SHARED(Locks::mutator_lock_) {
489 bool success = DoIGetQuick<field_type>(shadow_frame, inst, inst_data);
490 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
491 return true;
492 }
493
494 template<FindFieldType find_type, Primitive::Type field_type>
495 ALWAYS_INLINE WARN_UNUSED bool HandlePut() REQUIRES_SHARED(Locks::mutator_lock_) {
496 bool success = DoFieldPut<find_type, field_type, do_access_check, transaction_active>(
497 self, shadow_frame, inst, inst_data);
498 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
499 return true;
500 }
501
502 template<Primitive::Type field_type>
503 ALWAYS_INLINE WARN_UNUSED bool HandlePutQuick() REQUIRES_SHARED(Locks::mutator_lock_) {
504 bool success = DoIPutQuick<field_type, transaction_active>(
505 shadow_frame, inst, inst_data);
506 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
507 return true;
508 }
509
510 template<InvokeType type, bool is_range, bool is_quick = false>
511 ALWAYS_INLINE WARN_UNUSED bool HandleInvoke() REQUIRES_SHARED(Locks::mutator_lock_) {
512 bool success = DoInvoke<type, is_range, do_access_check, /*is_mterp=*/ false, is_quick>(
513 self, shadow_frame, inst, inst_data, ResultRegister());
514 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
515 return true;
516 }
517
518 ALWAYS_INLINE WARN_UNUSED bool HandleUnused() REQUIRES_SHARED(Locks::mutator_lock_) {
519 UnexpectedOpcode(inst, shadow_frame);
520 return true;
521 }
522
David Srbeckybd613ec2019-05-30 15:39:38 +0100523 ALWAYS_INLINE bool NOP() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100524 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100525 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100526 }
527
David Srbeckybd613ec2019-05-30 15:39:38 +0100528 ALWAYS_INLINE bool MOVE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100529 SetVReg(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100530 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100531 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100532 }
533
David Srbeckybd613ec2019-05-30 15:39:38 +0100534 ALWAYS_INLINE bool MOVE_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100535 SetVReg(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100536 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100537 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100538 }
539
David Srbeckybd613ec2019-05-30 15:39:38 +0100540 ALWAYS_INLINE bool MOVE_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100541 SetVReg(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100542 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100543 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100544 }
545
David Srbeckybd613ec2019-05-30 15:39:38 +0100546 ALWAYS_INLINE bool MOVE_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100547 SetVRegLong(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100548 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100549 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100550 }
551
David Srbeckybd613ec2019-05-30 15:39:38 +0100552 ALWAYS_INLINE bool MOVE_WIDE_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100553 SetVRegLong(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100554 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100555 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100556 }
557
David Srbeckybd613ec2019-05-30 15:39:38 +0100558 ALWAYS_INLINE bool MOVE_WIDE_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100559 SetVRegLong(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100560 inst = inst->Next_3xx();
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_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100565 SetVRegReference(A(), GetVRegReference(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_OBJECT_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100571 SetVRegReference(A(), GetVRegReference(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_OBJECT_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100577 SetVRegReference(A(), GetVRegReference(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_RESULT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100583 SetVReg(A(), ResultRegister()->GetI());
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_RESULT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100589 SetVRegLong(A(), ResultRegister()->GetJ());
David Srbecky6da82472018-10-23 14:03:08 +0100590 inst = inst->Next_1xx();
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_RESULT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100595 SetVRegReference(A(), ResultRegister()->GetL());
David Srbecky6da82472018-10-23 14:03:08 +0100596 inst = inst->Next_1xx();
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_EXCEPTION() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100601 ObjPtr<mirror::Throwable> exception = self->GetException();
602 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
David Srbecky6baf6442019-05-30 14:57:43 +0100603 SetVRegReference(A(), exception);
David Srbecky6da82472018-10-23 14:03:08 +0100604 self->ClearException();
605 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100606 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100607 }
608
David Srbeckybd613ec2019-05-30 15:39:38 +0100609 ALWAYS_INLINE bool RETURN_VOID_NO_BARRIER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100610 JValue result;
David Srbeckyee12e3a2019-06-03 15:18:57 +0100611 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100612 }
613
David Srbeckybd613ec2019-05-30 15:39:38 +0100614 ALWAYS_INLINE bool RETURN_VOID() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100615 QuasiAtomic::ThreadFenceForConstructor();
616 JValue result;
David Srbeckyee12e3a2019-06-03 15:18:57 +0100617 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100618 }
619
David Srbeckybd613ec2019-05-30 15:39:38 +0100620 ALWAYS_INLINE bool RETURN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100621 JValue result;
622 result.SetJ(0);
David Srbecky6baf6442019-05-30 14:57:43 +0100623 result.SetI(GetVReg(A()));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100624 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100625 }
626
David Srbeckybd613ec2019-05-30 15:39:38 +0100627 ALWAYS_INLINE bool RETURN_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100628 JValue result;
David Srbecky6baf6442019-05-30 14:57:43 +0100629 result.SetJ(GetVRegLong(A()));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100630 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100631 }
632
David Srbeckybd613ec2019-05-30 15:39:38 +0100633 ALWAYS_INLINE bool RETURN_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100634 JValue result;
635 self->AllowThreadSuspension();
David Srbecky47ad3762018-10-31 12:43:40 +0000636 if (!HandleMonitorChecks()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100637 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000638 }
David Srbeckyd6f579c2019-05-29 18:09:30 +0100639 const size_t ref_idx = A();
David Srbecky6baf6442019-05-30 14:57:43 +0100640 ObjPtr<mirror::Object> obj_result = GetVRegReference(ref_idx);
David Srbecky6da82472018-10-23 14:03:08 +0100641 if (do_assignability_check && obj_result != nullptr) {
642 ObjPtr<mirror::Class> return_type = shadow_frame.GetMethod()->ResolveReturnType();
643 // Re-load since it might have moved.
David Srbecky6baf6442019-05-30 14:57:43 +0100644 obj_result = GetVRegReference(ref_idx);
David Srbecky6da82472018-10-23 14:03:08 +0100645 if (return_type == nullptr) {
646 // Return the pending exception.
647 HANDLE_PENDING_EXCEPTION();
648 }
649 if (!obj_result->VerifierInstanceOf(return_type)) {
650 // This should never happen.
651 std::string temp1, temp2;
652 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
653 "Returning '%s' that is not instance of return type '%s'",
654 obj_result->GetClass()->GetDescriptor(&temp1),
655 return_type->GetDescriptor(&temp2));
656 HANDLE_PENDING_EXCEPTION();
657 }
658 }
659 result.SetL(obj_result);
660 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
661 !SendMethodExitEvents(self,
662 instrumentation,
663 shadow_frame,
664 shadow_frame.GetThisObject(Accessor().InsSize()),
665 shadow_frame.GetMethod(),
666 inst->GetDexPc(Insns()),
667 result))) {
David Srbecky47ad3762018-10-31 12:43:40 +0000668 if (!HandlePendingExceptionWithInstrumentation(nullptr)) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100669 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000670 }
David Srbecky6da82472018-10-23 14:03:08 +0100671 }
672 // Re-load since it might have moved during the MethodExitEvent.
David Srbecky6baf6442019-05-30 14:57:43 +0100673 result.SetL(GetVRegReference(ref_idx));
David Srbecky6da82472018-10-23 14:03:08 +0100674 if (ctx->interpret_one_instruction) {
675 /* Signal mterp to return to caller */
676 shadow_frame.SetDexPC(dex::kDexNoIndex);
677 }
678 ctx->result = result;
679 exit_interpreter_loop = true;
David Srbeckybd613ec2019-05-30 15:39:38 +0100680 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100681 }
682
David Srbeckybd613ec2019-05-30 15:39:38 +0100683 ALWAYS_INLINE bool CONST_4() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100684 uint4_t dst = inst->VRegA_11n(inst_data);
685 int4_t val = inst->VRegB_11n(inst_data);
David Srbecky6baf6442019-05-30 14:57:43 +0100686 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100687 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100688 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100689 }
690 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100691 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100692 }
693
David Srbeckybd613ec2019-05-30 15:39:38 +0100694 ALWAYS_INLINE bool CONST_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100695 uint8_t dst = A();
696 int16_t val = B();
David Srbecky6baf6442019-05-30 14:57:43 +0100697 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100698 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100699 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100700 }
701 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100702 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100703 }
704
David Srbeckybd613ec2019-05-30 15:39:38 +0100705 ALWAYS_INLINE bool CONST() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100706 uint8_t dst = A();
707 int32_t val = B();
David Srbecky6baf6442019-05-30 14:57:43 +0100708 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100709 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100710 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100711 }
712 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100713 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100714 }
715
David Srbeckybd613ec2019-05-30 15:39:38 +0100716 ALWAYS_INLINE bool CONST_HIGH16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100717 uint8_t dst = A();
718 int32_t val = static_cast<int32_t>(B() << 16);
David Srbecky6baf6442019-05-30 14:57:43 +0100719 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100720 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100721 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100722 }
723 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100724 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100725 }
726
David Srbeckybd613ec2019-05-30 15:39:38 +0100727 ALWAYS_INLINE bool CONST_WIDE_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100728 SetVRegLong(A(), B());
David Srbecky6da82472018-10-23 14:03:08 +0100729 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100730 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100731 }
732
David Srbeckybd613ec2019-05-30 15:39:38 +0100733 ALWAYS_INLINE bool CONST_WIDE_32() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100734 SetVRegLong(A(), B());
David Srbecky6da82472018-10-23 14:03:08 +0100735 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100736 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100737 }
738
David Srbeckybd613ec2019-05-30 15:39:38 +0100739 ALWAYS_INLINE bool CONST_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100740 SetVRegLong(A(), inst->WideVRegB());
David Srbecky6da82472018-10-23 14:03:08 +0100741 inst = inst->Next_51l();
David Srbeckybd613ec2019-05-30 15:39:38 +0100742 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100743 }
744
David Srbeckybd613ec2019-05-30 15:39:38 +0100745 ALWAYS_INLINE bool CONST_WIDE_HIGH16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100746 SetVRegLong(A(), static_cast<uint64_t>(B()) << 48);
David Srbecky6da82472018-10-23 14:03:08 +0100747 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100748 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100749 }
750
David Srbeckybd613ec2019-05-30 15:39:38 +0100751 ALWAYS_INLINE bool CONST_STRING() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100752 ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, dex::StringIndex(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100753 if (UNLIKELY(s == nullptr)) {
754 HANDLE_PENDING_EXCEPTION();
755 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100756 SetVRegReference(A(), s);
David Srbecky6da82472018-10-23 14:03:08 +0100757 inst = inst->Next_2xx();
758 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100759 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100760 }
761
David Srbeckybd613ec2019-05-30 15:39:38 +0100762 ALWAYS_INLINE bool CONST_STRING_JUMBO() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100763 ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, dex::StringIndex(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100764 if (UNLIKELY(s == nullptr)) {
765 HANDLE_PENDING_EXCEPTION();
766 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100767 SetVRegReference(A(), s);
David Srbecky6da82472018-10-23 14:03:08 +0100768 inst = inst->Next_3xx();
769 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100770 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100771 }
772
David Srbeckybd613ec2019-05-30 15:39:38 +0100773 ALWAYS_INLINE bool CONST_CLASS() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100774 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100775 shadow_frame.GetMethod(),
776 self,
777 false,
778 do_access_check);
779 if (UNLIKELY(c == nullptr)) {
780 HANDLE_PENDING_EXCEPTION();
781 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100782 SetVRegReference(A(), c);
David Srbecky6da82472018-10-23 14:03:08 +0100783 inst = inst->Next_2xx();
784 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100785 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100786 }
787
David Srbeckybd613ec2019-05-30 15:39:38 +0100788 ALWAYS_INLINE bool CONST_METHOD_HANDLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100789 ClassLinker* cl = Runtime::Current()->GetClassLinker();
790 ObjPtr<mirror::MethodHandle> mh = cl->ResolveMethodHandle(self,
David Srbeckyd6f579c2019-05-29 18:09:30 +0100791 B(),
David Srbecky6da82472018-10-23 14:03:08 +0100792 shadow_frame.GetMethod());
793 if (UNLIKELY(mh == nullptr)) {
794 HANDLE_PENDING_EXCEPTION();
795 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100796 SetVRegReference(A(), mh);
David Srbecky6da82472018-10-23 14:03:08 +0100797 inst = inst->Next_2xx();
798 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100799 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100800 }
801
David Srbeckybd613ec2019-05-30 15:39:38 +0100802 ALWAYS_INLINE bool CONST_METHOD_TYPE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100803 ClassLinker* cl = Runtime::Current()->GetClassLinker();
804 ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(self,
David Srbeckyd6f579c2019-05-29 18:09:30 +0100805 dex::ProtoIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100806 shadow_frame.GetMethod());
807 if (UNLIKELY(mt == nullptr)) {
808 HANDLE_PENDING_EXCEPTION();
809 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100810 SetVRegReference(A(), mt);
David Srbecky6da82472018-10-23 14:03:08 +0100811 inst = inst->Next_2xx();
812 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100813 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100814 }
815
David Srbeckybd613ec2019-05-30 15:39:38 +0100816 ALWAYS_INLINE bool MONITOR_ENTER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000817 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100818 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000819 }
David Srbecky6baf6442019-05-30 14:57:43 +0100820 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100821 if (UNLIKELY(obj == nullptr)) {
822 ThrowNullPointerExceptionFromInterpreter();
823 HANDLE_PENDING_EXCEPTION();
824 } else {
825 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
826 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
827 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100828 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100829 }
830
David Srbeckybd613ec2019-05-30 15:39:38 +0100831 ALWAYS_INLINE bool MONITOR_EXIT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000832 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100833 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000834 }
David Srbecky6baf6442019-05-30 14:57:43 +0100835 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100836 if (UNLIKELY(obj == nullptr)) {
837 ThrowNullPointerExceptionFromInterpreter();
838 HANDLE_PENDING_EXCEPTION();
839 } else {
840 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
841 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
842 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100843 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100844 }
845
David Srbeckybd613ec2019-05-30 15:39:38 +0100846 ALWAYS_INLINE bool CHECK_CAST() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100847 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100848 shadow_frame.GetMethod(),
849 self,
850 false,
851 do_access_check);
852 if (UNLIKELY(c == nullptr)) {
853 HANDLE_PENDING_EXCEPTION();
854 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100855 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100856 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
857 ThrowClassCastException(c, obj->GetClass());
858 HANDLE_PENDING_EXCEPTION();
859 } else {
860 inst = inst->Next_2xx();
861 }
862 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100863 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100864 }
865
David Srbeckybd613ec2019-05-30 15:39:38 +0100866 ALWAYS_INLINE bool INSTANCE_OF() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100867 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(C()),
David Srbecky6da82472018-10-23 14:03:08 +0100868 shadow_frame.GetMethod(),
869 self,
870 false,
871 do_access_check);
872 if (UNLIKELY(c == nullptr)) {
873 HANDLE_PENDING_EXCEPTION();
874 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100875 ObjPtr<mirror::Object> obj = GetVRegReference(B());
876 SetVReg(A(), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
David Srbecky6da82472018-10-23 14:03:08 +0100877 inst = inst->Next_2xx();
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 ARRAY_LENGTH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100883 ObjPtr<mirror::Object> array = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +0100884 if (UNLIKELY(array == nullptr)) {
885 ThrowNullPointerExceptionFromInterpreter();
886 HANDLE_PENDING_EXCEPTION();
887 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100888 SetVReg(A(), array->AsArray()->GetLength());
David Srbecky6da82472018-10-23 14:03:08 +0100889 inst = inst->Next_1xx();
890 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100891 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100892 }
893
David Srbeckybd613ec2019-05-30 15:39:38 +0100894 ALWAYS_INLINE bool NEW_INSTANCE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100895 ObjPtr<mirror::Object> obj = nullptr;
David Srbeckyd6f579c2019-05-29 18:09:30 +0100896 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100897 shadow_frame.GetMethod(),
898 self,
899 false,
900 do_access_check);
901 if (LIKELY(c != nullptr)) {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100902 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
David Srbecky6da82472018-10-23 14:03:08 +0100903 if (UNLIKELY(c->IsStringClass())) {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100904 obj = mirror::String::AllocEmptyString(self, allocator_type);
David Srbecky6da82472018-10-23 14:03:08 +0100905 } else {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100906 obj = AllocObjectFromCode(c, self, allocator_type);
David Srbecky6da82472018-10-23 14:03:08 +0100907 }
908 }
909 if (UNLIKELY(obj == nullptr)) {
910 HANDLE_PENDING_EXCEPTION();
911 } else {
912 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
913 // Don't allow finalizable objects to be allocated during a transaction since these can't
914 // be finalized without a started runtime.
915 if (transaction_active && obj->GetClass()->IsFinalizable()) {
916 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
917 obj->PrettyTypeOf().c_str());
918 HANDLE_PENDING_EXCEPTION();
919 }
David Srbecky6baf6442019-05-30 14:57:43 +0100920 SetVRegReference(A(), obj);
David Srbecky6da82472018-10-23 14:03:08 +0100921 inst = inst->Next_2xx();
922 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100923 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100924 }
925
David Srbeckybd613ec2019-05-30 15:39:38 +0100926 ALWAYS_INLINE bool NEW_ARRAY() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100927 int32_t length = GetVReg(B());
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100928 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check>(
David Srbeckyd6f579c2019-05-29 18:09:30 +0100929 dex::TypeIndex(C()),
David Srbecky6da82472018-10-23 14:03:08 +0100930 length,
931 shadow_frame.GetMethod(),
932 self,
933 Runtime::Current()->GetHeap()->GetCurrentAllocator());
934 if (UNLIKELY(obj == nullptr)) {
935 HANDLE_PENDING_EXCEPTION();
936 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100937 SetVRegReference(A(), obj);
David Srbecky6da82472018-10-23 14:03:08 +0100938 inst = inst->Next_2xx();
939 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100940 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100941 }
942
David Srbeckybd613ec2019-05-30 15:39:38 +0100943 ALWAYS_INLINE bool FILLED_NEW_ARRAY() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100944 bool success =
945 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
946 ResultRegister());
947 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
David Srbeckybd613ec2019-05-30 15:39:38 +0100948 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100949 }
950
David Srbeckybd613ec2019-05-30 15:39:38 +0100951 ALWAYS_INLINE bool FILLED_NEW_ARRAY_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100952 bool success =
953 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
954 self, ResultRegister());
955 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
David Srbeckybd613ec2019-05-30 15:39:38 +0100956 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100957 }
958
David Srbeckybd613ec2019-05-30 15:39:38 +0100959 ALWAYS_INLINE bool FILL_ARRAY_DATA() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100960 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + B();
David Srbecky6da82472018-10-23 14:03:08 +0100961 const Instruction::ArrayDataPayload* payload =
962 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
David Srbecky6baf6442019-05-30 14:57:43 +0100963 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100964 bool success = FillArrayData(obj, payload);
965 if (!success) {
966 HANDLE_PENDING_EXCEPTION();
967 }
968 if (transaction_active) {
969 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
970 }
971 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100972 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100973 }
974
David Srbeckybd613ec2019-05-30 15:39:38 +0100975 ALWAYS_INLINE bool THROW() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000976 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100977 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000978 }
David Srbecky6baf6442019-05-30 14:57:43 +0100979 ObjPtr<mirror::Object> exception = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100980 if (UNLIKELY(exception == nullptr)) {
981 ThrowNullPointerException("throw with null exception");
982 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
983 // This should never happen.
984 std::string temp;
985 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
986 "Throwing '%s' that is not instance of Throwable",
987 exception->GetClass()->GetDescriptor(&temp));
988 } else {
989 self->SetException(exception->AsThrowable());
990 }
991 HANDLE_PENDING_EXCEPTION();
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 GOTO() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100996 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +0100997 }
998
David Srbeckybd613ec2019-05-30 15:39:38 +0100999 ALWAYS_INLINE bool GOTO_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001000 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +01001001 }
1002
David Srbeckybd613ec2019-05-30 15:39:38 +01001003 ALWAYS_INLINE bool GOTO_32() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001004 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +01001005 }
1006
David Srbeckybd613ec2019-05-30 15:39:38 +01001007 ALWAYS_INLINE bool PACKED_SWITCH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001008 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
1009 BRANCH_INSTRUMENTATION(offset);
1010 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001011 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +01001012 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001013 }
1014
David Srbeckybd613ec2019-05-30 15:39:38 +01001015 ALWAYS_INLINE bool SPARSE_SWITCH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001016 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
1017 BRANCH_INSTRUMENTATION(offset);
1018 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001019 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +01001020 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001021 }
1022
David Srbeckybd613ec2019-05-30 15:39:38 +01001023 ALWAYS_INLINE bool CMPL_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001024 return HandleCmpl<float>(GetVRegFloat(B()), GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001025 }
1026
David Srbeckybd613ec2019-05-30 15:39:38 +01001027 ALWAYS_INLINE bool CMPG_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001028 return HandleCmpg<float>(GetVRegFloat(B()), GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001029 }
1030
David Srbeckybd613ec2019-05-30 15:39:38 +01001031 ALWAYS_INLINE bool CMPL_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001032 return HandleCmpl<double>(GetVRegDouble(B()), GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001033 }
1034
David Srbeckybd613ec2019-05-30 15:39:38 +01001035 ALWAYS_INLINE bool CMPG_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001036 return HandleCmpg<double>(GetVRegDouble(B()), GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001037 }
1038
David Srbeckybd613ec2019-05-30 15:39:38 +01001039 ALWAYS_INLINE bool CMP_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001040 return HandleCmpl<int64_t>(GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001041 }
1042
David Srbeckybd613ec2019-05-30 15:39:38 +01001043 ALWAYS_INLINE bool IF_EQ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001044 return HandleIf(GetVReg(A()) == GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001045 }
1046
David Srbeckybd613ec2019-05-30 15:39:38 +01001047 ALWAYS_INLINE bool IF_NE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001048 return HandleIf(GetVReg(A()) != GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001049 }
1050
David Srbeckybd613ec2019-05-30 15:39:38 +01001051 ALWAYS_INLINE bool IF_LT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001052 return HandleIf(GetVReg(A()) < GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001053 }
1054
David Srbeckybd613ec2019-05-30 15:39:38 +01001055 ALWAYS_INLINE bool IF_GE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001056 return HandleIf(GetVReg(A()) >= GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001057 }
1058
David Srbeckybd613ec2019-05-30 15:39:38 +01001059 ALWAYS_INLINE bool IF_GT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001060 return HandleIf(GetVReg(A()) > GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001061 }
1062
David Srbeckybd613ec2019-05-30 15:39:38 +01001063 ALWAYS_INLINE bool IF_LE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001064 return HandleIf(GetVReg(A()) <= GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001065 }
1066
David Srbeckybd613ec2019-05-30 15:39:38 +01001067 ALWAYS_INLINE bool IF_EQZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001068 return HandleIf(GetVReg(A()) == 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001069 }
1070
David Srbeckybd613ec2019-05-30 15:39:38 +01001071 ALWAYS_INLINE bool IF_NEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001072 return HandleIf(GetVReg(A()) != 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001073 }
1074
David Srbeckybd613ec2019-05-30 15:39:38 +01001075 ALWAYS_INLINE bool IF_LTZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001076 return HandleIf(GetVReg(A()) < 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001077 }
1078
David Srbeckybd613ec2019-05-30 15:39:38 +01001079 ALWAYS_INLINE bool IF_GEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001080 return HandleIf(GetVReg(A()) >= 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001081 }
1082
David Srbeckybd613ec2019-05-30 15:39:38 +01001083 ALWAYS_INLINE bool IF_GTZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001084 return HandleIf(GetVReg(A()) > 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001085 }
1086
David Srbeckybd613ec2019-05-30 15:39:38 +01001087 ALWAYS_INLINE bool IF_LEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001088 return HandleIf(GetVReg(A()) <= 0, B());
David Srbecky6da82472018-10-23 14:03:08 +01001089 }
1090
David Srbeckybd613ec2019-05-30 15:39:38 +01001091 ALWAYS_INLINE bool AGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001092 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001093 if (UNLIKELY(a == nullptr)) {
1094 ThrowNullPointerExceptionFromInterpreter();
1095 HANDLE_PENDING_EXCEPTION();
1096 }
David Srbecky6baf6442019-05-30 14:57:43 +01001097 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001098 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
1099 if (array->CheckIsValidIndex(index)) {
David Srbecky6baf6442019-05-30 14:57:43 +01001100 SetVReg(A(), array->GetWithoutChecks(index));
David Srbecky6da82472018-10-23 14:03:08 +01001101 inst = inst->Next_2xx();
1102 } else {
1103 HANDLE_PENDING_EXCEPTION();
1104 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001105 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001106 }
1107
David Srbeckybd613ec2019-05-30 15:39:38 +01001108 ALWAYS_INLINE bool AGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001109 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001110 if (UNLIKELY(a == nullptr)) {
1111 ThrowNullPointerExceptionFromInterpreter();
1112 HANDLE_PENDING_EXCEPTION();
1113 }
David Srbecky6baf6442019-05-30 14:57:43 +01001114 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001115 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
1116 if (array->CheckIsValidIndex(index)) {
David Srbecky6baf6442019-05-30 14:57:43 +01001117 SetVReg(A(), array->GetWithoutChecks(index));
David Srbecky6da82472018-10-23 14:03:08 +01001118 inst = inst->Next_2xx();
1119 } else {
1120 HANDLE_PENDING_EXCEPTION();
1121 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001122 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001123 }
1124
David Srbeckybd613ec2019-05-30 15:39:38 +01001125 ALWAYS_INLINE bool AGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001126 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001127 if (UNLIKELY(a == nullptr)) {
1128 ThrowNullPointerExceptionFromInterpreter();
1129 HANDLE_PENDING_EXCEPTION();
1130 }
David Srbecky6baf6442019-05-30 14:57:43 +01001131 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001132 ObjPtr<mirror::CharArray> array = a->AsCharArray();
1133 if (array->CheckIsValidIndex(index)) {
David Srbecky6baf6442019-05-30 14:57:43 +01001134 SetVReg(A(), array->GetWithoutChecks(index));
David Srbecky6da82472018-10-23 14:03:08 +01001135 inst = inst->Next_2xx();
1136 } else {
1137 HANDLE_PENDING_EXCEPTION();
1138 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001139 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001140 }
1141
David Srbeckybd613ec2019-05-30 15:39:38 +01001142 ALWAYS_INLINE bool AGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001143 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001144 if (UNLIKELY(a == nullptr)) {
1145 ThrowNullPointerExceptionFromInterpreter();
1146 HANDLE_PENDING_EXCEPTION();
1147 }
David Srbecky6baf6442019-05-30 14:57:43 +01001148 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001149 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
1150 if (array->CheckIsValidIndex(index)) {
David Srbecky6baf6442019-05-30 14:57:43 +01001151 SetVReg(A(), array->GetWithoutChecks(index));
David Srbecky6da82472018-10-23 14:03:08 +01001152 inst = inst->Next_2xx();
1153 } else {
1154 HANDLE_PENDING_EXCEPTION();
1155 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001156 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001157 }
1158
David Srbeckybd613ec2019-05-30 15:39:38 +01001159 ALWAYS_INLINE bool AGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001160 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001161 if (UNLIKELY(a == nullptr)) {
1162 ThrowNullPointerExceptionFromInterpreter();
1163 HANDLE_PENDING_EXCEPTION();
1164 }
David Srbecky6baf6442019-05-30 14:57:43 +01001165 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001166 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
1167 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
1168 if (array->CheckIsValidIndex(index)) {
David Srbecky6baf6442019-05-30 14:57:43 +01001169 SetVReg(A(), array->GetWithoutChecks(index));
David Srbecky6da82472018-10-23 14:03:08 +01001170 inst = inst->Next_2xx();
1171 } else {
1172 HANDLE_PENDING_EXCEPTION();
1173 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001174 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001175 }
1176
David Srbeckybd613ec2019-05-30 15:39:38 +01001177 ALWAYS_INLINE bool AGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001178 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001179 if (UNLIKELY(a == nullptr)) {
1180 ThrowNullPointerExceptionFromInterpreter();
1181 HANDLE_PENDING_EXCEPTION();
1182 }
David Srbecky6baf6442019-05-30 14:57:43 +01001183 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001184 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
1185 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
1186 if (array->CheckIsValidIndex(index)) {
David Srbecky6baf6442019-05-30 14:57:43 +01001187 SetVRegLong(A(), array->GetWithoutChecks(index));
David Srbecky6da82472018-10-23 14:03:08 +01001188 inst = inst->Next_2xx();
1189 } else {
1190 HANDLE_PENDING_EXCEPTION();
1191 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001192 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001193 }
1194
David Srbeckybd613ec2019-05-30 15:39:38 +01001195 ALWAYS_INLINE bool AGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001196 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001197 if (UNLIKELY(a == nullptr)) {
1198 ThrowNullPointerExceptionFromInterpreter();
1199 HANDLE_PENDING_EXCEPTION();
1200 }
David Srbecky6baf6442019-05-30 14:57:43 +01001201 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001202 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
1203 if (array->CheckIsValidIndex(index)) {
David Srbecky6baf6442019-05-30 14:57:43 +01001204 SetVRegReference(A(), array->GetWithoutChecks(index));
David Srbecky6da82472018-10-23 14:03:08 +01001205 inst = inst->Next_2xx();
1206 } else {
1207 HANDLE_PENDING_EXCEPTION();
1208 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001209 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001210 }
1211
David Srbeckybd613ec2019-05-30 15:39:38 +01001212 ALWAYS_INLINE bool APUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001213 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001214 if (UNLIKELY(a == nullptr)) {
1215 ThrowNullPointerExceptionFromInterpreter();
1216 HANDLE_PENDING_EXCEPTION();
1217 }
David Srbecky6baf6442019-05-30 14:57:43 +01001218 uint8_t val = GetVReg(A());
1219 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001220 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
1221 if (array->CheckIsValidIndex(index)) {
1222 array->SetWithoutChecks<transaction_active>(index, val);
1223 inst = inst->Next_2xx();
1224 } else {
1225 HANDLE_PENDING_EXCEPTION();
1226 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001227 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001228 }
1229
David Srbeckybd613ec2019-05-30 15:39:38 +01001230 ALWAYS_INLINE bool APUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001231 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001232 if (UNLIKELY(a == nullptr)) {
1233 ThrowNullPointerExceptionFromInterpreter();
1234 HANDLE_PENDING_EXCEPTION();
1235 }
David Srbecky6baf6442019-05-30 14:57:43 +01001236 int8_t val = GetVReg(A());
1237 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001238 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
1239 if (array->CheckIsValidIndex(index)) {
1240 array->SetWithoutChecks<transaction_active>(index, val);
1241 inst = inst->Next_2xx();
1242 } else {
1243 HANDLE_PENDING_EXCEPTION();
1244 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001245 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001246 }
1247
David Srbeckybd613ec2019-05-30 15:39:38 +01001248 ALWAYS_INLINE bool APUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001249 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001250 if (UNLIKELY(a == nullptr)) {
1251 ThrowNullPointerExceptionFromInterpreter();
1252 HANDLE_PENDING_EXCEPTION();
1253 }
David Srbecky6baf6442019-05-30 14:57:43 +01001254 uint16_t val = GetVReg(A());
1255 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001256 ObjPtr<mirror::CharArray> array = a->AsCharArray();
1257 if (array->CheckIsValidIndex(index)) {
1258 array->SetWithoutChecks<transaction_active>(index, val);
1259 inst = inst->Next_2xx();
1260 } else {
1261 HANDLE_PENDING_EXCEPTION();
1262 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001263 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001264 }
1265
David Srbeckybd613ec2019-05-30 15:39:38 +01001266 ALWAYS_INLINE bool APUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001267 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001268 if (UNLIKELY(a == nullptr)) {
1269 ThrowNullPointerExceptionFromInterpreter();
1270 HANDLE_PENDING_EXCEPTION();
1271 }
David Srbecky6baf6442019-05-30 14:57:43 +01001272 int16_t val = GetVReg(A());
1273 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001274 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
1275 if (array->CheckIsValidIndex(index)) {
1276 array->SetWithoutChecks<transaction_active>(index, val);
1277 inst = inst->Next_2xx();
1278 } else {
1279 HANDLE_PENDING_EXCEPTION();
1280 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001281 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001282 }
1283
David Srbeckybd613ec2019-05-30 15:39:38 +01001284 ALWAYS_INLINE bool APUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001285 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001286 if (UNLIKELY(a == nullptr)) {
1287 ThrowNullPointerExceptionFromInterpreter();
1288 HANDLE_PENDING_EXCEPTION();
1289 }
David Srbecky6baf6442019-05-30 14:57:43 +01001290 int32_t val = GetVReg(A());
1291 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001292 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
1293 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
1294 if (array->CheckIsValidIndex(index)) {
1295 array->SetWithoutChecks<transaction_active>(index, val);
1296 inst = inst->Next_2xx();
1297 } else {
1298 HANDLE_PENDING_EXCEPTION();
1299 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001300 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001301 }
1302
David Srbeckybd613ec2019-05-30 15:39:38 +01001303 ALWAYS_INLINE bool APUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001304 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001305 if (UNLIKELY(a == nullptr)) {
1306 ThrowNullPointerExceptionFromInterpreter();
1307 HANDLE_PENDING_EXCEPTION();
1308 }
David Srbecky6baf6442019-05-30 14:57:43 +01001309 int64_t val = GetVRegLong(A());
1310 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001311 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
1312 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
1313 if (array->CheckIsValidIndex(index)) {
1314 array->SetWithoutChecks<transaction_active>(index, val);
1315 inst = inst->Next_2xx();
1316 } else {
1317 HANDLE_PENDING_EXCEPTION();
1318 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001319 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001320 }
1321
David Srbeckybd613ec2019-05-30 15:39:38 +01001322 ALWAYS_INLINE bool APUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001323 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001324 if (UNLIKELY(a == nullptr)) {
1325 ThrowNullPointerExceptionFromInterpreter();
1326 HANDLE_PENDING_EXCEPTION();
1327 }
David Srbecky6baf6442019-05-30 14:57:43 +01001328 int32_t index = GetVReg(C());
1329 ObjPtr<mirror::Object> val = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +01001330 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
1331 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
1332 array->SetWithoutChecks<transaction_active>(index, val);
1333 inst = inst->Next_2xx();
1334 } else {
1335 HANDLE_PENDING_EXCEPTION();
1336 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001337 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001338 }
1339
David Srbeckybd613ec2019-05-30 15:39:38 +01001340 ALWAYS_INLINE bool IGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001341 return HandleGet<InstancePrimitiveRead, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001342 }
1343
David Srbeckybd613ec2019-05-30 15:39:38 +01001344 ALWAYS_INLINE bool IGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001345 return HandleGet<InstancePrimitiveRead, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001346 }
1347
David Srbeckybd613ec2019-05-30 15:39:38 +01001348 ALWAYS_INLINE bool IGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001349 return HandleGet<InstancePrimitiveRead, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001350 }
1351
David Srbeckybd613ec2019-05-30 15:39:38 +01001352 ALWAYS_INLINE bool IGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001353 return HandleGet<InstancePrimitiveRead, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001354 }
1355
David Srbeckybd613ec2019-05-30 15:39:38 +01001356 ALWAYS_INLINE bool IGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001357 return HandleGet<InstancePrimitiveRead, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001358 }
1359
David Srbeckybd613ec2019-05-30 15:39:38 +01001360 ALWAYS_INLINE bool IGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001361 return HandleGet<InstancePrimitiveRead, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001362 }
1363
David Srbeckybd613ec2019-05-30 15:39:38 +01001364 ALWAYS_INLINE bool IGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001365 return HandleGet<InstanceObjectRead, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001366 }
1367
David Srbeckybd613ec2019-05-30 15:39:38 +01001368 ALWAYS_INLINE bool IGET_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001369 return HandleGetQuick<Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001370 }
1371
David Srbeckybd613ec2019-05-30 15:39:38 +01001372 ALWAYS_INLINE bool IGET_WIDE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001373 return HandleGetQuick<Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001374 }
1375
David Srbeckybd613ec2019-05-30 15:39:38 +01001376 ALWAYS_INLINE bool IGET_OBJECT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001377 return HandleGetQuick<Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001378 }
1379
David Srbeckybd613ec2019-05-30 15:39:38 +01001380 ALWAYS_INLINE bool IGET_BOOLEAN_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001381 return HandleGetQuick<Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001382 }
1383
David Srbeckybd613ec2019-05-30 15:39:38 +01001384 ALWAYS_INLINE bool IGET_BYTE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001385 return HandleGetQuick<Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001386 }
1387
David Srbeckybd613ec2019-05-30 15:39:38 +01001388 ALWAYS_INLINE bool IGET_CHAR_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001389 return HandleGetQuick<Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001390 }
1391
David Srbeckybd613ec2019-05-30 15:39:38 +01001392 ALWAYS_INLINE bool IGET_SHORT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001393 return HandleGetQuick<Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001394 }
1395
David Srbeckybd613ec2019-05-30 15:39:38 +01001396 ALWAYS_INLINE bool SGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001397 return HandleGet<StaticPrimitiveRead, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001398 }
1399
David Srbeckybd613ec2019-05-30 15:39:38 +01001400 ALWAYS_INLINE bool SGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001401 return HandleGet<StaticPrimitiveRead, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001402 }
1403
David Srbeckybd613ec2019-05-30 15:39:38 +01001404 ALWAYS_INLINE bool SGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001405 return HandleGet<StaticPrimitiveRead, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001406 }
1407
David Srbeckybd613ec2019-05-30 15:39:38 +01001408 ALWAYS_INLINE bool SGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001409 return HandleGet<StaticPrimitiveRead, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001410 }
1411
David Srbeckybd613ec2019-05-30 15:39:38 +01001412 ALWAYS_INLINE bool SGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001413 return HandleGet<StaticPrimitiveRead, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001414 }
1415
David Srbeckybd613ec2019-05-30 15:39:38 +01001416 ALWAYS_INLINE bool SGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001417 return HandleGet<StaticPrimitiveRead, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001418 }
1419
David Srbeckybd613ec2019-05-30 15:39:38 +01001420 ALWAYS_INLINE bool SGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001421 return HandleGet<StaticObjectRead, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001422 }
1423
David Srbeckybd613ec2019-05-30 15:39:38 +01001424 ALWAYS_INLINE bool IPUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001425 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001426 }
1427
David Srbeckybd613ec2019-05-30 15:39:38 +01001428 ALWAYS_INLINE bool IPUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001429 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001430 }
1431
David Srbeckybd613ec2019-05-30 15:39:38 +01001432 ALWAYS_INLINE bool IPUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001433 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001434 }
1435
David Srbeckybd613ec2019-05-30 15:39:38 +01001436 ALWAYS_INLINE bool IPUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001437 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001438 }
1439
David Srbeckybd613ec2019-05-30 15:39:38 +01001440 ALWAYS_INLINE bool IPUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001441 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001442 }
1443
David Srbeckybd613ec2019-05-30 15:39:38 +01001444 ALWAYS_INLINE bool IPUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001445 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001446 }
1447
David Srbeckybd613ec2019-05-30 15:39:38 +01001448 ALWAYS_INLINE bool IPUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001449 return HandlePut<InstanceObjectWrite, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001450 }
1451
David Srbeckybd613ec2019-05-30 15:39:38 +01001452 ALWAYS_INLINE bool IPUT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001453 return HandlePutQuick<Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001454 }
1455
David Srbeckybd613ec2019-05-30 15:39:38 +01001456 ALWAYS_INLINE bool IPUT_BOOLEAN_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001457 return HandlePutQuick<Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001458 }
1459
David Srbeckybd613ec2019-05-30 15:39:38 +01001460 ALWAYS_INLINE bool IPUT_BYTE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001461 return HandlePutQuick<Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001462 }
1463
David Srbeckybd613ec2019-05-30 15:39:38 +01001464 ALWAYS_INLINE bool IPUT_CHAR_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001465 return HandlePutQuick<Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001466 }
1467
David Srbeckybd613ec2019-05-30 15:39:38 +01001468 ALWAYS_INLINE bool IPUT_SHORT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001469 return HandlePutQuick<Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001470 }
1471
David Srbeckybd613ec2019-05-30 15:39:38 +01001472 ALWAYS_INLINE bool IPUT_WIDE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001473 return HandlePutQuick<Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001474 }
1475
David Srbeckybd613ec2019-05-30 15:39:38 +01001476 ALWAYS_INLINE bool IPUT_OBJECT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001477 return HandlePutQuick<Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001478 }
1479
David Srbeckybd613ec2019-05-30 15:39:38 +01001480 ALWAYS_INLINE bool SPUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001481 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001482 }
1483
David Srbeckybd613ec2019-05-30 15:39:38 +01001484 ALWAYS_INLINE bool SPUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001485 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001486 }
1487
David Srbeckybd613ec2019-05-30 15:39:38 +01001488 ALWAYS_INLINE bool SPUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001489 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001490 }
1491
David Srbeckybd613ec2019-05-30 15:39:38 +01001492 ALWAYS_INLINE bool SPUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001493 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001494 }
1495
David Srbeckybd613ec2019-05-30 15:39:38 +01001496 ALWAYS_INLINE bool SPUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001497 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001498 }
1499
David Srbeckybd613ec2019-05-30 15:39:38 +01001500 ALWAYS_INLINE bool SPUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001501 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001502 }
1503
David Srbeckybd613ec2019-05-30 15:39:38 +01001504 ALWAYS_INLINE bool SPUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001505 return HandlePut<StaticObjectWrite, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001506 }
1507
David Srbeckybd613ec2019-05-30 15:39:38 +01001508 ALWAYS_INLINE bool INVOKE_VIRTUAL() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001509 return HandleInvoke<kVirtual, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001510 }
1511
David Srbeckybd613ec2019-05-30 15:39:38 +01001512 ALWAYS_INLINE bool INVOKE_VIRTUAL_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001513 return HandleInvoke<kVirtual, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001514 }
1515
David Srbeckybd613ec2019-05-30 15:39:38 +01001516 ALWAYS_INLINE bool INVOKE_SUPER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001517 return HandleInvoke<kSuper, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001518 }
1519
David Srbeckybd613ec2019-05-30 15:39:38 +01001520 ALWAYS_INLINE bool INVOKE_SUPER_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001521 return HandleInvoke<kSuper, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001522 }
1523
David Srbeckybd613ec2019-05-30 15:39:38 +01001524 ALWAYS_INLINE bool INVOKE_DIRECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001525 return HandleInvoke<kDirect, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001526 }
1527
David Srbeckybd613ec2019-05-30 15:39:38 +01001528 ALWAYS_INLINE bool INVOKE_DIRECT_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001529 return HandleInvoke<kDirect, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001530 }
1531
David Srbeckybd613ec2019-05-30 15:39:38 +01001532 ALWAYS_INLINE bool INVOKE_INTERFACE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001533 return HandleInvoke<kInterface, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001534 }
1535
David Srbeckybd613ec2019-05-30 15:39:38 +01001536 ALWAYS_INLINE bool INVOKE_INTERFACE_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001537 return HandleInvoke<kInterface, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001538 }
1539
David Srbeckybd613ec2019-05-30 15:39:38 +01001540 ALWAYS_INLINE bool INVOKE_STATIC() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001541 return HandleInvoke<kStatic, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001542 }
1543
David Srbeckybd613ec2019-05-30 15:39:38 +01001544 ALWAYS_INLINE bool INVOKE_STATIC_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001545 return HandleInvoke<kStatic, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001546 }
1547
David Srbeckybd613ec2019-05-30 15:39:38 +01001548 ALWAYS_INLINE bool INVOKE_VIRTUAL_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001549 return HandleInvoke<kVirtual, /*is_range=*/ false, /*is_quick=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001550 }
1551
David Srbeckybd613ec2019-05-30 15:39:38 +01001552 ALWAYS_INLINE bool INVOKE_VIRTUAL_RANGE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001553 return HandleInvoke<kVirtual, /*is_range=*/ true, /*is_quick=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001554 }
1555
David Srbeckybd613ec2019-05-30 15:39:38 +01001556 ALWAYS_INLINE bool INVOKE_POLYMORPHIC() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001557 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1558 bool success = DoInvokePolymorphic</* is_range= */ false>(
1559 self, shadow_frame, inst, inst_data, ResultRegister());
1560 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001561 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001562 }
1563
David Srbeckybd613ec2019-05-30 15:39:38 +01001564 ALWAYS_INLINE bool INVOKE_POLYMORPHIC_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001565 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1566 bool success = DoInvokePolymorphic</* is_range= */ true>(
1567 self, shadow_frame, inst, inst_data, ResultRegister());
1568 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001569 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001570 }
1571
David Srbeckybd613ec2019-05-30 15:39:38 +01001572 ALWAYS_INLINE bool INVOKE_CUSTOM() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001573 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1574 bool success = DoInvokeCustom</* is_range= */ false>(
1575 self, shadow_frame, inst, inst_data, ResultRegister());
1576 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001577 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001578 }
1579
David Srbeckybd613ec2019-05-30 15:39:38 +01001580 ALWAYS_INLINE bool INVOKE_CUSTOM_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001581 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1582 bool success = DoInvokeCustom</* is_range= */ true>(
1583 self, shadow_frame, inst, inst_data, ResultRegister());
1584 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001585 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001586 }
1587
David Srbeckybd613ec2019-05-30 15:39:38 +01001588 ALWAYS_INLINE bool NEG_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001589 SetVReg(A(), -GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001590 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001591 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001592 }
1593
David Srbeckybd613ec2019-05-30 15:39:38 +01001594 ALWAYS_INLINE bool NOT_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001595 SetVReg(A(), ~GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001596 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001597 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001598 }
1599
David Srbeckybd613ec2019-05-30 15:39:38 +01001600 ALWAYS_INLINE bool NEG_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001601 SetVRegLong(A(), -GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001602 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001603 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001604 }
1605
David Srbeckybd613ec2019-05-30 15:39:38 +01001606 ALWAYS_INLINE bool NOT_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001607 SetVRegLong(A(), ~GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001608 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001609 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001610 }
1611
David Srbeckybd613ec2019-05-30 15:39:38 +01001612 ALWAYS_INLINE bool NEG_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001613 SetVRegFloat(A(), -GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001614 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001615 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001616 }
1617
David Srbeckybd613ec2019-05-30 15:39:38 +01001618 ALWAYS_INLINE bool NEG_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001619 SetVRegDouble(A(), -GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001620 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001621 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001622 }
1623
David Srbeckybd613ec2019-05-30 15:39:38 +01001624 ALWAYS_INLINE bool INT_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001625 SetVRegLong(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001626 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001627 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001628 }
1629
David Srbeckybd613ec2019-05-30 15:39:38 +01001630 ALWAYS_INLINE bool INT_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001631 SetVRegFloat(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001632 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001633 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001634 }
1635
David Srbeckybd613ec2019-05-30 15:39:38 +01001636 ALWAYS_INLINE bool INT_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001637 SetVRegDouble(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001638 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001639 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001640 }
1641
David Srbeckybd613ec2019-05-30 15:39:38 +01001642 ALWAYS_INLINE bool LONG_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001643 SetVReg(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001644 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001645 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001646 }
1647
David Srbeckybd613ec2019-05-30 15:39:38 +01001648 ALWAYS_INLINE bool LONG_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001649 SetVRegFloat(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001650 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001651 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001652 }
1653
David Srbeckybd613ec2019-05-30 15:39:38 +01001654 ALWAYS_INLINE bool LONG_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001655 SetVRegDouble(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001656 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001657 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001658 }
1659
David Srbeckybd613ec2019-05-30 15:39:38 +01001660 ALWAYS_INLINE bool FLOAT_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001661 float val = GetVRegFloat(B());
David Srbecky6da82472018-10-23 14:03:08 +01001662 int32_t result = art_float_to_integral<int32_t, float>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001663 SetVReg(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001664 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001665 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001666 }
1667
David Srbeckybd613ec2019-05-30 15:39:38 +01001668 ALWAYS_INLINE bool FLOAT_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001669 float val = GetVRegFloat(B());
David Srbecky6da82472018-10-23 14:03:08 +01001670 int64_t result = art_float_to_integral<int64_t, float>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001671 SetVRegLong(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001672 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001673 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001674 }
1675
David Srbeckybd613ec2019-05-30 15:39:38 +01001676 ALWAYS_INLINE bool FLOAT_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001677 SetVRegDouble(A(), GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001678 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001679 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001680 }
1681
David Srbeckybd613ec2019-05-30 15:39:38 +01001682 ALWAYS_INLINE bool DOUBLE_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001683 double val = GetVRegDouble(B());
David Srbecky6da82472018-10-23 14:03:08 +01001684 int32_t result = art_float_to_integral<int32_t, double>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001685 SetVReg(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001686 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001687 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001688 }
1689
David Srbeckybd613ec2019-05-30 15:39:38 +01001690 ALWAYS_INLINE bool DOUBLE_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001691 double val = GetVRegDouble(B());
David Srbecky6da82472018-10-23 14:03:08 +01001692 int64_t result = art_float_to_integral<int64_t, double>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001693 SetVRegLong(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001694 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001695 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001696 }
1697
David Srbeckybd613ec2019-05-30 15:39:38 +01001698 ALWAYS_INLINE bool DOUBLE_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001699 SetVRegFloat(A(), GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001700 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001701 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001702 }
1703
David Srbeckybd613ec2019-05-30 15:39:38 +01001704 ALWAYS_INLINE bool INT_TO_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001705 SetVReg(A(), static_cast<int8_t>(GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001706 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001707 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001708 }
1709
David Srbeckybd613ec2019-05-30 15:39:38 +01001710 ALWAYS_INLINE bool INT_TO_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001711 SetVReg(A(), static_cast<uint16_t>(GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001712 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001713 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001714 }
1715
David Srbeckybd613ec2019-05-30 15:39:38 +01001716 ALWAYS_INLINE bool INT_TO_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001717 SetVReg(A(), static_cast<int16_t>(GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001718 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001719 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001720 }
1721
David Srbeckybd613ec2019-05-30 15:39:38 +01001722 ALWAYS_INLINE bool ADD_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001723 SetVReg(A(), SafeAdd(GetVReg(B()), GetVReg(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001724 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001725 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001726 }
1727
David Srbeckybd613ec2019-05-30 15:39:38 +01001728 ALWAYS_INLINE bool SUB_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001729 SetVReg(A(), SafeSub(GetVReg(B()), GetVReg(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001730 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001731 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001732 }
1733
David Srbeckybd613ec2019-05-30 15:39:38 +01001734 ALWAYS_INLINE bool MUL_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001735 SetVReg(A(), SafeMul(GetVReg(B()), GetVReg(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001736 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001737 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001738 }
1739
David Srbeckybd613ec2019-05-30 15:39:38 +01001740 ALWAYS_INLINE bool DIV_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001741 bool success = DoIntDivide(shadow_frame, A(), GetVReg(B()), GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001742 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001743 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001744 }
1745
David Srbeckybd613ec2019-05-30 15:39:38 +01001746 ALWAYS_INLINE bool REM_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001747 bool success = DoIntRemainder(shadow_frame, A(), GetVReg(B()), GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001748 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001749 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001750 }
1751
David Srbeckybd613ec2019-05-30 15:39:38 +01001752 ALWAYS_INLINE bool SHL_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001753 SetVReg(A(), GetVReg(B()) << (GetVReg(C()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001754 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001755 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001756 }
1757
David Srbeckybd613ec2019-05-30 15:39:38 +01001758 ALWAYS_INLINE bool SHR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001759 SetVReg(A(), GetVReg(B()) >> (GetVReg(C()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001760 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001761 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001762 }
1763
David Srbeckybd613ec2019-05-30 15:39:38 +01001764 ALWAYS_INLINE bool USHR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001765 SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (GetVReg(C()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001766 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001767 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001768 }
1769
David Srbeckybd613ec2019-05-30 15:39:38 +01001770 ALWAYS_INLINE bool AND_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001771 SetVReg(A(), GetVReg(B()) & GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001772 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001773 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001774 }
1775
David Srbeckybd613ec2019-05-30 15:39:38 +01001776 ALWAYS_INLINE bool OR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001777 SetVReg(A(), GetVReg(B()) | GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001778 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001779 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001780 }
1781
David Srbeckybd613ec2019-05-30 15:39:38 +01001782 ALWAYS_INLINE bool XOR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001783 SetVReg(A(), GetVReg(B()) ^ GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001784 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001785 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001786 }
1787
David Srbeckybd613ec2019-05-30 15:39:38 +01001788 ALWAYS_INLINE bool ADD_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001789 SetVRegLong(A(), SafeAdd(GetVRegLong(B()), GetVRegLong(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001790 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001791 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001792 }
1793
David Srbeckybd613ec2019-05-30 15:39:38 +01001794 ALWAYS_INLINE bool SUB_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001795 SetVRegLong(A(), SafeSub(GetVRegLong(B()), GetVRegLong(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001796 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001797 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001798 }
1799
David Srbeckybd613ec2019-05-30 15:39:38 +01001800 ALWAYS_INLINE bool MUL_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001801 SetVRegLong(A(), SafeMul(GetVRegLong(B()), GetVRegLong(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001802 inst = inst->Next_2xx();
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 DIV_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001807 DoLongDivide(shadow_frame, A(), GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001808 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001809 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001810 }
1811
David Srbeckybd613ec2019-05-30 15:39:38 +01001812 ALWAYS_INLINE bool REM_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001813 DoLongRemainder(shadow_frame, A(), GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001814 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001815 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001816 }
1817
David Srbeckybd613ec2019-05-30 15:39:38 +01001818 ALWAYS_INLINE bool AND_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001819 SetVRegLong(A(), GetVRegLong(B()) & GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001820 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001821 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001822 }
1823
David Srbeckybd613ec2019-05-30 15:39:38 +01001824 ALWAYS_INLINE bool OR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001825 SetVRegLong(A(), GetVRegLong(B()) | GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001826 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001827 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001828 }
1829
David Srbeckybd613ec2019-05-30 15:39:38 +01001830 ALWAYS_INLINE bool XOR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001831 SetVRegLong(A(), GetVRegLong(B()) ^ GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001832 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001833 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001834 }
1835
David Srbeckybd613ec2019-05-30 15:39:38 +01001836 ALWAYS_INLINE bool SHL_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001837 SetVRegLong(A(), GetVRegLong(B()) << (GetVReg(C()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001838 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001839 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001840 }
1841
David Srbeckybd613ec2019-05-30 15:39:38 +01001842 ALWAYS_INLINE bool SHR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001843 SetVRegLong(A(), GetVRegLong(B()) >> (GetVReg(C()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001844 inst = inst->Next_2xx();
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 USHR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001849 SetVRegLong(A(), static_cast<uint64_t>(GetVRegLong(B())) >> (GetVReg(C()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01001850 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001851 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001852 }
1853
David Srbeckybd613ec2019-05-30 15:39:38 +01001854 ALWAYS_INLINE bool ADD_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001855 SetVRegFloat(A(), GetVRegFloat(B()) + GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001856 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001857 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001858 }
1859
David Srbeckybd613ec2019-05-30 15:39:38 +01001860 ALWAYS_INLINE bool SUB_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001861 SetVRegFloat(A(), GetVRegFloat(B()) - GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001862 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001863 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001864 }
1865
David Srbeckybd613ec2019-05-30 15:39:38 +01001866 ALWAYS_INLINE bool MUL_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001867 SetVRegFloat(A(), GetVRegFloat(B()) * GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001868 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001869 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001870 }
1871
David Srbeckybd613ec2019-05-30 15:39:38 +01001872 ALWAYS_INLINE bool DIV_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001873 SetVRegFloat(A(), GetVRegFloat(B()) / GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001874 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001875 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001876 }
1877
David Srbeckybd613ec2019-05-30 15:39:38 +01001878 ALWAYS_INLINE bool REM_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001879 SetVRegFloat(A(), fmodf(GetVRegFloat(B()), GetVRegFloat(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001880 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001881 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001882 }
1883
David Srbeckybd613ec2019-05-30 15:39:38 +01001884 ALWAYS_INLINE bool ADD_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001885 SetVRegDouble(A(), GetVRegDouble(B()) + GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001886 inst = inst->Next_2xx();
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 SUB_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001891 SetVRegDouble(A(), GetVRegDouble(B()) - GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001892 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001893 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001894 }
1895
David Srbeckybd613ec2019-05-30 15:39:38 +01001896 ALWAYS_INLINE bool MUL_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001897 SetVRegDouble(A(), GetVRegDouble(B()) * GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001898 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001899 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001900 }
1901
David Srbeckybd613ec2019-05-30 15:39:38 +01001902 ALWAYS_INLINE bool DIV_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001903 SetVRegDouble(A(), GetVRegDouble(B()) / GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001904 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001905 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001906 }
1907
David Srbeckybd613ec2019-05-30 15:39:38 +01001908 ALWAYS_INLINE bool REM_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001909 SetVRegDouble(A(), fmod(GetVRegDouble(B()), GetVRegDouble(C())));
David Srbecky6da82472018-10-23 14:03:08 +01001910 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001911 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001912 }
1913
David Srbeckybd613ec2019-05-30 15:39:38 +01001914 ALWAYS_INLINE bool ADD_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001915 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001916 SetVReg(vregA, SafeAdd(GetVReg(vregA), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001917 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001918 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001919 }
1920
David Srbeckybd613ec2019-05-30 15:39:38 +01001921 ALWAYS_INLINE bool SUB_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001922 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001923 SetVReg(vregA, SafeSub(GetVReg(vregA), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001924 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001925 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001926 }
1927
David Srbeckybd613ec2019-05-30 15:39:38 +01001928 ALWAYS_INLINE bool MUL_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001929 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001930 SetVReg(vregA, SafeMul(GetVReg(vregA), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001931 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001932 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001933 }
1934
David Srbeckybd613ec2019-05-30 15:39:38 +01001935 ALWAYS_INLINE bool DIV_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001936 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001937 bool success = DoIntDivide(shadow_frame, vregA, GetVReg(vregA), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001938 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001939 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001940 }
1941
David Srbeckybd613ec2019-05-30 15:39:38 +01001942 ALWAYS_INLINE bool REM_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001943 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001944 bool success = DoIntRemainder(shadow_frame, vregA, GetVReg(vregA), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001945 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001946 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001947 }
1948
David Srbeckybd613ec2019-05-30 15:39:38 +01001949 ALWAYS_INLINE bool SHL_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001950 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001951 SetVReg(vregA, GetVReg(vregA) << (GetVReg(B()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001952 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001953 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001954 }
1955
David Srbeckybd613ec2019-05-30 15:39:38 +01001956 ALWAYS_INLINE bool SHR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001957 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001958 SetVReg(vregA, GetVReg(vregA) >> (GetVReg(B()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001959 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001960 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001961 }
1962
David Srbeckybd613ec2019-05-30 15:39:38 +01001963 ALWAYS_INLINE bool USHR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001964 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001965 SetVReg(vregA, static_cast<uint32_t>(GetVReg(vregA)) >> (GetVReg(B()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01001966 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001967 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001968 }
1969
David Srbeckybd613ec2019-05-30 15:39:38 +01001970 ALWAYS_INLINE bool AND_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001971 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001972 SetVReg(vregA, GetVReg(vregA) & GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001973 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001974 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001975 }
1976
David Srbeckybd613ec2019-05-30 15:39:38 +01001977 ALWAYS_INLINE bool OR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001978 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001979 SetVReg(vregA, GetVReg(vregA) | GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001980 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001981 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001982 }
1983
David Srbeckybd613ec2019-05-30 15:39:38 +01001984 ALWAYS_INLINE bool XOR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001985 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001986 SetVReg(vregA, GetVReg(vregA) ^ GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001987 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001988 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001989 }
1990
David Srbeckybd613ec2019-05-30 15:39:38 +01001991 ALWAYS_INLINE bool ADD_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001992 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001993 SetVRegLong(vregA, SafeAdd(GetVRegLong(vregA), GetVRegLong(B())));
David Srbecky6da82472018-10-23 14:03:08 +01001994 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001995 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001996 }
1997
David Srbeckybd613ec2019-05-30 15:39:38 +01001998 ALWAYS_INLINE bool SUB_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001999 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002000 SetVRegLong(vregA, SafeSub(GetVRegLong(vregA), GetVRegLong(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002001 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002002 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002003 }
2004
David Srbeckybd613ec2019-05-30 15:39:38 +01002005 ALWAYS_INLINE bool MUL_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002006 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002007 SetVRegLong(vregA, SafeMul(GetVRegLong(vregA), GetVRegLong(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002008 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002009 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002010 }
2011
David Srbeckybd613ec2019-05-30 15:39:38 +01002012 ALWAYS_INLINE bool DIV_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002013 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002014 DoLongDivide(shadow_frame, vregA, GetVRegLong(vregA), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002015 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
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_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002020 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002021 DoLongRemainder(shadow_frame, vregA, GetVRegLong(vregA), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002022 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002023 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002024 }
2025
David Srbeckybd613ec2019-05-30 15:39:38 +01002026 ALWAYS_INLINE bool AND_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002027 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002028 SetVRegLong(vregA, GetVRegLong(vregA) & GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002029 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002030 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002031 }
2032
David Srbeckybd613ec2019-05-30 15:39:38 +01002033 ALWAYS_INLINE bool OR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002034 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002035 SetVRegLong(vregA, GetVRegLong(vregA) | GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002036 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002037 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002038 }
2039
David Srbeckybd613ec2019-05-30 15:39:38 +01002040 ALWAYS_INLINE bool XOR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002041 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002042 SetVRegLong(vregA, GetVRegLong(vregA) ^ GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002043 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002044 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002045 }
2046
David Srbeckybd613ec2019-05-30 15:39:38 +01002047 ALWAYS_INLINE bool SHL_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002048 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002049 SetVRegLong(vregA, GetVRegLong(vregA) << (GetVReg(B()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01002050 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002051 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002052 }
2053
David Srbeckybd613ec2019-05-30 15:39:38 +01002054 ALWAYS_INLINE bool SHR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002055 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002056 SetVRegLong(vregA, GetVRegLong(vregA) >> (GetVReg(B()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01002057 inst = inst->Next_1xx();
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 USHR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002062 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002063 SetVRegLong(vregA, static_cast<uint64_t>(GetVRegLong(vregA)) >> (GetVReg(B()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01002064 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002065 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002066 }
2067
David Srbeckybd613ec2019-05-30 15:39:38 +01002068 ALWAYS_INLINE bool ADD_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002069 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002070 SetVRegFloat(vregA, GetVRegFloat(vregA) + GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002071 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002072 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002073 }
2074
David Srbeckybd613ec2019-05-30 15:39:38 +01002075 ALWAYS_INLINE bool SUB_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002076 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002077 SetVRegFloat(vregA, GetVRegFloat(vregA) - GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002078 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002079 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002080 }
2081
David Srbeckybd613ec2019-05-30 15:39:38 +01002082 ALWAYS_INLINE bool MUL_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002083 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002084 SetVRegFloat(vregA, GetVRegFloat(vregA) * GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002085 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002086 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002087 }
2088
David Srbeckybd613ec2019-05-30 15:39:38 +01002089 ALWAYS_INLINE bool DIV_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002090 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002091 SetVRegFloat(vregA, GetVRegFloat(vregA) / GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002092 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002093 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002094 }
2095
David Srbeckybd613ec2019-05-30 15:39:38 +01002096 ALWAYS_INLINE bool REM_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002097 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002098 SetVRegFloat(vregA, fmodf(GetVRegFloat(vregA), GetVRegFloat(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002099 inst = inst->Next_1xx();
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 ADD_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002104 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002105 SetVRegDouble(vregA, GetVRegDouble(vregA) + GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002106 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002107 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002108 }
2109
David Srbeckybd613ec2019-05-30 15:39:38 +01002110 ALWAYS_INLINE bool SUB_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002111 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002112 SetVRegDouble(vregA, GetVRegDouble(vregA) - GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002113 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002114 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002115 }
2116
David Srbeckybd613ec2019-05-30 15:39:38 +01002117 ALWAYS_INLINE bool MUL_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002118 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002119 SetVRegDouble(vregA, GetVRegDouble(vregA) * GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002120 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002121 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002122 }
2123
David Srbeckybd613ec2019-05-30 15:39:38 +01002124 ALWAYS_INLINE bool DIV_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002125 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002126 SetVRegDouble(vregA, GetVRegDouble(vregA) / GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002127 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002128 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002129 }
2130
David Srbeckybd613ec2019-05-30 15:39:38 +01002131 ALWAYS_INLINE bool REM_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002132 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002133 SetVRegDouble(vregA, fmod(GetVRegDouble(vregA), GetVRegDouble(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002134 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002135 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002136 }
2137
David Srbeckybd613ec2019-05-30 15:39:38 +01002138 ALWAYS_INLINE bool ADD_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002139 SetVReg(A(), SafeAdd(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01002140 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002141 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002142 }
2143
David Srbeckybd613ec2019-05-30 15:39:38 +01002144 ALWAYS_INLINE bool RSUB_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002145 SetVReg(A(), SafeSub(C(), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002146 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002147 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002148 }
2149
David Srbeckybd613ec2019-05-30 15:39:38 +01002150 ALWAYS_INLINE bool MUL_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002151 SetVReg(A(), SafeMul(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01002152 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002153 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002154 }
2155
David Srbeckybd613ec2019-05-30 15:39:38 +01002156 ALWAYS_INLINE bool DIV_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002157 bool success = DoIntDivide(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01002158 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002159 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002160 }
2161
David Srbeckybd613ec2019-05-30 15:39:38 +01002162 ALWAYS_INLINE bool REM_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002163 bool success = DoIntRemainder(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01002164 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002165 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002166 }
2167
David Srbeckybd613ec2019-05-30 15:39:38 +01002168 ALWAYS_INLINE bool AND_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002169 SetVReg(A(), GetVReg(B()) & C());
David Srbecky6da82472018-10-23 14:03:08 +01002170 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002171 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002172 }
2173
David Srbeckybd613ec2019-05-30 15:39:38 +01002174 ALWAYS_INLINE bool OR_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002175 SetVReg(A(), GetVReg(B()) | C());
David Srbecky6da82472018-10-23 14:03:08 +01002176 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002177 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002178 }
2179
David Srbeckybd613ec2019-05-30 15:39:38 +01002180 ALWAYS_INLINE bool XOR_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002181 SetVReg(A(), GetVReg(B()) ^ C());
David Srbecky6da82472018-10-23 14:03:08 +01002182 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002183 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002184 }
2185
David Srbeckybd613ec2019-05-30 15:39:38 +01002186 ALWAYS_INLINE bool ADD_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002187 SetVReg(A(), SafeAdd(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01002188 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002189 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002190 }
2191
David Srbeckybd613ec2019-05-30 15:39:38 +01002192 ALWAYS_INLINE bool RSUB_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002193 SetVReg(A(), SafeSub(C(), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002194 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002195 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002196 }
2197
David Srbeckybd613ec2019-05-30 15:39:38 +01002198 ALWAYS_INLINE bool MUL_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002199 SetVReg(A(), SafeMul(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01002200 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002201 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002202 }
2203
David Srbeckybd613ec2019-05-30 15:39:38 +01002204 ALWAYS_INLINE bool DIV_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002205 bool success = DoIntDivide(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01002206 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002207 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002208 }
2209
David Srbeckybd613ec2019-05-30 15:39:38 +01002210 ALWAYS_INLINE bool REM_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002211 bool success = DoIntRemainder(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01002212 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002213 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002214 }
2215
David Srbeckybd613ec2019-05-30 15:39:38 +01002216 ALWAYS_INLINE bool AND_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002217 SetVReg(A(), GetVReg(B()) & C());
David Srbecky6da82472018-10-23 14:03:08 +01002218 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002219 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002220 }
2221
David Srbeckybd613ec2019-05-30 15:39:38 +01002222 ALWAYS_INLINE bool OR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002223 SetVReg(A(), GetVReg(B()) | C());
David Srbecky6da82472018-10-23 14:03:08 +01002224 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002225 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002226 }
2227
David Srbeckybd613ec2019-05-30 15:39:38 +01002228 ALWAYS_INLINE bool XOR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002229 SetVReg(A(), GetVReg(B()) ^ C());
David Srbecky6da82472018-10-23 14:03:08 +01002230 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002231 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002232 }
2233
David Srbeckybd613ec2019-05-30 15:39:38 +01002234 ALWAYS_INLINE bool SHL_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002235 SetVReg(A(), GetVReg(B()) << (C() & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002236 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002237 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002238 }
2239
David Srbeckybd613ec2019-05-30 15:39:38 +01002240 ALWAYS_INLINE bool SHR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002241 SetVReg(A(), GetVReg(B()) >> (C() & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002242 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002243 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002244 }
2245
David Srbeckybd613ec2019-05-30 15:39:38 +01002246 ALWAYS_INLINE bool USHR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002247 SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (C() & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002248 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002249 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002250 }
2251
David Srbeckybd613ec2019-05-30 15:39:38 +01002252 ALWAYS_INLINE bool UNUSED_3E() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002253 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002254 }
2255
David Srbeckybd613ec2019-05-30 15:39:38 +01002256 ALWAYS_INLINE bool UNUSED_3F() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002257 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002258 }
2259
David Srbeckybd613ec2019-05-30 15:39:38 +01002260 ALWAYS_INLINE bool UNUSED_40() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002261 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002262 }
2263
David Srbeckybd613ec2019-05-30 15:39:38 +01002264 ALWAYS_INLINE bool UNUSED_41() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002265 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002266 }
2267
David Srbeckybd613ec2019-05-30 15:39:38 +01002268 ALWAYS_INLINE bool UNUSED_42() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002269 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002270 }
2271
David Srbeckybd613ec2019-05-30 15:39:38 +01002272 ALWAYS_INLINE bool UNUSED_43() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002273 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002274 }
2275
David Srbeckybd613ec2019-05-30 15:39:38 +01002276 ALWAYS_INLINE bool UNUSED_79() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002277 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002278 }
2279
David Srbeckybd613ec2019-05-30 15:39:38 +01002280 ALWAYS_INLINE bool UNUSED_7A() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002281 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002282 }
2283
David Srbeckybd613ec2019-05-30 15:39:38 +01002284 ALWAYS_INLINE bool UNUSED_F3() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002285 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002286 }
2287
David Srbeckybd613ec2019-05-30 15:39:38 +01002288 ALWAYS_INLINE bool UNUSED_F4() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002289 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002290 }
2291
David Srbeckybd613ec2019-05-30 15:39:38 +01002292 ALWAYS_INLINE bool UNUSED_F5() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002293 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002294 }
2295
David Srbeckybd613ec2019-05-30 15:39:38 +01002296 ALWAYS_INLINE bool UNUSED_F6() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002297 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002298 }
2299
David Srbeckybd613ec2019-05-30 15:39:38 +01002300 ALWAYS_INLINE bool UNUSED_F7() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002301 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002302 }
2303
David Srbeckybd613ec2019-05-30 15:39:38 +01002304 ALWAYS_INLINE bool UNUSED_F8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002305 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002306 }
2307
David Srbeckybd613ec2019-05-30 15:39:38 +01002308 ALWAYS_INLINE bool UNUSED_F9() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01002309 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01002310 }
2311
2312 ALWAYS_INLINE InstructionHandler(SwitchImplContext* ctx,
2313 const instrumentation::Instrumentation* instrumentation,
2314 Thread* self,
2315 ShadowFrame& shadow_frame,
2316 uint16_t dex_pc,
2317 const Instruction*& inst,
2318 uint16_t inst_data,
2319 bool& exit_interpreter_loop)
2320 : ctx(ctx),
2321 instrumentation(instrumentation),
2322 self(self),
2323 shadow_frame(shadow_frame),
2324 dex_pc(dex_pc),
2325 inst(inst),
2326 inst_data(inst_data),
2327 exit_interpreter_loop(exit_interpreter_loop) {
2328 }
2329
2330 private:
2331 static constexpr bool do_assignability_check = do_access_check;
2332
2333 const CodeItemDataAccessor& Accessor() { return ctx->accessor; }
2334 const uint16_t* Insns() { return ctx->accessor.Insns(); }
2335 JValue* ResultRegister() { return &ctx->result_register; }
2336
David Srbecky436f6c12019-05-22 13:28:42 +01002337 ALWAYS_INLINE int32_t A() { return inst->VRegA(kFormat, inst_data); }
2338 ALWAYS_INLINE int32_t B() { return inst->VRegB(kFormat, inst_data); }
2339 ALWAYS_INLINE int32_t C() { return inst->VRegC(kFormat); }
2340
David Srbecky6baf6442019-05-30 14:57:43 +01002341 int32_t GetVReg(size_t i) const { return shadow_frame.GetVReg(i); }
2342 int64_t GetVRegLong(size_t i) const { return shadow_frame.GetVRegLong(i); }
2343 float GetVRegFloat(size_t i) const { return shadow_frame.GetVRegFloat(i); }
2344 double GetVRegDouble(size_t i) const { return shadow_frame.GetVRegDouble(i); }
2345 ObjPtr<mirror::Object> GetVRegReference(size_t i) const REQUIRES_SHARED(Locks::mutator_lock_) {
2346 return shadow_frame.GetVRegReference(i);
2347 }
2348
2349 void SetVReg(size_t i, int32_t val) { shadow_frame.SetVReg(i, val); }
2350 void SetVRegLong(size_t i, int64_t val) { shadow_frame.SetVRegLong(i, val); }
2351 void SetVRegFloat(size_t i, float val) { shadow_frame.SetVRegFloat(i, val); }
2352 void SetVRegDouble(size_t i, double val) { shadow_frame.SetVRegDouble(i, val); }
2353 void SetVRegReference(size_t i, ObjPtr<mirror::Object> val)
2354 REQUIRES_SHARED(Locks::mutator_lock_) {
2355 shadow_frame.SetVRegReference(i, val);
2356 }
2357
David Srbecky6da82472018-10-23 14:03:08 +01002358 SwitchImplContext* const ctx;
2359 const instrumentation::Instrumentation* const instrumentation;
2360 Thread* const self;
2361 ShadowFrame& shadow_frame;
2362 uint32_t const dex_pc;
2363 const Instruction*& inst;
2364 uint16_t const inst_data;
2365 bool& exit_interpreter_loop;
2366};
2367
David Srbecky6da82472018-10-23 14:03:08 +01002368#undef BRANCH_INSTRUMENTATION
David Srbecky6da82472018-10-23 14:03:08 +01002369#undef POSSIBLY_HANDLE_PENDING_EXCEPTION
2370#undef POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE
2371#undef POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC
David Srbecky6da82472018-10-23 14:03:08 +01002372#undef HANDLE_PENDING_EXCEPTION
David Srbecky6da82472018-10-23 14:03:08 +01002373
Alex Light6f22e062018-10-05 15:05:12 -07002374// TODO On ASAN builds this function gets a huge stack frame. Since normally we run in the mterp
2375// this shouldn't cause any problems for stack overflow detection. Remove this once b/117341496 is
2376// fixed.
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002377template<bool do_access_check, bool transaction_active>
Alex Light6f22e062018-10-05 15:05:12 -07002378ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
David Srbecky946bb092018-03-09 17:23:01 +00002379 Thread* self = ctx->self;
2380 const CodeItemDataAccessor& accessor = ctx->accessor;
2381 ShadowFrame& shadow_frame = ctx->shadow_frame;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002382 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
2383 LOG(FATAL) << "Invalid shadow frame for interpreter use";
David Srbecky946bb092018-03-09 17:23:01 +00002384 ctx->result = JValue();
2385 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002386 }
2387 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002388
2389 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002390 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002391 const uint16_t* const insns = accessor.Insns();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002392 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002393 uint16_t inst_data;
Igor Murashkin6918bf12015-09-27 19:19:06 -07002394
Alex Light0aa7a5a2018-10-10 15:58:14 +00002395 DCHECK(!shadow_frame.GetForceRetryInstruction())
2396 << "Entered interpreter from invoke without retry instruction being handled!";
2397
David Srbecky6da82472018-10-23 14:03:08 +01002398 bool const interpret_one_instruction = ctx->interpret_one_instruction;
2399 while (true) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002400 dex_pc = inst->GetDexPc(insns);
2401 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -08002402 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002403 inst_data = inst->Fetch16(0);
David Srbeckya4a96af2018-10-31 16:34:58 +00002404 {
2405 bool exit_loop = false;
David Srbecky436f6c12019-05-22 13:28:42 +01002406 InstructionHandler<do_access_check, transaction_active, Instruction::kInvalidFormat> handler(
David Srbeckya4a96af2018-10-31 16:34:58 +00002407 ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, exit_loop);
2408 if (!handler.Preamble()) {
2409 if (UNLIKELY(exit_loop)) {
2410 return;
2411 }
2412 if (UNLIKELY(interpret_one_instruction)) {
2413 break;
2414 }
2415 continue;
2416 }
2417 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002418 switch (inst->Opcode(inst_data)) {
David Srbecky436f6c12019-05-22 13:28:42 +01002419#define OPCODE_CASE(OPCODE, OPCODE_NAME, pname, FORMAT, i, a, e, v) \
David Srbecky6da82472018-10-23 14:03:08 +01002420 case OPCODE: { \
2421 bool exit_loop = false; \
David Srbecky436f6c12019-05-22 13:28:42 +01002422 InstructionHandler<do_access_check, transaction_active, Instruction::FORMAT> handler( \
David Srbecky6da82472018-10-23 14:03:08 +01002423 ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, exit_loop); \
David Srbeckya4a96af2018-10-31 16:34:58 +00002424 handler.OPCODE_NAME(); \
David Srbecky6da82472018-10-23 14:03:08 +01002425 /* TODO: Advance 'inst' here, instead of explicitly in each handler */ \
2426 if (UNLIKELY(exit_loop)) { \
2427 return; \
2428 } \
2429 break; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002430 }
David Srbecky6da82472018-10-23 14:03:08 +01002431DEX_INSTRUCTION_LIST(OPCODE_CASE)
2432#undef OPCODE_CASE
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002433 }
David Srbecky6da82472018-10-23 14:03:08 +01002434 if (UNLIKELY(interpret_one_instruction)) {
David Srbeckya4a96af2018-10-31 16:34:58 +00002435 break;
David Srbecky6da82472018-10-23 14:03:08 +01002436 }
2437 }
David Srbeckya4a96af2018-10-31 16:34:58 +00002438 // Record where we stopped.
2439 shadow_frame.SetDexPC(inst->GetDexPc(insns));
2440 ctx->result = ctx->result_register;
2441 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002442} // NOLINT(readability/fn_size)
2443
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002444} // namespace interpreter
2445} // namespace art
David Srbecky2ee09ff2018-10-24 13:24:22 +01002446
2447#endif // ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_