blob: 26898387f0b7e6bc474ebde67f88988a7aa73778 [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
David Srbecky2ee09ff2018-10-24 13:24:22 +010017#ifndef ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
18#define ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
19
Andreas Gampe5e26eb12016-08-22 17:54:17 -070020#include "interpreter_switch_impl.h"
21
Andreas Gampe542451c2016-07-26 09:02:02 -070022#include "base/enums.h"
Alex Light49af7042019-05-29 18:30:33 -070023#include "base/globals.h"
Alex Light6f22e062018-10-05 15:05:12 -070024#include "base/memory_tool.h"
David Sehrc431b9d2018-03-02 12:01:51 -080025#include "base/quasi_atomic.h"
David Sehr9e734c72018-01-04 17:56:19 -080026#include "dex/dex_file_types.h"
David Srbecky6da82472018-10-23 14:03:08 +010027#include "dex/dex_instruction_list.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070028#include "experimental_flags.h"
Alex Light49af7042019-05-29 18:30:33 -070029#include "handle_scope.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020030#include "interpreter_common.h"
Alex Light49af7042019-05-29 18:30:33 -070031#include "interpreter/shadow_frame.h"
David Srbeckye3fc2d12018-11-30 13:41:14 +000032#include "jit/jit-inl.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070033#include "jvalue-inl.h"
Andreas Gampefd63bbf2018-10-29 12:55:35 -070034#include "mirror/string-alloc-inl.h"
Alex Light49af7042019-05-29 18:30:33 -070035#include "mirror/throwable.h"
Alex Lightb7c640d2019-03-20 15:52:13 -070036#include "monitor.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000037#include "nth_caller_visitor.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070038#include "safe_math.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010039#include "shadow_frame-inl.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000040#include "thread.h"
Alex Light49af7042019-05-29 18:30:33 -070041#include "verifier/method_verifier.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020042
43namespace art {
44namespace interpreter {
45
David Srbecky6da82472018-10-23 14:03:08 +010046// Short-lived helper class which executes single DEX bytecode. It is inlined by compiler.
David Srbecky8d335b62019-06-06 14:25:42 +010047// Any relevant execution information is stored in the fields - it should be kept to minimum.
48// All instance functions must be inlined so that the fields can be stored in registers.
David Srbecky6da82472018-10-23 14:03:08 +010049//
50// The function names must match the names from dex_instruction_list.h and have no arguments.
David Srbecky8d335b62019-06-06 14:25:42 +010051// Return value: The handlers must return false if the instruction throws or returns (exits).
David Srbecky47ad3762018-10-31 12:43:40 +000052//
David Srbecky436f6c12019-05-22 13:28:42 +010053template<bool do_access_check, bool transaction_active, Instruction::Format kFormat>
David Srbecky6da82472018-10-23 14:03:08 +010054class InstructionHandler {
55 public:
David Srbecky47ad3762018-10-31 12:43:40 +000056 ALWAYS_INLINE WARN_UNUSED bool CheckForceReturn()
57 REQUIRES_SHARED(Locks::mutator_lock_) {
Alex Lightb7c640d2019-03-20 15:52:13 -070058 if (PerformNonStandardReturn<kMonitorState>(self,
59 shadow_frame,
60 ctx->result,
61 instrumentation,
62 Accessor().InsSize(),
63 inst->GetDexPc(Insns()))) {
David Srbecky47ad3762018-10-31 12:43:40 +000064 exit_interpreter_loop = true;
65 return false;
66 }
67 return true;
68 }
69
David Srbecky8d335b62019-06-06 14:25:42 +010070 ALWAYS_INLINE WARN_UNUSED bool HandlePendingException()
David Srbecky47ad3762018-10-31 12:43:40 +000071 REQUIRES_SHARED(Locks::mutator_lock_) {
72 DCHECK(self->IsExceptionPending());
73 self->AllowThreadSuspension();
74 if (!CheckForceReturn()) {
75 return false;
76 }
David Srbecky8d335b62019-06-06 14:25:42 +010077 bool skip_event = shadow_frame.GetSkipNextExceptionEvent();
78 shadow_frame.SetSkipNextExceptionEvent(false);
79 if (!MoveToExceptionHandler(self, shadow_frame, skip_event ? nullptr : instrumentation)) {
David Srbecky47ad3762018-10-31 12:43:40 +000080 /* Structured locking is to be enforced for abnormal termination, too. */
81 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame);
David Srbecky47ad3762018-10-31 12:43:40 +000082 ctx->result = JValue(); /* Handled in caller. */
83 exit_interpreter_loop = true;
84 return false; // Return to caller.
85 }
86 if (!CheckForceReturn()) {
87 return false;
88 }
89 int32_t displacement =
90 static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc);
David Srbecky8867f3b2019-05-31 20:01:46 +010091 SetNextInstruction(inst->RelativeAt(displacement));
David Srbecky8d335b62019-06-06 14:25:42 +010092 return true;
David Srbecky47ad3762018-10-31 12:43:40 +000093 }
94
David Srbecky8d335b62019-06-06 14:25:42 +010095 ALWAYS_INLINE WARN_UNUSED bool PossiblyHandlePendingExceptionOnInvoke(bool is_exception_pending)
David Srbecky47ad3762018-10-31 12:43:40 +000096 REQUIRES_SHARED(Locks::mutator_lock_) {
97 if (UNLIKELY(shadow_frame.GetForceRetryInstruction())) {
98 /* Don't need to do anything except clear the flag and exception. We leave the */
99 /* instruction the same so it will be re-executed on the next go-around. */
100 DCHECK(inst->IsInvoke());
101 shadow_frame.SetForceRetryInstruction(false);
102 if (UNLIKELY(is_exception_pending)) {
103 DCHECK(self->IsExceptionPending());
104 if (kIsDebugBuild) {
105 LOG(WARNING) << "Suppressing exception for instruction-retry: "
106 << self->GetException()->Dump();
107 }
108 self->ClearException();
109 }
David Srbecky8867f3b2019-05-31 20:01:46 +0100110 SetNextInstruction(inst);
David Srbecky47ad3762018-10-31 12:43:40 +0000111 } else if (UNLIKELY(is_exception_pending)) {
112 /* Should have succeeded. */
113 DCHECK(!shadow_frame.GetForceRetryInstruction());
David Srbecky8d335b62019-06-06 14:25:42 +0100114 return false; // Pending exception.
David Srbecky47ad3762018-10-31 12:43:40 +0000115 }
116 return true;
117 }
118
119 ALWAYS_INLINE WARN_UNUSED bool HandleMonitorChecks()
120 REQUIRES_SHARED(Locks::mutator_lock_) {
121 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100122 return false; // Pending exception.
David Srbecky47ad3762018-10-31 12:43:40 +0000123 }
124 return true;
125 }
126
127 // Code to run before each dex instruction.
David Srbeckya4a96af2018-10-31 16:34:58 +0000128 ALWAYS_INLINE WARN_UNUSED bool Preamble()
David Srbecky47ad3762018-10-31 12:43:40 +0000129 REQUIRES_SHARED(Locks::mutator_lock_) {
130 /* We need to put this before & after the instrumentation to avoid having to put in a */
131 /* post-script macro. */
132 if (!CheckForceReturn()) {
133 return false;
134 }
135 if (UNLIKELY(instrumentation->HasDexPcListeners())) {
David Srbeckya4a96af2018-10-31 16:34:58 +0000136 uint8_t opcode = inst->Opcode(inst_data);
137 bool is_move_result_object = (opcode == Instruction::MOVE_RESULT_OBJECT);
138 JValue* save_ref = is_move_result_object ? &ctx->result_register : nullptr;
David Srbecky47ad3762018-10-31 12:43:40 +0000139 if (UNLIKELY(!DoDexPcMoveEvent(self,
140 Accessor(),
141 shadow_frame,
142 dex_pc,
143 instrumentation,
144 save_ref))) {
David Srbecky8d335b62019-06-06 14:25:42 +0100145 DCHECK(self->IsExceptionPending());
146 // Do not raise exception event if it is caused by other instrumentation event.
147 shadow_frame.SetSkipNextExceptionEvent(true);
148 return false; // Pending exception.
David Srbecky47ad3762018-10-31 12:43:40 +0000149 }
150 if (!CheckForceReturn()) {
151 return false;
152 }
153 }
154 return true;
155 }
156
157 ALWAYS_INLINE WARN_UNUSED bool BranchInstrumentation(int32_t offset)
158 REQUIRES_SHARED(Locks::mutator_lock_) {
159 if (UNLIKELY(instrumentation->HasBranchListeners())) {
160 instrumentation->Branch(self, shadow_frame.GetMethod(), dex_pc, offset);
161 }
162 JValue result;
163 if (jit::Jit::MaybeDoOnStackReplacement(self,
164 shadow_frame.GetMethod(),
165 dex_pc,
166 offset,
167 &result)) {
David Srbecky47ad3762018-10-31 12:43:40 +0000168 ctx->result = result;
169 exit_interpreter_loop = true;
170 return false;
171 }
172 return true;
173 }
174
175 ALWAYS_INLINE void HotnessUpdate()
176 REQUIRES_SHARED(Locks::mutator_lock_) {
177 jit::Jit* jit = Runtime::Current()->GetJit();
178 if (jit != nullptr) {
179 jit->AddSamples(self, shadow_frame.GetMethod(), 1, /*with_backedges=*/ true);
180 }
181 }
182
183 ALWAYS_INLINE WARN_UNUSED bool HandleAsyncException()
184 REQUIRES_SHARED(Locks::mutator_lock_) {
185 if (UNLIKELY(self->ObserveAsyncException())) {
David Srbecky8d335b62019-06-06 14:25:42 +0100186 return false; // Pending exception.
David Srbecky47ad3762018-10-31 12:43:40 +0000187 }
188 return true;
189 }
190
191 ALWAYS_INLINE void HandleBackwardBranch(int32_t offset)
192 REQUIRES_SHARED(Locks::mutator_lock_) {
193 if (IsBackwardBranch(offset)) {
194 HotnessUpdate();
195 /* Record new dex pc early to have consistent suspend point at loop header. */
David Srbeckyc56a23e2019-06-05 17:45:49 +0100196 shadow_frame.SetDexPC(next->GetDexPc(Insns()));
David Srbecky47ad3762018-10-31 12:43:40 +0000197 self->AllowThreadSuspension();
198 }
199 }
200
201 // Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
202 // the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
203 // to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
204 // jvmti-agents while handling breakpoint or single step events. We had to move this into its own
205 // function because it was making ExecuteSwitchImpl have too large a stack.
206 NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
207 const CodeItemDataAccessor& accessor,
208 const ShadowFrame& shadow_frame,
209 uint32_t dex_pc,
210 const instrumentation::Instrumentation* instrumentation,
211 JValue* save_ref)
212 REQUIRES_SHARED(Locks::mutator_lock_) {
213 DCHECK(instrumentation->HasDexPcListeners());
214 StackHandleScope<2> hs(self);
215 Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
216 mirror::Object* null_obj = nullptr;
217 HandleWrapper<mirror::Object> h(
218 hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
219 self->ClearException();
220 instrumentation->DexPcMovedEvent(self,
221 shadow_frame.GetThisObject(accessor.InsSize()),
222 shadow_frame.GetMethod(),
223 dex_pc);
224 if (UNLIKELY(self->IsExceptionPending())) {
225 // We got a new exception in the dex-pc-moved event.
226 // We just let this exception replace the old one.
227 // TODO It would be good to add the old exception to the
228 // suppressed exceptions of the new one if possible.
David Srbecky8d335b62019-06-06 14:25:42 +0100229 return false; // Pending exception.
David Srbecky47ad3762018-10-31 12:43:40 +0000230 } else {
231 if (UNLIKELY(!thr.IsNull())) {
232 self->SetException(thr.Get());
233 }
234 return true;
235 }
236 }
237
David Srbeckyee12e3a2019-06-03 15:18:57 +0100238 ALWAYS_INLINE WARN_UNUSED bool HandleReturn(JValue result) REQUIRES_SHARED(Locks::mutator_lock_) {
239 self->AllowThreadSuspension();
240 if (!HandleMonitorChecks()) {
241 return false;
242 }
243 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
244 !SendMethodExitEvents(self,
245 instrumentation,
246 shadow_frame,
247 shadow_frame.GetThisObject(Accessor().InsSize()),
248 shadow_frame.GetMethod(),
249 inst->GetDexPc(Insns()),
250 result))) {
David Srbecky8d335b62019-06-06 14:25:42 +0100251 DCHECK(self->IsExceptionPending());
252 // Do not raise exception event if it is caused by other instrumentation event.
253 shadow_frame.SetSkipNextExceptionEvent(true);
254 return false; // Pending exception.
David Srbeckyee12e3a2019-06-03 15:18:57 +0100255 }
256 ctx->result = result;
257 exit_interpreter_loop = true;
David Srbecky8d335b62019-06-06 14:25:42 +0100258 return false;
David Srbeckyee12e3a2019-06-03 15:18:57 +0100259 }
260
261 ALWAYS_INLINE WARN_UNUSED bool HandleGoto(int32_t offset) REQUIRES_SHARED(Locks::mutator_lock_) {
262 if (!HandleAsyncException()) {
263 return false;
264 }
David Srbecky8d335b62019-06-06 14:25:42 +0100265 if (!BranchInstrumentation(offset)) {
266 return false;
267 }
David Srbecky8867f3b2019-05-31 20:01:46 +0100268 SetNextInstruction(inst->RelativeAt(offset));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100269 HandleBackwardBranch(offset);
270 return true;
271 }
272
273#pragma clang diagnostic push
274#pragma clang diagnostic ignored "-Wfloat-equal"
275
276 template<typename T>
277 ALWAYS_INLINE WARN_UNUSED bool HandleCmpl(T val1, T val2) REQUIRES_SHARED(Locks::mutator_lock_) {
278 int32_t result;
279 if (val1 > val2) {
280 result = 1;
281 } else if (val1 == val2) {
282 result = 0;
283 } else {
284 result = -1;
285 }
286 SetVReg(A(), result);
David Srbeckyee12e3a2019-06-03 15:18:57 +0100287 return true;
288 }
289
290 // Returns the same result as the function above. It only differs for NaN values.
291 template<typename T>
292 ALWAYS_INLINE WARN_UNUSED bool HandleCmpg(T val1, T val2) REQUIRES_SHARED(Locks::mutator_lock_) {
293 int32_t result;
294 if (val1 < val2) {
295 result = -1;
296 } else if (val1 == val2) {
297 result = 0;
298 } else {
299 result = 1;
300 }
301 SetVReg(A(), result);
David Srbeckyee12e3a2019-06-03 15:18:57 +0100302 return true;
303 }
304
305#pragma clang diagnostic pop
306
307 ALWAYS_INLINE WARN_UNUSED bool HandleIf(bool cond, int32_t offset)
308 REQUIRES_SHARED(Locks::mutator_lock_) {
309 if (cond) {
David Srbecky8d335b62019-06-06 14:25:42 +0100310 if (!BranchInstrumentation(offset)) {
311 return false;
312 }
David Srbecky8867f3b2019-05-31 20:01:46 +0100313 SetNextInstruction(inst->RelativeAt(offset));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100314 HandleBackwardBranch(offset);
315 } else {
David Srbecky8d335b62019-06-06 14:25:42 +0100316 if (!BranchInstrumentation(2)) {
317 return false;
318 }
David Srbeckyee12e3a2019-06-03 15:18:57 +0100319 }
320 return true;
321 }
322
David Srbecky1332c262019-06-04 13:13:37 +0100323 template<typename ArrayType, typename SetVRegFn>
324 ALWAYS_INLINE bool HandleAGet(SetVRegFn setVReg) REQUIRES_SHARED(Locks::mutator_lock_) {
325 ObjPtr<mirror::Object> a = GetVRegReference(B());
326 if (UNLIKELY(a == nullptr)) {
327 ThrowNullPointerExceptionFromInterpreter();
David Srbecky8d335b62019-06-06 14:25:42 +0100328 return false; // Pending exception.
David Srbecky1332c262019-06-04 13:13:37 +0100329 }
330 int32_t index = GetVReg(C());
331 ObjPtr<ArrayType> array = ObjPtr<ArrayType>::DownCast(a);
332 if (UNLIKELY(!array->CheckIsValidIndex(index))) {
David Srbecky8d335b62019-06-06 14:25:42 +0100333 return false; // Pending exception.
David Srbecky1332c262019-06-04 13:13:37 +0100334 } else {
335 (this->*setVReg)(A(), array->GetWithoutChecks(index));
David Srbecky1332c262019-06-04 13:13:37 +0100336 }
337 return true;
338 }
339
340 template<typename ArrayType, typename T>
341 ALWAYS_INLINE bool HandleAPut(T value) REQUIRES_SHARED(Locks::mutator_lock_) {
342 ObjPtr<mirror::Object> a = GetVRegReference(B());
343 if (UNLIKELY(a == nullptr)) {
344 ThrowNullPointerExceptionFromInterpreter();
David Srbecky8d335b62019-06-06 14:25:42 +0100345 return false; // Pending exception.
David Srbecky1332c262019-06-04 13:13:37 +0100346 }
347 int32_t index = GetVReg(C());
348 ObjPtr<ArrayType> array = ObjPtr<ArrayType>::DownCast(a);
349 if (UNLIKELY(!array->CheckIsValidIndex(index))) {
David Srbecky8d335b62019-06-06 14:25:42 +0100350 return false; // Pending exception.
David Srbecky1332c262019-06-04 13:13:37 +0100351 } else {
352 array->template SetWithoutChecks<transaction_active>(index, value);
David Srbecky1332c262019-06-04 13:13:37 +0100353 }
354 return true;
355 }
356
David Srbeckyee12e3a2019-06-03 15:18:57 +0100357 template<FindFieldType find_type, Primitive::Type field_type>
358 ALWAYS_INLINE WARN_UNUSED bool HandleGet() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky8d335b62019-06-06 14:25:42 +0100359 return DoFieldGet<find_type, field_type, do_access_check, transaction_active>(
David Srbeckyee12e3a2019-06-03 15:18:57 +0100360 self, shadow_frame, inst, inst_data);
David Srbeckyee12e3a2019-06-03 15:18:57 +0100361 }
362
363 template<Primitive::Type field_type>
364 ALWAYS_INLINE WARN_UNUSED bool HandleGetQuick() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky8d335b62019-06-06 14:25:42 +0100365 return DoIGetQuick<field_type>(shadow_frame, inst, inst_data);
David Srbeckyee12e3a2019-06-03 15:18:57 +0100366 }
367
368 template<FindFieldType find_type, Primitive::Type field_type>
369 ALWAYS_INLINE WARN_UNUSED bool HandlePut() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky8d335b62019-06-06 14:25:42 +0100370 return DoFieldPut<find_type, field_type, do_access_check, transaction_active>(
David Srbeckyee12e3a2019-06-03 15:18:57 +0100371 self, shadow_frame, inst, inst_data);
David Srbeckyee12e3a2019-06-03 15:18:57 +0100372 }
373
374 template<Primitive::Type field_type>
375 ALWAYS_INLINE WARN_UNUSED bool HandlePutQuick() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky8d335b62019-06-06 14:25:42 +0100376 return DoIPutQuick<field_type, transaction_active>(
David Srbeckyee12e3a2019-06-03 15:18:57 +0100377 shadow_frame, inst, inst_data);
David Srbeckyee12e3a2019-06-03 15:18:57 +0100378 }
379
380 template<InvokeType type, bool is_range, bool is_quick = false>
381 ALWAYS_INLINE WARN_UNUSED bool HandleInvoke() REQUIRES_SHARED(Locks::mutator_lock_) {
382 bool success = DoInvoke<type, is_range, do_access_check, /*is_mterp=*/ false, is_quick>(
383 self, shadow_frame, inst, inst_data, ResultRegister());
David Srbecky8d335b62019-06-06 14:25:42 +0100384 return PossiblyHandlePendingExceptionOnInvoke(!success);
David Srbeckyee12e3a2019-06-03 15:18:57 +0100385 }
386
387 ALWAYS_INLINE WARN_UNUSED bool HandleUnused() REQUIRES_SHARED(Locks::mutator_lock_) {
388 UnexpectedOpcode(inst, shadow_frame);
389 return true;
390 }
391
David Srbeckybd613ec2019-05-30 15:39:38 +0100392 ALWAYS_INLINE bool NOP() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100393 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100394 }
395
David Srbeckybd613ec2019-05-30 15:39:38 +0100396 ALWAYS_INLINE bool MOVE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100397 SetVReg(A(), GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100398 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100399 }
400
David Srbeckybd613ec2019-05-30 15:39:38 +0100401 ALWAYS_INLINE bool MOVE_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100402 SetVReg(A(), GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100403 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100404 }
405
David Srbeckybd613ec2019-05-30 15:39:38 +0100406 ALWAYS_INLINE bool MOVE_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100407 SetVReg(A(), GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100408 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100409 }
410
David Srbeckybd613ec2019-05-30 15:39:38 +0100411 ALWAYS_INLINE bool MOVE_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100412 SetVRegLong(A(), GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100413 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100414 }
415
David Srbeckybd613ec2019-05-30 15:39:38 +0100416 ALWAYS_INLINE bool MOVE_WIDE_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100417 SetVRegLong(A(), GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100418 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100419 }
420
David Srbeckybd613ec2019-05-30 15:39:38 +0100421 ALWAYS_INLINE bool MOVE_WIDE_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100422 SetVRegLong(A(), GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100423 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100424 }
425
David Srbeckybd613ec2019-05-30 15:39:38 +0100426 ALWAYS_INLINE bool MOVE_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100427 SetVRegReference(A(), GetVRegReference(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100428 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100429 }
430
David Srbeckybd613ec2019-05-30 15:39:38 +0100431 ALWAYS_INLINE bool MOVE_OBJECT_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100432 SetVRegReference(A(), GetVRegReference(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100433 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100434 }
435
David Srbeckybd613ec2019-05-30 15:39:38 +0100436 ALWAYS_INLINE bool MOVE_OBJECT_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100437 SetVRegReference(A(), GetVRegReference(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +0100438 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100439 }
440
David Srbeckybd613ec2019-05-30 15:39:38 +0100441 ALWAYS_INLINE bool MOVE_RESULT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100442 SetVReg(A(), ResultRegister()->GetI());
David Srbeckybd613ec2019-05-30 15:39:38 +0100443 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100444 }
445
David Srbeckybd613ec2019-05-30 15:39:38 +0100446 ALWAYS_INLINE bool MOVE_RESULT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100447 SetVRegLong(A(), ResultRegister()->GetJ());
David Srbeckybd613ec2019-05-30 15:39:38 +0100448 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100449 }
450
David Srbeckybd613ec2019-05-30 15:39:38 +0100451 ALWAYS_INLINE bool MOVE_RESULT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100452 SetVRegReference(A(), ResultRegister()->GetL());
David Srbeckybd613ec2019-05-30 15:39:38 +0100453 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100454 }
455
David Srbeckybd613ec2019-05-30 15:39:38 +0100456 ALWAYS_INLINE bool MOVE_EXCEPTION() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100457 ObjPtr<mirror::Throwable> exception = self->GetException();
458 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
David Srbecky6baf6442019-05-30 14:57:43 +0100459 SetVRegReference(A(), exception);
David Srbecky6da82472018-10-23 14:03:08 +0100460 self->ClearException();
David Srbeckybd613ec2019-05-30 15:39:38 +0100461 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100462 }
463
David Srbeckybd613ec2019-05-30 15:39:38 +0100464 ALWAYS_INLINE bool RETURN_VOID_NO_BARRIER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100465 JValue result;
David Srbeckyee12e3a2019-06-03 15:18:57 +0100466 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100467 }
468
David Srbeckybd613ec2019-05-30 15:39:38 +0100469 ALWAYS_INLINE bool RETURN_VOID() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100470 QuasiAtomic::ThreadFenceForConstructor();
471 JValue result;
David Srbeckyee12e3a2019-06-03 15:18:57 +0100472 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100473 }
474
David Srbeckybd613ec2019-05-30 15:39:38 +0100475 ALWAYS_INLINE bool RETURN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100476 JValue result;
477 result.SetJ(0);
David Srbecky6baf6442019-05-30 14:57:43 +0100478 result.SetI(GetVReg(A()));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100479 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100480 }
481
David Srbeckybd613ec2019-05-30 15:39:38 +0100482 ALWAYS_INLINE bool RETURN_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100483 JValue result;
David Srbecky6baf6442019-05-30 14:57:43 +0100484 result.SetJ(GetVRegLong(A()));
David Srbeckyee12e3a2019-06-03 15:18:57 +0100485 return HandleReturn(result);
David Srbecky6da82472018-10-23 14:03:08 +0100486 }
487
David Srbeckybd613ec2019-05-30 15:39:38 +0100488 ALWAYS_INLINE bool RETURN_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100489 JValue result;
490 self->AllowThreadSuspension();
David Srbecky47ad3762018-10-31 12:43:40 +0000491 if (!HandleMonitorChecks()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100492 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000493 }
David Srbeckyd6f579c2019-05-29 18:09:30 +0100494 const size_t ref_idx = A();
David Srbecky6baf6442019-05-30 14:57:43 +0100495 ObjPtr<mirror::Object> obj_result = GetVRegReference(ref_idx);
David Srbecky6da82472018-10-23 14:03:08 +0100496 if (do_assignability_check && obj_result != nullptr) {
497 ObjPtr<mirror::Class> return_type = shadow_frame.GetMethod()->ResolveReturnType();
498 // Re-load since it might have moved.
David Srbecky6baf6442019-05-30 14:57:43 +0100499 obj_result = GetVRegReference(ref_idx);
David Srbecky6da82472018-10-23 14:03:08 +0100500 if (return_type == nullptr) {
501 // Return the pending exception.
David Srbecky8d335b62019-06-06 14:25:42 +0100502 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100503 }
504 if (!obj_result->VerifierInstanceOf(return_type)) {
505 // This should never happen.
506 std::string temp1, temp2;
507 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
508 "Returning '%s' that is not instance of return type '%s'",
509 obj_result->GetClass()->GetDescriptor(&temp1),
510 return_type->GetDescriptor(&temp2));
David Srbecky8d335b62019-06-06 14:25:42 +0100511 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100512 }
513 }
Alex Lightb7c640d2019-03-20 15:52:13 -0700514 StackHandleScope<1> hs(self);
515 MutableHandle<mirror::Object> h_result(hs.NewHandle(obj_result));
David Srbecky6da82472018-10-23 14:03:08 +0100516 result.SetL(obj_result);
517 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
518 !SendMethodExitEvents(self,
519 instrumentation,
520 shadow_frame,
521 shadow_frame.GetThisObject(Accessor().InsSize()),
522 shadow_frame.GetMethod(),
523 inst->GetDexPc(Insns()),
Alex Lightb7c640d2019-03-20 15:52:13 -0700524 h_result))) {
David Srbecky8d335b62019-06-06 14:25:42 +0100525 DCHECK(self->IsExceptionPending());
526 // Do not raise exception event if it is caused by other instrumentation event.
527 shadow_frame.SetSkipNextExceptionEvent(true);
528 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100529 }
Alex Lightb7c640d2019-03-20 15:52:13 -0700530 // Re-load since it might have moved or been replaced during the MethodExitEvent.
531 result.SetL(h_result.Get());
David Srbecky6da82472018-10-23 14:03:08 +0100532 ctx->result = result;
533 exit_interpreter_loop = true;
David Srbecky8d335b62019-06-06 14:25:42 +0100534 return false;
David Srbecky6da82472018-10-23 14:03:08 +0100535 }
536
David Srbeckybd613ec2019-05-30 15:39:38 +0100537 ALWAYS_INLINE bool CONST_4() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100538 uint4_t dst = inst->VRegA_11n(inst_data);
539 int4_t val = inst->VRegB_11n(inst_data);
David Srbecky6baf6442019-05-30 14:57:43 +0100540 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100541 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100542 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100543 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100544 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100545 }
546
David Srbeckybd613ec2019-05-30 15:39:38 +0100547 ALWAYS_INLINE bool CONST_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100548 uint8_t dst = A();
549 int16_t val = B();
David Srbecky6baf6442019-05-30 14:57:43 +0100550 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100551 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100552 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100553 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100554 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100555 }
556
David Srbeckybd613ec2019-05-30 15:39:38 +0100557 ALWAYS_INLINE bool CONST() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100558 uint8_t dst = A();
559 int32_t val = B();
David Srbecky6baf6442019-05-30 14:57:43 +0100560 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100561 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100562 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100563 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100564 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100565 }
566
David Srbeckybd613ec2019-05-30 15:39:38 +0100567 ALWAYS_INLINE bool CONST_HIGH16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100568 uint8_t dst = A();
569 int32_t val = static_cast<int32_t>(B() << 16);
David Srbecky6baf6442019-05-30 14:57:43 +0100570 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100571 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100572 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100573 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100574 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100575 }
576
David Srbeckybd613ec2019-05-30 15:39:38 +0100577 ALWAYS_INLINE bool CONST_WIDE_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100578 SetVRegLong(A(), B());
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 CONST_WIDE_32() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100583 SetVRegLong(A(), B());
David Srbeckybd613ec2019-05-30 15:39:38 +0100584 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100585 }
586
David Srbeckybd613ec2019-05-30 15:39:38 +0100587 ALWAYS_INLINE bool CONST_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100588 SetVRegLong(A(), inst->WideVRegB());
David Srbeckybd613ec2019-05-30 15:39:38 +0100589 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100590 }
591
David Srbeckybd613ec2019-05-30 15:39:38 +0100592 ALWAYS_INLINE bool CONST_WIDE_HIGH16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100593 SetVRegLong(A(), static_cast<uint64_t>(B()) << 48);
David Srbeckybd613ec2019-05-30 15:39:38 +0100594 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100595 }
596
David Srbeckybd613ec2019-05-30 15:39:38 +0100597 ALWAYS_INLINE bool CONST_STRING() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100598 ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, dex::StringIndex(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100599 if (UNLIKELY(s == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100600 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100601 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100602 SetVRegReference(A(), s);
David Srbecky6da82472018-10-23 14:03:08 +0100603 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100604 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100605 }
606
David Srbeckybd613ec2019-05-30 15:39:38 +0100607 ALWAYS_INLINE bool CONST_STRING_JUMBO() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100608 ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, dex::StringIndex(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100609 if (UNLIKELY(s == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100610 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100611 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100612 SetVRegReference(A(), s);
David Srbecky6da82472018-10-23 14:03:08 +0100613 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100614 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100615 }
616
David Srbeckybd613ec2019-05-30 15:39:38 +0100617 ALWAYS_INLINE bool CONST_CLASS() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100618 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100619 shadow_frame.GetMethod(),
620 self,
621 false,
622 do_access_check);
623 if (UNLIKELY(c == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100624 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100625 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100626 SetVRegReference(A(), c);
David Srbecky6da82472018-10-23 14:03:08 +0100627 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100628 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100629 }
630
David Srbeckybd613ec2019-05-30 15:39:38 +0100631 ALWAYS_INLINE bool CONST_METHOD_HANDLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100632 ClassLinker* cl = Runtime::Current()->GetClassLinker();
633 ObjPtr<mirror::MethodHandle> mh = cl->ResolveMethodHandle(self,
David Srbeckyd6f579c2019-05-29 18:09:30 +0100634 B(),
David Srbecky6da82472018-10-23 14:03:08 +0100635 shadow_frame.GetMethod());
636 if (UNLIKELY(mh == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100637 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100638 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100639 SetVRegReference(A(), mh);
David Srbecky6da82472018-10-23 14:03:08 +0100640 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100641 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100642 }
643
David Srbeckybd613ec2019-05-30 15:39:38 +0100644 ALWAYS_INLINE bool CONST_METHOD_TYPE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100645 ClassLinker* cl = Runtime::Current()->GetClassLinker();
646 ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(self,
David Srbeckyd6f579c2019-05-29 18:09:30 +0100647 dex::ProtoIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100648 shadow_frame.GetMethod());
649 if (UNLIKELY(mt == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100650 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100651 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100652 SetVRegReference(A(), mt);
David Srbecky6da82472018-10-23 14:03:08 +0100653 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100654 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100655 }
656
David Srbeckybd613ec2019-05-30 15:39:38 +0100657 ALWAYS_INLINE bool MONITOR_ENTER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000658 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100659 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000660 }
David Srbecky6baf6442019-05-30 14:57:43 +0100661 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100662 if (UNLIKELY(obj == nullptr)) {
663 ThrowNullPointerExceptionFromInterpreter();
David Srbecky8d335b62019-06-06 14:25:42 +0100664 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100665 } else {
666 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
David Srbecky8d335b62019-06-06 14:25:42 +0100667 return !self->IsExceptionPending();
David Srbecky6da82472018-10-23 14:03:08 +0100668 }
669 }
670
David Srbeckybd613ec2019-05-30 15:39:38 +0100671 ALWAYS_INLINE bool MONITOR_EXIT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000672 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100673 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000674 }
David Srbecky6baf6442019-05-30 14:57:43 +0100675 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100676 if (UNLIKELY(obj == nullptr)) {
677 ThrowNullPointerExceptionFromInterpreter();
David Srbecky8d335b62019-06-06 14:25:42 +0100678 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100679 } else {
680 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
David Srbecky8d335b62019-06-06 14:25:42 +0100681 return !self->IsExceptionPending();
David Srbecky6da82472018-10-23 14:03:08 +0100682 }
683 }
684
David Srbeckybd613ec2019-05-30 15:39:38 +0100685 ALWAYS_INLINE bool CHECK_CAST() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100686 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100687 shadow_frame.GetMethod(),
688 self,
689 false,
690 do_access_check);
691 if (UNLIKELY(c == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100692 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100693 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100694 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100695 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
696 ThrowClassCastException(c, obj->GetClass());
David Srbecky8d335b62019-06-06 14:25:42 +0100697 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100698 }
699 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100700 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100701 }
702
David Srbeckybd613ec2019-05-30 15:39:38 +0100703 ALWAYS_INLINE bool INSTANCE_OF() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100704 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(C()),
David Srbecky6da82472018-10-23 14:03:08 +0100705 shadow_frame.GetMethod(),
706 self,
707 false,
708 do_access_check);
709 if (UNLIKELY(c == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100710 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100711 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100712 ObjPtr<mirror::Object> obj = GetVRegReference(B());
713 SetVReg(A(), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
David Srbecky6da82472018-10-23 14:03:08 +0100714 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100715 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100716 }
717
David Srbeckybd613ec2019-05-30 15:39:38 +0100718 ALWAYS_INLINE bool ARRAY_LENGTH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100719 ObjPtr<mirror::Object> array = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +0100720 if (UNLIKELY(array == nullptr)) {
721 ThrowNullPointerExceptionFromInterpreter();
David Srbecky8d335b62019-06-06 14:25:42 +0100722 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100723 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100724 SetVReg(A(), array->AsArray()->GetLength());
David Srbecky6da82472018-10-23 14:03:08 +0100725 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100726 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100727 }
728
David Srbeckybd613ec2019-05-30 15:39:38 +0100729 ALWAYS_INLINE bool NEW_INSTANCE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100730 ObjPtr<mirror::Object> obj = nullptr;
David Srbeckyd6f579c2019-05-29 18:09:30 +0100731 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100732 shadow_frame.GetMethod(),
733 self,
734 false,
735 do_access_check);
736 if (LIKELY(c != nullptr)) {
Vladimir Marko64b56032019-06-20 15:52:39 +0100737 // Don't allow finalizable objects to be allocated during a transaction since these can't
738 // be finalized without a started runtime.
739 if (transaction_active && c->IsFinalizable()) {
740 AbortTransactionF(self,
741 "Allocating finalizable object in transaction: %s",
742 c->PrettyDescriptor().c_str());
David Srbecky8d335b62019-06-06 14:25:42 +0100743 return false; // Pending exception.
Vladimir Marko64b56032019-06-20 15:52:39 +0100744 }
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100745 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
David Srbecky6da82472018-10-23 14:03:08 +0100746 if (UNLIKELY(c->IsStringClass())) {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100747 obj = mirror::String::AllocEmptyString(self, allocator_type);
David Srbecky6da82472018-10-23 14:03:08 +0100748 } else {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100749 obj = AllocObjectFromCode(c, self, allocator_type);
David Srbecky6da82472018-10-23 14:03:08 +0100750 }
751 }
752 if (UNLIKELY(obj == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100753 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100754 } else {
755 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
David Srbecky6baf6442019-05-30 14:57:43 +0100756 SetVRegReference(A(), obj);
David Srbecky6da82472018-10-23 14:03:08 +0100757 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100758 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100759 }
760
David Srbeckybd613ec2019-05-30 15:39:38 +0100761 ALWAYS_INLINE bool NEW_ARRAY() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100762 int32_t length = GetVReg(B());
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100763 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check>(
David Srbeckyd6f579c2019-05-29 18:09:30 +0100764 dex::TypeIndex(C()),
David Srbecky6da82472018-10-23 14:03:08 +0100765 length,
766 shadow_frame.GetMethod(),
767 self,
768 Runtime::Current()->GetHeap()->GetCurrentAllocator());
769 if (UNLIKELY(obj == nullptr)) {
David Srbecky8d335b62019-06-06 14:25:42 +0100770 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100771 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100772 SetVRegReference(A(), obj);
David Srbecky6da82472018-10-23 14:03:08 +0100773 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100774 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100775 }
776
David Srbeckybd613ec2019-05-30 15:39:38 +0100777 ALWAYS_INLINE bool FILLED_NEW_ARRAY() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky8d335b62019-06-06 14:25:42 +0100778 return DoFilledNewArray<false, do_access_check, transaction_active>(
779 inst, shadow_frame, self, ResultRegister());
David Srbecky6da82472018-10-23 14:03:08 +0100780 }
781
David Srbeckybd613ec2019-05-30 15:39:38 +0100782 ALWAYS_INLINE bool FILLED_NEW_ARRAY_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky8d335b62019-06-06 14:25:42 +0100783 return DoFilledNewArray<true, do_access_check, transaction_active>(
784 inst, shadow_frame, self, ResultRegister());
David Srbecky6da82472018-10-23 14:03:08 +0100785 }
786
David Srbeckybd613ec2019-05-30 15:39:38 +0100787 ALWAYS_INLINE bool FILL_ARRAY_DATA() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100788 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + B();
David Srbecky6da82472018-10-23 14:03:08 +0100789 const Instruction::ArrayDataPayload* payload =
790 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
David Srbecky6baf6442019-05-30 14:57:43 +0100791 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky8d335b62019-06-06 14:25:42 +0100792 if (!FillArrayData(obj, payload)) {
793 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100794 }
795 if (transaction_active) {
796 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
797 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100798 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100799 }
800
David Srbeckybd613ec2019-05-30 15:39:38 +0100801 ALWAYS_INLINE bool THROW() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000802 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100803 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000804 }
David Srbecky6baf6442019-05-30 14:57:43 +0100805 ObjPtr<mirror::Object> exception = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100806 if (UNLIKELY(exception == nullptr)) {
807 ThrowNullPointerException("throw with null exception");
808 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
809 // This should never happen.
810 std::string temp;
811 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
812 "Throwing '%s' that is not instance of Throwable",
813 exception->GetClass()->GetDescriptor(&temp));
814 } else {
815 self->SetException(exception->AsThrowable());
816 }
David Srbecky8d335b62019-06-06 14:25:42 +0100817 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100818 }
819
David Srbeckybd613ec2019-05-30 15:39:38 +0100820 ALWAYS_INLINE bool GOTO() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100821 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +0100822 }
823
David Srbeckybd613ec2019-05-30 15:39:38 +0100824 ALWAYS_INLINE bool GOTO_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100825 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +0100826 }
827
David Srbeckybd613ec2019-05-30 15:39:38 +0100828 ALWAYS_INLINE bool GOTO_32() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100829 return HandleGoto(A());
David Srbecky6da82472018-10-23 14:03:08 +0100830 }
831
David Srbeckybd613ec2019-05-30 15:39:38 +0100832 ALWAYS_INLINE bool PACKED_SWITCH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100833 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
David Srbecky8d335b62019-06-06 14:25:42 +0100834 if (!BranchInstrumentation(offset)) {
835 return false;
836 }
David Srbecky8867f3b2019-05-31 20:01:46 +0100837 SetNextInstruction(inst->RelativeAt(offset));
David Srbecky47ad3762018-10-31 12:43:40 +0000838 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +0100839 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100840 }
841
David Srbeckybd613ec2019-05-30 15:39:38 +0100842 ALWAYS_INLINE bool SPARSE_SWITCH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100843 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
David Srbecky8d335b62019-06-06 14:25:42 +0100844 if (!BranchInstrumentation(offset)) {
845 return false;
846 }
David Srbecky8867f3b2019-05-31 20:01:46 +0100847 SetNextInstruction(inst->RelativeAt(offset));
David Srbecky47ad3762018-10-31 12:43:40 +0000848 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +0100849 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100850 }
851
David Srbeckybd613ec2019-05-30 15:39:38 +0100852 ALWAYS_INLINE bool CMPL_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100853 return HandleCmpl<float>(GetVRegFloat(B()), GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +0100854 }
855
David Srbeckybd613ec2019-05-30 15:39:38 +0100856 ALWAYS_INLINE bool CMPG_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100857 return HandleCmpg<float>(GetVRegFloat(B()), GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +0100858 }
859
David Srbeckybd613ec2019-05-30 15:39:38 +0100860 ALWAYS_INLINE bool CMPL_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100861 return HandleCmpl<double>(GetVRegDouble(B()), GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +0100862 }
863
David Srbeckybd613ec2019-05-30 15:39:38 +0100864 ALWAYS_INLINE bool CMPG_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100865 return HandleCmpg<double>(GetVRegDouble(B()), GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +0100866 }
867
David Srbeckybd613ec2019-05-30 15:39:38 +0100868 ALWAYS_INLINE bool CMP_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100869 return HandleCmpl<int64_t>(GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +0100870 }
871
David Srbeckybd613ec2019-05-30 15:39:38 +0100872 ALWAYS_INLINE bool IF_EQ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100873 return HandleIf(GetVReg(A()) == GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +0100874 }
875
David Srbeckybd613ec2019-05-30 15:39:38 +0100876 ALWAYS_INLINE bool IF_NE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100877 return HandleIf(GetVReg(A()) != GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +0100878 }
879
David Srbeckybd613ec2019-05-30 15:39:38 +0100880 ALWAYS_INLINE bool IF_LT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100881 return HandleIf(GetVReg(A()) < GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +0100882 }
883
David Srbeckybd613ec2019-05-30 15:39:38 +0100884 ALWAYS_INLINE bool IF_GE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100885 return HandleIf(GetVReg(A()) >= GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +0100886 }
887
David Srbeckybd613ec2019-05-30 15:39:38 +0100888 ALWAYS_INLINE bool IF_GT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100889 return HandleIf(GetVReg(A()) > GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +0100890 }
891
David Srbeckybd613ec2019-05-30 15:39:38 +0100892 ALWAYS_INLINE bool IF_LE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100893 return HandleIf(GetVReg(A()) <= GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +0100894 }
895
David Srbeckybd613ec2019-05-30 15:39:38 +0100896 ALWAYS_INLINE bool IF_EQZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100897 return HandleIf(GetVReg(A()) == 0, B());
David Srbecky6da82472018-10-23 14:03:08 +0100898 }
899
David Srbeckybd613ec2019-05-30 15:39:38 +0100900 ALWAYS_INLINE bool IF_NEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100901 return HandleIf(GetVReg(A()) != 0, B());
David Srbecky6da82472018-10-23 14:03:08 +0100902 }
903
David Srbeckybd613ec2019-05-30 15:39:38 +0100904 ALWAYS_INLINE bool IF_LTZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100905 return HandleIf(GetVReg(A()) < 0, B());
David Srbecky6da82472018-10-23 14:03:08 +0100906 }
907
David Srbeckybd613ec2019-05-30 15:39:38 +0100908 ALWAYS_INLINE bool IF_GEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100909 return HandleIf(GetVReg(A()) >= 0, B());
David Srbecky6da82472018-10-23 14:03:08 +0100910 }
911
David Srbeckybd613ec2019-05-30 15:39:38 +0100912 ALWAYS_INLINE bool IF_GTZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100913 return HandleIf(GetVReg(A()) > 0, B());
David Srbecky6da82472018-10-23 14:03:08 +0100914 }
915
David Srbeckybd613ec2019-05-30 15:39:38 +0100916 ALWAYS_INLINE bool IF_LEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100917 return HandleIf(GetVReg(A()) <= 0, B());
David Srbecky6da82472018-10-23 14:03:08 +0100918 }
919
David Srbeckybd613ec2019-05-30 15:39:38 +0100920 ALWAYS_INLINE bool AGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +0100921 return HandleAGet<mirror::BooleanArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +0100922 }
923
David Srbeckybd613ec2019-05-30 15:39:38 +0100924 ALWAYS_INLINE bool AGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +0100925 return HandleAGet<mirror::ByteArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +0100926 }
927
David Srbeckybd613ec2019-05-30 15:39:38 +0100928 ALWAYS_INLINE bool AGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +0100929 return HandleAGet<mirror::CharArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +0100930 }
931
David Srbeckybd613ec2019-05-30 15:39:38 +0100932 ALWAYS_INLINE bool AGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +0100933 return HandleAGet<mirror::ShortArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +0100934 }
935
David Srbeckybd613ec2019-05-30 15:39:38 +0100936 ALWAYS_INLINE bool AGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +0100937 return HandleAGet<mirror::IntArray>(&InstructionHandler::SetVReg);
David Srbecky6da82472018-10-23 14:03:08 +0100938 }
939
David Srbeckybd613ec2019-05-30 15:39:38 +0100940 ALWAYS_INLINE bool AGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +0100941 return HandleAGet<mirror::LongArray>(&InstructionHandler::SetVRegLong);
David Srbecky6da82472018-10-23 14:03:08 +0100942 }
943
David Srbeckybd613ec2019-05-30 15:39:38 +0100944 ALWAYS_INLINE bool AGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +0100945 return HandleAGet<mirror::ObjectArray<mirror::Object>>(&InstructionHandler::SetVRegReference);
David Srbecky6da82472018-10-23 14:03:08 +0100946 }
947
David Srbeckybd613ec2019-05-30 15:39:38 +0100948 ALWAYS_INLINE bool APUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +0100949 return HandleAPut<mirror::BooleanArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +0100950 }
951
David Srbeckybd613ec2019-05-30 15:39:38 +0100952 ALWAYS_INLINE bool APUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +0100953 return HandleAPut<mirror::ByteArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +0100954 }
955
David Srbeckybd613ec2019-05-30 15:39:38 +0100956 ALWAYS_INLINE bool APUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +0100957 return HandleAPut<mirror::CharArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +0100958 }
959
David Srbeckybd613ec2019-05-30 15:39:38 +0100960 ALWAYS_INLINE bool APUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +0100961 return HandleAPut<mirror::ShortArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +0100962 }
963
David Srbeckybd613ec2019-05-30 15:39:38 +0100964 ALWAYS_INLINE bool APUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +0100965 return HandleAPut<mirror::IntArray>(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +0100966 }
967
David Srbeckybd613ec2019-05-30 15:39:38 +0100968 ALWAYS_INLINE bool APUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky1332c262019-06-04 13:13:37 +0100969 return HandleAPut<mirror::LongArray>(GetVRegLong(A()));
David Srbecky6da82472018-10-23 14:03:08 +0100970 }
971
David Srbeckybd613ec2019-05-30 15:39:38 +0100972 ALWAYS_INLINE bool APUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100973 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +0100974 if (UNLIKELY(a == nullptr)) {
975 ThrowNullPointerExceptionFromInterpreter();
David Srbecky8d335b62019-06-06 14:25:42 +0100976 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100977 }
David Srbecky6baf6442019-05-30 14:57:43 +0100978 int32_t index = GetVReg(C());
979 ObjPtr<mirror::Object> val = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100980 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
981 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
982 array->SetWithoutChecks<transaction_active>(index, val);
David Srbecky6da82472018-10-23 14:03:08 +0100983 } else {
David Srbecky8d335b62019-06-06 14:25:42 +0100984 return false; // Pending exception.
David Srbecky6da82472018-10-23 14:03:08 +0100985 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100986 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100987 }
988
David Srbeckybd613ec2019-05-30 15:39:38 +0100989 ALWAYS_INLINE bool IGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100990 return HandleGet<InstancePrimitiveRead, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +0100991 }
992
David Srbeckybd613ec2019-05-30 15:39:38 +0100993 ALWAYS_INLINE bool IGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100994 return HandleGet<InstancePrimitiveRead, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +0100995 }
996
David Srbeckybd613ec2019-05-30 15:39:38 +0100997 ALWAYS_INLINE bool IGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +0100998 return HandleGet<InstancePrimitiveRead, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +0100999 }
1000
David Srbeckybd613ec2019-05-30 15:39:38 +01001001 ALWAYS_INLINE bool IGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001002 return HandleGet<InstancePrimitiveRead, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001003 }
1004
David Srbeckybd613ec2019-05-30 15:39:38 +01001005 ALWAYS_INLINE bool IGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001006 return HandleGet<InstancePrimitiveRead, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001007 }
1008
David Srbeckybd613ec2019-05-30 15:39:38 +01001009 ALWAYS_INLINE bool IGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001010 return HandleGet<InstancePrimitiveRead, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001011 }
1012
David Srbeckybd613ec2019-05-30 15:39:38 +01001013 ALWAYS_INLINE bool IGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001014 return HandleGet<InstanceObjectRead, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001015 }
1016
David Srbeckybd613ec2019-05-30 15:39:38 +01001017 ALWAYS_INLINE bool IGET_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001018 return HandleGetQuick<Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001019 }
1020
David Srbeckybd613ec2019-05-30 15:39:38 +01001021 ALWAYS_INLINE bool IGET_WIDE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001022 return HandleGetQuick<Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001023 }
1024
David Srbeckybd613ec2019-05-30 15:39:38 +01001025 ALWAYS_INLINE bool IGET_OBJECT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001026 return HandleGetQuick<Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001027 }
1028
David Srbeckybd613ec2019-05-30 15:39:38 +01001029 ALWAYS_INLINE bool IGET_BOOLEAN_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001030 return HandleGetQuick<Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001031 }
1032
David Srbeckybd613ec2019-05-30 15:39:38 +01001033 ALWAYS_INLINE bool IGET_BYTE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001034 return HandleGetQuick<Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001035 }
1036
David Srbeckybd613ec2019-05-30 15:39:38 +01001037 ALWAYS_INLINE bool IGET_CHAR_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001038 return HandleGetQuick<Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001039 }
1040
David Srbeckybd613ec2019-05-30 15:39:38 +01001041 ALWAYS_INLINE bool IGET_SHORT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001042 return HandleGetQuick<Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001043 }
1044
David Srbeckybd613ec2019-05-30 15:39:38 +01001045 ALWAYS_INLINE bool SGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001046 return HandleGet<StaticPrimitiveRead, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001047 }
1048
David Srbeckybd613ec2019-05-30 15:39:38 +01001049 ALWAYS_INLINE bool SGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001050 return HandleGet<StaticPrimitiveRead, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001051 }
1052
David Srbeckybd613ec2019-05-30 15:39:38 +01001053 ALWAYS_INLINE bool SGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001054 return HandleGet<StaticPrimitiveRead, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001055 }
1056
David Srbeckybd613ec2019-05-30 15:39:38 +01001057 ALWAYS_INLINE bool SGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001058 return HandleGet<StaticPrimitiveRead, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001059 }
1060
David Srbeckybd613ec2019-05-30 15:39:38 +01001061 ALWAYS_INLINE bool SGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001062 return HandleGet<StaticPrimitiveRead, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001063 }
1064
David Srbeckybd613ec2019-05-30 15:39:38 +01001065 ALWAYS_INLINE bool SGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001066 return HandleGet<StaticPrimitiveRead, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001067 }
1068
David Srbeckybd613ec2019-05-30 15:39:38 +01001069 ALWAYS_INLINE bool SGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001070 return HandleGet<StaticObjectRead, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001071 }
1072
David Srbeckybd613ec2019-05-30 15:39:38 +01001073 ALWAYS_INLINE bool IPUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001074 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001075 }
1076
David Srbeckybd613ec2019-05-30 15:39:38 +01001077 ALWAYS_INLINE bool IPUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001078 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001079 }
1080
David Srbeckybd613ec2019-05-30 15:39:38 +01001081 ALWAYS_INLINE bool IPUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001082 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001083 }
1084
David Srbeckybd613ec2019-05-30 15:39:38 +01001085 ALWAYS_INLINE bool IPUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001086 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001087 }
1088
David Srbeckybd613ec2019-05-30 15:39:38 +01001089 ALWAYS_INLINE bool IPUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001090 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001091 }
1092
David Srbeckybd613ec2019-05-30 15:39:38 +01001093 ALWAYS_INLINE bool IPUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001094 return HandlePut<InstancePrimitiveWrite, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001095 }
1096
David Srbeckybd613ec2019-05-30 15:39:38 +01001097 ALWAYS_INLINE bool IPUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001098 return HandlePut<InstanceObjectWrite, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001099 }
1100
David Srbeckybd613ec2019-05-30 15:39:38 +01001101 ALWAYS_INLINE bool IPUT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001102 return HandlePutQuick<Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001103 }
1104
David Srbeckybd613ec2019-05-30 15:39:38 +01001105 ALWAYS_INLINE bool IPUT_BOOLEAN_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001106 return HandlePutQuick<Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001107 }
1108
David Srbeckybd613ec2019-05-30 15:39:38 +01001109 ALWAYS_INLINE bool IPUT_BYTE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001110 return HandlePutQuick<Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001111 }
1112
David Srbeckybd613ec2019-05-30 15:39:38 +01001113 ALWAYS_INLINE bool IPUT_CHAR_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001114 return HandlePutQuick<Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001115 }
1116
David Srbeckybd613ec2019-05-30 15:39:38 +01001117 ALWAYS_INLINE bool IPUT_SHORT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001118 return HandlePutQuick<Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001119 }
1120
David Srbeckybd613ec2019-05-30 15:39:38 +01001121 ALWAYS_INLINE bool IPUT_WIDE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001122 return HandlePutQuick<Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001123 }
1124
David Srbeckybd613ec2019-05-30 15:39:38 +01001125 ALWAYS_INLINE bool IPUT_OBJECT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001126 return HandlePutQuick<Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001127 }
1128
David Srbeckybd613ec2019-05-30 15:39:38 +01001129 ALWAYS_INLINE bool SPUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001130 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimBoolean>();
David Srbecky6da82472018-10-23 14:03:08 +01001131 }
1132
David Srbeckybd613ec2019-05-30 15:39:38 +01001133 ALWAYS_INLINE bool SPUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001134 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimByte>();
David Srbecky6da82472018-10-23 14:03:08 +01001135 }
1136
David Srbeckybd613ec2019-05-30 15:39:38 +01001137 ALWAYS_INLINE bool SPUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001138 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimChar>();
David Srbecky6da82472018-10-23 14:03:08 +01001139 }
1140
David Srbeckybd613ec2019-05-30 15:39:38 +01001141 ALWAYS_INLINE bool SPUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001142 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimShort>();
David Srbecky6da82472018-10-23 14:03:08 +01001143 }
1144
David Srbeckybd613ec2019-05-30 15:39:38 +01001145 ALWAYS_INLINE bool SPUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001146 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimInt>();
David Srbecky6da82472018-10-23 14:03:08 +01001147 }
1148
David Srbeckybd613ec2019-05-30 15:39:38 +01001149 ALWAYS_INLINE bool SPUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001150 return HandlePut<StaticPrimitiveWrite, Primitive::kPrimLong>();
David Srbecky6da82472018-10-23 14:03:08 +01001151 }
1152
David Srbeckybd613ec2019-05-30 15:39:38 +01001153 ALWAYS_INLINE bool SPUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001154 return HandlePut<StaticObjectWrite, Primitive::kPrimNot>();
David Srbecky6da82472018-10-23 14:03:08 +01001155 }
1156
David Srbeckybd613ec2019-05-30 15:39:38 +01001157 ALWAYS_INLINE bool INVOKE_VIRTUAL() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001158 return HandleInvoke<kVirtual, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001159 }
1160
David Srbeckybd613ec2019-05-30 15:39:38 +01001161 ALWAYS_INLINE bool INVOKE_VIRTUAL_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001162 return HandleInvoke<kVirtual, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001163 }
1164
David Srbeckybd613ec2019-05-30 15:39:38 +01001165 ALWAYS_INLINE bool INVOKE_SUPER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001166 return HandleInvoke<kSuper, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001167 }
1168
David Srbeckybd613ec2019-05-30 15:39:38 +01001169 ALWAYS_INLINE bool INVOKE_SUPER_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001170 return HandleInvoke<kSuper, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001171 }
1172
David Srbeckybd613ec2019-05-30 15:39:38 +01001173 ALWAYS_INLINE bool INVOKE_DIRECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001174 return HandleInvoke<kDirect, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001175 }
1176
David Srbeckybd613ec2019-05-30 15:39:38 +01001177 ALWAYS_INLINE bool INVOKE_DIRECT_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001178 return HandleInvoke<kDirect, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001179 }
1180
David Srbeckybd613ec2019-05-30 15:39:38 +01001181 ALWAYS_INLINE bool INVOKE_INTERFACE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001182 return HandleInvoke<kInterface, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001183 }
1184
David Srbeckybd613ec2019-05-30 15:39:38 +01001185 ALWAYS_INLINE bool INVOKE_INTERFACE_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001186 return HandleInvoke<kInterface, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001187 }
1188
David Srbeckybd613ec2019-05-30 15:39:38 +01001189 ALWAYS_INLINE bool INVOKE_STATIC() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001190 return HandleInvoke<kStatic, /*is_range=*/ false>();
David Srbecky6da82472018-10-23 14:03:08 +01001191 }
1192
David Srbeckybd613ec2019-05-30 15:39:38 +01001193 ALWAYS_INLINE bool INVOKE_STATIC_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001194 return HandleInvoke<kStatic, /*is_range=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001195 }
1196
David Srbeckybd613ec2019-05-30 15:39:38 +01001197 ALWAYS_INLINE bool INVOKE_VIRTUAL_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001198 return HandleInvoke<kVirtual, /*is_range=*/ false, /*is_quick=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001199 }
1200
David Srbeckybd613ec2019-05-30 15:39:38 +01001201 ALWAYS_INLINE bool INVOKE_VIRTUAL_RANGE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001202 return HandleInvoke<kVirtual, /*is_range=*/ true, /*is_quick=*/ true>();
David Srbecky6da82472018-10-23 14:03:08 +01001203 }
1204
David Srbeckybd613ec2019-05-30 15:39:38 +01001205 ALWAYS_INLINE bool INVOKE_POLYMORPHIC() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001206 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1207 bool success = DoInvokePolymorphic</* is_range= */ false>(
1208 self, shadow_frame, inst, inst_data, ResultRegister());
David Srbecky8d335b62019-06-06 14:25:42 +01001209 return PossiblyHandlePendingExceptionOnInvoke(!success);
David Srbecky6da82472018-10-23 14:03:08 +01001210 }
1211
David Srbeckybd613ec2019-05-30 15:39:38 +01001212 ALWAYS_INLINE bool INVOKE_POLYMORPHIC_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001213 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1214 bool success = DoInvokePolymorphic</* is_range= */ true>(
1215 self, shadow_frame, inst, inst_data, ResultRegister());
David Srbecky8d335b62019-06-06 14:25:42 +01001216 return PossiblyHandlePendingExceptionOnInvoke(!success);
David Srbecky6da82472018-10-23 14:03:08 +01001217 }
1218
David Srbeckybd613ec2019-05-30 15:39:38 +01001219 ALWAYS_INLINE bool INVOKE_CUSTOM() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001220 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1221 bool success = DoInvokeCustom</* is_range= */ false>(
1222 self, shadow_frame, inst, inst_data, ResultRegister());
David Srbecky8d335b62019-06-06 14:25:42 +01001223 return PossiblyHandlePendingExceptionOnInvoke(!success);
David Srbecky6da82472018-10-23 14:03:08 +01001224 }
1225
David Srbeckybd613ec2019-05-30 15:39:38 +01001226 ALWAYS_INLINE bool INVOKE_CUSTOM_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001227 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1228 bool success = DoInvokeCustom</* is_range= */ true>(
1229 self, shadow_frame, inst, inst_data, ResultRegister());
David Srbecky8d335b62019-06-06 14:25:42 +01001230 return PossiblyHandlePendingExceptionOnInvoke(!success);
David Srbecky6da82472018-10-23 14:03:08 +01001231 }
1232
David Srbeckybd613ec2019-05-30 15:39:38 +01001233 ALWAYS_INLINE bool NEG_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001234 SetVReg(A(), -GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001235 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001236 }
1237
David Srbeckybd613ec2019-05-30 15:39:38 +01001238 ALWAYS_INLINE bool NOT_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001239 SetVReg(A(), ~GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001240 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001241 }
1242
David Srbeckybd613ec2019-05-30 15:39:38 +01001243 ALWAYS_INLINE bool NEG_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001244 SetVRegLong(A(), -GetVRegLong(B()));
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 NOT_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001249 SetVRegLong(A(), ~GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001250 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001251 }
1252
David Srbeckybd613ec2019-05-30 15:39:38 +01001253 ALWAYS_INLINE bool NEG_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001254 SetVRegFloat(A(), -GetVRegFloat(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001255 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001256 }
1257
David Srbeckybd613ec2019-05-30 15:39:38 +01001258 ALWAYS_INLINE bool NEG_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001259 SetVRegDouble(A(), -GetVRegDouble(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001260 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001261 }
1262
David Srbeckybd613ec2019-05-30 15:39:38 +01001263 ALWAYS_INLINE bool INT_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001264 SetVRegLong(A(), GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001265 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001266 }
1267
David Srbeckybd613ec2019-05-30 15:39:38 +01001268 ALWAYS_INLINE bool INT_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001269 SetVRegFloat(A(), GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001270 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001271 }
1272
David Srbeckybd613ec2019-05-30 15:39:38 +01001273 ALWAYS_INLINE bool INT_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001274 SetVRegDouble(A(), GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001275 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001276 }
1277
David Srbeckybd613ec2019-05-30 15:39:38 +01001278 ALWAYS_INLINE bool LONG_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001279 SetVReg(A(), GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001280 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001281 }
1282
David Srbeckybd613ec2019-05-30 15:39:38 +01001283 ALWAYS_INLINE bool LONG_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001284 SetVRegFloat(A(), GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001285 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001286 }
1287
David Srbeckybd613ec2019-05-30 15:39:38 +01001288 ALWAYS_INLINE bool LONG_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001289 SetVRegDouble(A(), GetVRegLong(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001290 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001291 }
1292
David Srbeckybd613ec2019-05-30 15:39:38 +01001293 ALWAYS_INLINE bool FLOAT_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001294 float val = GetVRegFloat(B());
David Srbecky6da82472018-10-23 14:03:08 +01001295 int32_t result = art_float_to_integral<int32_t, float>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001296 SetVReg(A(), result);
David Srbeckybd613ec2019-05-30 15:39:38 +01001297 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001298 }
1299
David Srbeckybd613ec2019-05-30 15:39:38 +01001300 ALWAYS_INLINE bool FLOAT_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001301 float val = GetVRegFloat(B());
David Srbecky6da82472018-10-23 14:03:08 +01001302 int64_t result = art_float_to_integral<int64_t, float>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001303 SetVRegLong(A(), result);
David Srbeckybd613ec2019-05-30 15:39:38 +01001304 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001305 }
1306
David Srbeckybd613ec2019-05-30 15:39:38 +01001307 ALWAYS_INLINE bool FLOAT_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001308 SetVRegDouble(A(), GetVRegFloat(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001309 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001310 }
1311
David Srbeckybd613ec2019-05-30 15:39:38 +01001312 ALWAYS_INLINE bool DOUBLE_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001313 double val = GetVRegDouble(B());
David Srbecky6da82472018-10-23 14:03:08 +01001314 int32_t result = art_float_to_integral<int32_t, double>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001315 SetVReg(A(), result);
David Srbeckybd613ec2019-05-30 15:39:38 +01001316 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001317 }
1318
David Srbeckybd613ec2019-05-30 15:39:38 +01001319 ALWAYS_INLINE bool DOUBLE_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001320 double val = GetVRegDouble(B());
David Srbecky6da82472018-10-23 14:03:08 +01001321 int64_t result = art_float_to_integral<int64_t, double>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001322 SetVRegLong(A(), result);
David Srbeckybd613ec2019-05-30 15:39:38 +01001323 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001324 }
1325
David Srbeckybd613ec2019-05-30 15:39:38 +01001326 ALWAYS_INLINE bool DOUBLE_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001327 SetVRegFloat(A(), GetVRegDouble(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001328 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001329 }
1330
David Srbeckybd613ec2019-05-30 15:39:38 +01001331 ALWAYS_INLINE bool INT_TO_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001332 SetVReg(A(), static_cast<int8_t>(GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001333 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001334 }
1335
David Srbeckybd613ec2019-05-30 15:39:38 +01001336 ALWAYS_INLINE bool INT_TO_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001337 SetVReg(A(), static_cast<uint16_t>(GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001338 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001339 }
1340
David Srbeckybd613ec2019-05-30 15:39:38 +01001341 ALWAYS_INLINE bool INT_TO_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001342 SetVReg(A(), static_cast<int16_t>(GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001343 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001344 }
1345
David Srbeckybd613ec2019-05-30 15:39:38 +01001346 ALWAYS_INLINE bool ADD_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001347 SetVReg(A(), SafeAdd(GetVReg(B()), GetVReg(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001348 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001349 }
1350
David Srbeckybd613ec2019-05-30 15:39:38 +01001351 ALWAYS_INLINE bool SUB_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001352 SetVReg(A(), SafeSub(GetVReg(B()), GetVReg(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001353 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001354 }
1355
David Srbeckybd613ec2019-05-30 15:39:38 +01001356 ALWAYS_INLINE bool MUL_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001357 SetVReg(A(), SafeMul(GetVReg(B()), GetVReg(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001358 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001359 }
1360
David Srbeckybd613ec2019-05-30 15:39:38 +01001361 ALWAYS_INLINE bool DIV_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky8d335b62019-06-06 14:25:42 +01001362 return DoIntDivide(shadow_frame, A(), GetVReg(B()), GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001363 }
1364
David Srbeckybd613ec2019-05-30 15:39:38 +01001365 ALWAYS_INLINE bool REM_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky8d335b62019-06-06 14:25:42 +01001366 return DoIntRemainder(shadow_frame, A(), GetVReg(B()), GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001367 }
1368
David Srbeckybd613ec2019-05-30 15:39:38 +01001369 ALWAYS_INLINE bool SHL_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001370 SetVReg(A(), GetVReg(B()) << (GetVReg(C()) & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001371 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001372 }
1373
David Srbeckybd613ec2019-05-30 15:39:38 +01001374 ALWAYS_INLINE bool SHR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001375 SetVReg(A(), GetVReg(B()) >> (GetVReg(C()) & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001376 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001377 }
1378
David Srbeckybd613ec2019-05-30 15:39:38 +01001379 ALWAYS_INLINE bool USHR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001380 SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (GetVReg(C()) & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001381 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001382 }
1383
David Srbeckybd613ec2019-05-30 15:39:38 +01001384 ALWAYS_INLINE bool AND_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001385 SetVReg(A(), GetVReg(B()) & GetVReg(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001386 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001387 }
1388
David Srbeckybd613ec2019-05-30 15:39:38 +01001389 ALWAYS_INLINE bool OR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001390 SetVReg(A(), GetVReg(B()) | GetVReg(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001391 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001392 }
1393
David Srbeckybd613ec2019-05-30 15:39:38 +01001394 ALWAYS_INLINE bool XOR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001395 SetVReg(A(), GetVReg(B()) ^ GetVReg(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001396 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001397 }
1398
David Srbeckybd613ec2019-05-30 15:39:38 +01001399 ALWAYS_INLINE bool ADD_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001400 SetVRegLong(A(), SafeAdd(GetVRegLong(B()), GetVRegLong(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001401 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001402 }
1403
David Srbeckybd613ec2019-05-30 15:39:38 +01001404 ALWAYS_INLINE bool SUB_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001405 SetVRegLong(A(), SafeSub(GetVRegLong(B()), GetVRegLong(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001406 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001407 }
1408
David Srbeckybd613ec2019-05-30 15:39:38 +01001409 ALWAYS_INLINE bool MUL_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001410 SetVRegLong(A(), SafeMul(GetVRegLong(B()), GetVRegLong(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001411 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001412 }
1413
David Srbeckybd613ec2019-05-30 15:39:38 +01001414 ALWAYS_INLINE bool DIV_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky8d335b62019-06-06 14:25:42 +01001415 return DoLongDivide(shadow_frame, A(), GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001416 }
1417
David Srbeckybd613ec2019-05-30 15:39:38 +01001418 ALWAYS_INLINE bool REM_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky8d335b62019-06-06 14:25:42 +01001419 return DoLongRemainder(shadow_frame, A(), GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01001420 }
1421
David Srbeckybd613ec2019-05-30 15:39:38 +01001422 ALWAYS_INLINE bool AND_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001423 SetVRegLong(A(), GetVRegLong(B()) & GetVRegLong(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001424 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001425 }
1426
David Srbeckybd613ec2019-05-30 15:39:38 +01001427 ALWAYS_INLINE bool OR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001428 SetVRegLong(A(), GetVRegLong(B()) | GetVRegLong(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001429 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001430 }
1431
David Srbeckybd613ec2019-05-30 15:39:38 +01001432 ALWAYS_INLINE bool XOR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001433 SetVRegLong(A(), GetVRegLong(B()) ^ GetVRegLong(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001434 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001435 }
1436
David Srbeckybd613ec2019-05-30 15:39:38 +01001437 ALWAYS_INLINE bool SHL_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001438 SetVRegLong(A(), GetVRegLong(B()) << (GetVReg(C()) & 0x3f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001439 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001440 }
1441
David Srbeckybd613ec2019-05-30 15:39:38 +01001442 ALWAYS_INLINE bool SHR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001443 SetVRegLong(A(), GetVRegLong(B()) >> (GetVReg(C()) & 0x3f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001444 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001445 }
1446
David Srbeckybd613ec2019-05-30 15:39:38 +01001447 ALWAYS_INLINE bool USHR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001448 SetVRegLong(A(), static_cast<uint64_t>(GetVRegLong(B())) >> (GetVReg(C()) & 0x3f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001449 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001450 }
1451
David Srbeckybd613ec2019-05-30 15:39:38 +01001452 ALWAYS_INLINE bool ADD_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001453 SetVRegFloat(A(), GetVRegFloat(B()) + GetVRegFloat(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001454 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001455 }
1456
David Srbeckybd613ec2019-05-30 15:39:38 +01001457 ALWAYS_INLINE bool SUB_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001458 SetVRegFloat(A(), GetVRegFloat(B()) - GetVRegFloat(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001459 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001460 }
1461
David Srbeckybd613ec2019-05-30 15:39:38 +01001462 ALWAYS_INLINE bool MUL_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001463 SetVRegFloat(A(), GetVRegFloat(B()) * GetVRegFloat(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001464 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001465 }
1466
David Srbeckybd613ec2019-05-30 15:39:38 +01001467 ALWAYS_INLINE bool DIV_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001468 SetVRegFloat(A(), GetVRegFloat(B()) / GetVRegFloat(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001469 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001470 }
1471
David Srbeckybd613ec2019-05-30 15:39:38 +01001472 ALWAYS_INLINE bool REM_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001473 SetVRegFloat(A(), fmodf(GetVRegFloat(B()), GetVRegFloat(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001474 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001475 }
1476
David Srbeckybd613ec2019-05-30 15:39:38 +01001477 ALWAYS_INLINE bool ADD_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001478 SetVRegDouble(A(), GetVRegDouble(B()) + GetVRegDouble(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001479 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001480 }
1481
David Srbeckybd613ec2019-05-30 15:39:38 +01001482 ALWAYS_INLINE bool SUB_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001483 SetVRegDouble(A(), GetVRegDouble(B()) - GetVRegDouble(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001484 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001485 }
1486
David Srbeckybd613ec2019-05-30 15:39:38 +01001487 ALWAYS_INLINE bool MUL_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001488 SetVRegDouble(A(), GetVRegDouble(B()) * GetVRegDouble(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001489 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001490 }
1491
David Srbeckybd613ec2019-05-30 15:39:38 +01001492 ALWAYS_INLINE bool DIV_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001493 SetVRegDouble(A(), GetVRegDouble(B()) / GetVRegDouble(C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001494 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001495 }
1496
David Srbeckybd613ec2019-05-30 15:39:38 +01001497 ALWAYS_INLINE bool REM_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001498 SetVRegDouble(A(), fmod(GetVRegDouble(B()), GetVRegDouble(C())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001499 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001500 }
1501
David Srbeckybd613ec2019-05-30 15:39:38 +01001502 ALWAYS_INLINE bool ADD_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001503 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001504 SetVReg(vregA, SafeAdd(GetVReg(vregA), GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001505 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001506 }
1507
David Srbeckybd613ec2019-05-30 15:39:38 +01001508 ALWAYS_INLINE bool SUB_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001509 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001510 SetVReg(vregA, SafeSub(GetVReg(vregA), GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001511 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001512 }
1513
David Srbeckybd613ec2019-05-30 15:39:38 +01001514 ALWAYS_INLINE bool MUL_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001515 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001516 SetVReg(vregA, SafeMul(GetVReg(vregA), GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001517 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001518 }
1519
David Srbeckybd613ec2019-05-30 15:39:38 +01001520 ALWAYS_INLINE bool DIV_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001521 uint4_t vregA = A();
David Srbecky8d335b62019-06-06 14:25:42 +01001522 return DoIntDivide(shadow_frame, vregA, GetVReg(vregA), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001523 }
1524
David Srbeckybd613ec2019-05-30 15:39:38 +01001525 ALWAYS_INLINE bool REM_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001526 uint4_t vregA = A();
David Srbecky8d335b62019-06-06 14:25:42 +01001527 return DoIntRemainder(shadow_frame, vregA, GetVReg(vregA), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001528 }
1529
David Srbeckybd613ec2019-05-30 15:39:38 +01001530 ALWAYS_INLINE bool SHL_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001531 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001532 SetVReg(vregA, GetVReg(vregA) << (GetVReg(B()) & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001533 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001534 }
1535
David Srbeckybd613ec2019-05-30 15:39:38 +01001536 ALWAYS_INLINE bool SHR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001537 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001538 SetVReg(vregA, GetVReg(vregA) >> (GetVReg(B()) & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001539 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001540 }
1541
David Srbeckybd613ec2019-05-30 15:39:38 +01001542 ALWAYS_INLINE bool USHR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001543 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001544 SetVReg(vregA, static_cast<uint32_t>(GetVReg(vregA)) >> (GetVReg(B()) & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001545 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001546 }
1547
David Srbeckybd613ec2019-05-30 15:39:38 +01001548 ALWAYS_INLINE bool AND_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001549 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001550 SetVReg(vregA, GetVReg(vregA) & GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001551 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001552 }
1553
David Srbeckybd613ec2019-05-30 15:39:38 +01001554 ALWAYS_INLINE bool OR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001555 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001556 SetVReg(vregA, GetVReg(vregA) | GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001557 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001558 }
1559
David Srbeckybd613ec2019-05-30 15:39:38 +01001560 ALWAYS_INLINE bool XOR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001561 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001562 SetVReg(vregA, GetVReg(vregA) ^ GetVReg(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001563 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001564 }
1565
David Srbeckybd613ec2019-05-30 15:39:38 +01001566 ALWAYS_INLINE bool ADD_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001567 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001568 SetVRegLong(vregA, SafeAdd(GetVRegLong(vregA), GetVRegLong(B())));
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 SUB_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001573 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001574 SetVRegLong(vregA, SafeSub(GetVRegLong(vregA), GetVRegLong(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001575 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001576 }
1577
David Srbeckybd613ec2019-05-30 15:39:38 +01001578 ALWAYS_INLINE bool MUL_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001579 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001580 SetVRegLong(vregA, SafeMul(GetVRegLong(vregA), GetVRegLong(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001581 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001582 }
1583
David Srbeckybd613ec2019-05-30 15:39:38 +01001584 ALWAYS_INLINE bool DIV_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001585 uint4_t vregA = A();
David Srbecky8d335b62019-06-06 14:25:42 +01001586 return DoLongDivide(shadow_frame, vregA, GetVRegLong(vregA), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001587 }
1588
David Srbeckybd613ec2019-05-30 15:39:38 +01001589 ALWAYS_INLINE bool REM_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001590 uint4_t vregA = A();
David Srbecky8d335b62019-06-06 14:25:42 +01001591 return DoLongRemainder(shadow_frame, vregA, GetVRegLong(vregA), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001592 }
1593
David Srbeckybd613ec2019-05-30 15:39:38 +01001594 ALWAYS_INLINE bool AND_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001595 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001596 SetVRegLong(vregA, GetVRegLong(vregA) & GetVRegLong(B()));
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 OR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001601 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001602 SetVRegLong(vregA, GetVRegLong(vregA) | GetVRegLong(B()));
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 XOR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001607 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001608 SetVRegLong(vregA, GetVRegLong(vregA) ^ GetVRegLong(B()));
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 SHL_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001613 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001614 SetVRegLong(vregA, GetVRegLong(vregA) << (GetVReg(B()) & 0x3f));
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 SHR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001619 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001620 SetVRegLong(vregA, GetVRegLong(vregA) >> (GetVReg(B()) & 0x3f));
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 USHR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001625 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001626 SetVRegLong(vregA, static_cast<uint64_t>(GetVRegLong(vregA)) >> (GetVReg(B()) & 0x3f));
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 ADD_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001631 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001632 SetVRegFloat(vregA, GetVRegFloat(vregA) + GetVRegFloat(B()));
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 SUB_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001637 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001638 SetVRegFloat(vregA, GetVRegFloat(vregA) - GetVRegFloat(B()));
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 MUL_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001643 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001644 SetVRegFloat(vregA, GetVRegFloat(vregA) * GetVRegFloat(B()));
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 DIV_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001649 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001650 SetVRegFloat(vregA, GetVRegFloat(vregA) / GetVRegFloat(B()));
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 REM_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001655 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001656 SetVRegFloat(vregA, fmodf(GetVRegFloat(vregA), GetVRegFloat(B())));
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 ADD_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001661 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001662 SetVRegDouble(vregA, GetVRegDouble(vregA) + GetVRegDouble(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001663 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001664 }
1665
David Srbeckybd613ec2019-05-30 15:39:38 +01001666 ALWAYS_INLINE bool SUB_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001667 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001668 SetVRegDouble(vregA, GetVRegDouble(vregA) - GetVRegDouble(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001669 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001670 }
1671
David Srbeckybd613ec2019-05-30 15:39:38 +01001672 ALWAYS_INLINE bool MUL_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001673 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001674 SetVRegDouble(vregA, GetVRegDouble(vregA) * GetVRegDouble(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001675 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001676 }
1677
David Srbeckybd613ec2019-05-30 15:39:38 +01001678 ALWAYS_INLINE bool DIV_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001679 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001680 SetVRegDouble(vregA, GetVRegDouble(vregA) / GetVRegDouble(B()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001681 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001682 }
1683
David Srbeckybd613ec2019-05-30 15:39:38 +01001684 ALWAYS_INLINE bool REM_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001685 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01001686 SetVRegDouble(vregA, fmod(GetVRegDouble(vregA), GetVRegDouble(B())));
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 ADD_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001691 SetVReg(A(), SafeAdd(GetVReg(B()), C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001692 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001693 }
1694
David Srbeckybd613ec2019-05-30 15:39:38 +01001695 ALWAYS_INLINE bool RSUB_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001696 SetVReg(A(), SafeSub(C(), GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001697 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001698 }
1699
David Srbeckybd613ec2019-05-30 15:39:38 +01001700 ALWAYS_INLINE bool MUL_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001701 SetVReg(A(), SafeMul(GetVReg(B()), C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001702 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001703 }
1704
David Srbeckybd613ec2019-05-30 15:39:38 +01001705 ALWAYS_INLINE bool DIV_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky8d335b62019-06-06 14:25:42 +01001706 return DoIntDivide(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001707 }
1708
David Srbeckybd613ec2019-05-30 15:39:38 +01001709 ALWAYS_INLINE bool REM_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky8d335b62019-06-06 14:25:42 +01001710 return DoIntRemainder(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001711 }
1712
David Srbeckybd613ec2019-05-30 15:39:38 +01001713 ALWAYS_INLINE bool AND_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001714 SetVReg(A(), GetVReg(B()) & C());
David Srbeckybd613ec2019-05-30 15:39:38 +01001715 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001716 }
1717
David Srbeckybd613ec2019-05-30 15:39:38 +01001718 ALWAYS_INLINE bool OR_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001719 SetVReg(A(), GetVReg(B()) | C());
David Srbeckybd613ec2019-05-30 15:39:38 +01001720 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001721 }
1722
David Srbeckybd613ec2019-05-30 15:39:38 +01001723 ALWAYS_INLINE bool XOR_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001724 SetVReg(A(), GetVReg(B()) ^ C());
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 ADD_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001729 SetVReg(A(), SafeAdd(GetVReg(B()), C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001730 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001731 }
1732
David Srbeckybd613ec2019-05-30 15:39:38 +01001733 ALWAYS_INLINE bool RSUB_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001734 SetVReg(A(), SafeSub(C(), GetVReg(B())));
David Srbeckybd613ec2019-05-30 15:39:38 +01001735 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001736 }
1737
David Srbeckybd613ec2019-05-30 15:39:38 +01001738 ALWAYS_INLINE bool MUL_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001739 SetVReg(A(), SafeMul(GetVReg(B()), C()));
David Srbeckybd613ec2019-05-30 15:39:38 +01001740 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001741 }
1742
David Srbeckybd613ec2019-05-30 15:39:38 +01001743 ALWAYS_INLINE bool DIV_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky8d335b62019-06-06 14:25:42 +01001744 return DoIntDivide(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001745 }
1746
David Srbeckybd613ec2019-05-30 15:39:38 +01001747 ALWAYS_INLINE bool REM_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky8d335b62019-06-06 14:25:42 +01001748 return DoIntRemainder(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01001749 }
1750
David Srbeckybd613ec2019-05-30 15:39:38 +01001751 ALWAYS_INLINE bool AND_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001752 SetVReg(A(), GetVReg(B()) & C());
David Srbeckybd613ec2019-05-30 15:39:38 +01001753 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001754 }
1755
David Srbeckybd613ec2019-05-30 15:39:38 +01001756 ALWAYS_INLINE bool OR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001757 SetVReg(A(), GetVReg(B()) | C());
David Srbeckybd613ec2019-05-30 15:39:38 +01001758 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001759 }
1760
David Srbeckybd613ec2019-05-30 15:39:38 +01001761 ALWAYS_INLINE bool XOR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001762 SetVReg(A(), GetVReg(B()) ^ C());
David Srbeckybd613ec2019-05-30 15:39:38 +01001763 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001764 }
1765
David Srbeckybd613ec2019-05-30 15:39:38 +01001766 ALWAYS_INLINE bool SHL_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001767 SetVReg(A(), GetVReg(B()) << (C() & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001768 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001769 }
1770
David Srbeckybd613ec2019-05-30 15:39:38 +01001771 ALWAYS_INLINE bool SHR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001772 SetVReg(A(), GetVReg(B()) >> (C() & 0x1f));
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 USHR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001777 SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (C() & 0x1f));
David Srbeckybd613ec2019-05-30 15:39:38 +01001778 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001779 }
1780
David Srbeckybd613ec2019-05-30 15:39:38 +01001781 ALWAYS_INLINE bool UNUSED_3E() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001782 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001783 }
1784
David Srbeckybd613ec2019-05-30 15:39:38 +01001785 ALWAYS_INLINE bool UNUSED_3F() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001786 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001787 }
1788
David Srbeckybd613ec2019-05-30 15:39:38 +01001789 ALWAYS_INLINE bool UNUSED_40() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001790 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001791 }
1792
David Srbeckybd613ec2019-05-30 15:39:38 +01001793 ALWAYS_INLINE bool UNUSED_41() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001794 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001795 }
1796
David Srbeckybd613ec2019-05-30 15:39:38 +01001797 ALWAYS_INLINE bool UNUSED_42() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001798 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001799 }
1800
David Srbeckybd613ec2019-05-30 15:39:38 +01001801 ALWAYS_INLINE bool UNUSED_43() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001802 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001803 }
1804
David Srbeckybd613ec2019-05-30 15:39:38 +01001805 ALWAYS_INLINE bool UNUSED_79() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001806 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001807 }
1808
David Srbeckybd613ec2019-05-30 15:39:38 +01001809 ALWAYS_INLINE bool UNUSED_7A() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001810 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001811 }
1812
David Srbeckybd613ec2019-05-30 15:39:38 +01001813 ALWAYS_INLINE bool UNUSED_F3() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001814 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001815 }
1816
David Srbeckybd613ec2019-05-30 15:39:38 +01001817 ALWAYS_INLINE bool UNUSED_F4() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001818 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001819 }
1820
David Srbeckybd613ec2019-05-30 15:39:38 +01001821 ALWAYS_INLINE bool UNUSED_F5() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001822 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001823 }
1824
David Srbeckybd613ec2019-05-30 15:39:38 +01001825 ALWAYS_INLINE bool UNUSED_F6() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001826 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001827 }
1828
David Srbeckybd613ec2019-05-30 15:39:38 +01001829 ALWAYS_INLINE bool UNUSED_F7() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001830 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001831 }
1832
David Srbeckybd613ec2019-05-30 15:39:38 +01001833 ALWAYS_INLINE bool UNUSED_F8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001834 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001835 }
1836
David Srbeckybd613ec2019-05-30 15:39:38 +01001837 ALWAYS_INLINE bool UNUSED_F9() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyee12e3a2019-06-03 15:18:57 +01001838 return HandleUnused();
David Srbecky6da82472018-10-23 14:03:08 +01001839 }
1840
1841 ALWAYS_INLINE InstructionHandler(SwitchImplContext* ctx,
1842 const instrumentation::Instrumentation* instrumentation,
1843 Thread* self,
1844 ShadowFrame& shadow_frame,
1845 uint16_t dex_pc,
David Srbeckyc56a23e2019-06-05 17:45:49 +01001846 const Instruction* inst,
David Srbecky6da82472018-10-23 14:03:08 +01001847 uint16_t inst_data,
David Srbecky8867f3b2019-05-31 20:01:46 +01001848 const Instruction*& next,
David Srbecky6da82472018-10-23 14:03:08 +01001849 bool& exit_interpreter_loop)
1850 : ctx(ctx),
1851 instrumentation(instrumentation),
1852 self(self),
1853 shadow_frame(shadow_frame),
1854 dex_pc(dex_pc),
1855 inst(inst),
1856 inst_data(inst_data),
David Srbecky8867f3b2019-05-31 20:01:46 +01001857 next(next),
David Srbecky6da82472018-10-23 14:03:08 +01001858 exit_interpreter_loop(exit_interpreter_loop) {
1859 }
1860
1861 private:
1862 static constexpr bool do_assignability_check = do_access_check;
Alex Lightb7c640d2019-03-20 15:52:13 -07001863 static constexpr MonitorState kMonitorState =
1864 do_assignability_check ? MonitorState::kCountingMonitors : MonitorState::kNormalMonitors;
David Srbecky6da82472018-10-23 14:03:08 +01001865
1866 const CodeItemDataAccessor& Accessor() { return ctx->accessor; }
1867 const uint16_t* Insns() { return ctx->accessor.Insns(); }
1868 JValue* ResultRegister() { return &ctx->result_register; }
1869
David Srbecky436f6c12019-05-22 13:28:42 +01001870 ALWAYS_INLINE int32_t A() { return inst->VRegA(kFormat, inst_data); }
1871 ALWAYS_INLINE int32_t B() { return inst->VRegB(kFormat, inst_data); }
1872 ALWAYS_INLINE int32_t C() { return inst->VRegC(kFormat); }
1873
David Srbecky6baf6442019-05-30 14:57:43 +01001874 int32_t GetVReg(size_t i) const { return shadow_frame.GetVReg(i); }
1875 int64_t GetVRegLong(size_t i) const { return shadow_frame.GetVRegLong(i); }
1876 float GetVRegFloat(size_t i) const { return shadow_frame.GetVRegFloat(i); }
1877 double GetVRegDouble(size_t i) const { return shadow_frame.GetVRegDouble(i); }
1878 ObjPtr<mirror::Object> GetVRegReference(size_t i) const REQUIRES_SHARED(Locks::mutator_lock_) {
1879 return shadow_frame.GetVRegReference(i);
1880 }
1881
1882 void SetVReg(size_t i, int32_t val) { shadow_frame.SetVReg(i, val); }
1883 void SetVRegLong(size_t i, int64_t val) { shadow_frame.SetVRegLong(i, val); }
1884 void SetVRegFloat(size_t i, float val) { shadow_frame.SetVRegFloat(i, val); }
1885 void SetVRegDouble(size_t i, double val) { shadow_frame.SetVRegDouble(i, val); }
1886 void SetVRegReference(size_t i, ObjPtr<mirror::Object> val)
1887 REQUIRES_SHARED(Locks::mutator_lock_) {
1888 shadow_frame.SetVRegReference(i, val);
1889 }
1890
David Srbecky8867f3b2019-05-31 20:01:46 +01001891 // Set the next instruction to be executed. It is the 'fall-through' instruction by default.
1892 ALWAYS_INLINE void SetNextInstruction(const Instruction* next_inst) {
1893 DCHECK_LT(next_inst->GetDexPc(Insns()), Accessor().InsnsSizeInCodeUnits());
1894 next = next_inst;
1895 }
1896
David Srbecky6da82472018-10-23 14:03:08 +01001897 SwitchImplContext* const ctx;
1898 const instrumentation::Instrumentation* const instrumentation;
1899 Thread* const self;
1900 ShadowFrame& shadow_frame;
1901 uint32_t const dex_pc;
David Srbeckyc56a23e2019-06-05 17:45:49 +01001902 const Instruction* const inst;
David Srbecky6da82472018-10-23 14:03:08 +01001903 uint16_t const inst_data;
David Srbecky8867f3b2019-05-31 20:01:46 +01001904 const Instruction*& next;
1905
David Srbecky6da82472018-10-23 14:03:08 +01001906 bool& exit_interpreter_loop;
1907};
1908
Alex Light6f22e062018-10-05 15:05:12 -07001909// TODO On ASAN builds this function gets a huge stack frame. Since normally we run in the mterp
1910// this shouldn't cause any problems for stack overflow detection. Remove this once b/117341496 is
1911// fixed.
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01001912template<bool do_access_check, bool transaction_active>
Alex Light6f22e062018-10-05 15:05:12 -07001913ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
David Srbecky946bb092018-03-09 17:23:01 +00001914 Thread* self = ctx->self;
1915 const CodeItemDataAccessor& accessor = ctx->accessor;
1916 ShadowFrame& shadow_frame = ctx->shadow_frame;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001917 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
1918 LOG(FATAL) << "Invalid shadow frame for interpreter use";
David Srbecky946bb092018-03-09 17:23:01 +00001919 ctx->result = JValue();
1920 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001921 }
1922 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001923
1924 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07001925 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Mathieu Chartier808c7a52017-12-15 11:19:33 -08001926 const uint16_t* const insns = accessor.Insns();
David Srbeckyc56a23e2019-06-05 17:45:49 +01001927 const Instruction* next = Instruction::At(insns + dex_pc);
Igor Murashkin6918bf12015-09-27 19:19:06 -07001928
Alex Light0aa7a5a2018-10-10 15:58:14 +00001929 DCHECK(!shadow_frame.GetForceRetryInstruction())
1930 << "Entered interpreter from invoke without retry instruction being handled!";
1931
David Srbecky6da82472018-10-23 14:03:08 +01001932 bool const interpret_one_instruction = ctx->interpret_one_instruction;
1933 while (true) {
David Srbeckyc56a23e2019-06-05 17:45:49 +01001934 const Instruction* const inst = next;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001935 dex_pc = inst->GetDexPc(insns);
1936 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -08001937 TraceExecution(shadow_frame, inst, dex_pc);
David Srbecky8d335b62019-06-06 14:25:42 +01001938 uint16_t inst_data = inst->Fetch16(0);
1939 bool exit = false;
1940 if (InstructionHandler<do_access_check, transaction_active, Instruction::kInvalidFormat>(
1941 ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit).
1942 Preamble()) {
1943 switch (inst->Opcode(inst_data)) {
David Srbecky8867f3b2019-05-31 20:01:46 +01001944#define OPCODE_CASE(OPCODE, OPCODE_NAME, NAME, FORMAT, i, a, e, v) \
David Srbecky8d335b62019-06-06 14:25:42 +01001945 case OPCODE: { \
1946 DCHECK_EQ(self->IsExceptionPending(), (OPCODE == Instruction::MOVE_EXCEPTION)); \
1947 next = inst->RelativeAt(Instruction::SizeInCodeUnits(Instruction::FORMAT)); \
1948 InstructionHandler<do_access_check, transaction_active, Instruction::FORMAT> handler( \
1949 ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit); \
1950 if (handler.OPCODE_NAME() && LIKELY(!interpret_one_instruction)) { \
1951 DCHECK(!exit) << NAME; \
1952 continue; \
1953 } \
1954 if (exit) { \
1955 shadow_frame.SetDexPC(dex::kDexNoIndex); \
1956 return; \
1957 } \
1958 break; \
1959 }
1960 DEX_INSTRUCTION_LIST(OPCODE_CASE)
David Srbecky6da82472018-10-23 14:03:08 +01001961#undef OPCODE_CASE
David Srbecky8d335b62019-06-06 14:25:42 +01001962 }
1963 } else {
1964 // Preamble returned false due to debugger event.
1965 if (exit) {
1966 shadow_frame.SetDexPC(dex::kDexNoIndex);
1967 return; // Return statement or debugger forced exit.
1968 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001969 }
David Srbecky8d335b62019-06-06 14:25:42 +01001970 if (self->IsExceptionPending()) {
1971 if (!InstructionHandler<do_access_check, transaction_active, Instruction::kInvalidFormat>(
1972 ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, next, exit).
1973 HandlePendingException()) {
1974 shadow_frame.SetDexPC(dex::kDexNoIndex);
1975 return; // Locally unhandled exception - return to caller.
1976 }
1977 // Continue execution in the catch block.
1978 }
1979 if (interpret_one_instruction) {
1980 shadow_frame.SetDexPC(next->GetDexPc(insns)); // Record where we stopped.
1981 ctx->result = ctx->result_register;
1982 return;
David Srbecky6da82472018-10-23 14:03:08 +01001983 }
1984 }
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001985} // NOLINT(readability/fn_size)
1986
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001987} // namespace interpreter
1988} // namespace art
David Srbecky2ee09ff2018-10-24 13:24:22 +01001989
1990#endif // ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_