blob: 2ba5a48f9467425b0d9292f97e096419099abe90 [file] [log] [blame]
Sebastien Hertz8ece0502013-08-07 11:26:41 +02001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
David Srbecky2ee09ff2018-10-24 13:24:22 +010017#ifndef ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
18#define ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_
19
Andreas Gampe5e26eb12016-08-22 17:54:17 -070020#include "interpreter_switch_impl.h"
21
Andreas Gampe542451c2016-07-26 09:02:02 -070022#include "base/enums.h"
Alex Light49af7042019-05-29 18:30:33 -070023#include "base/globals.h"
Alex Light6f22e062018-10-05 15:05:12 -070024#include "base/memory_tool.h"
David Sehrc431b9d2018-03-02 12:01:51 -080025#include "base/quasi_atomic.h"
David Sehr9e734c72018-01-04 17:56:19 -080026#include "dex/dex_file_types.h"
David Srbecky6da82472018-10-23 14:03:08 +010027#include "dex/dex_instruction_list.h"
Alex Lighteb7c1442015-08-31 13:17:42 -070028#include "experimental_flags.h"
Alex Light49af7042019-05-29 18:30:33 -070029#include "handle_scope.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020030#include "interpreter_common.h"
Alex Light49af7042019-05-29 18:30:33 -070031#include "interpreter/shadow_frame.h"
David Srbeckye3fc2d12018-11-30 13:41:14 +000032#include "jit/jit-inl.h"
Mathieu Chartier28bd2e42016-10-04 13:54:57 -070033#include "jvalue-inl.h"
Andreas Gampefd63bbf2018-10-29 12:55:35 -070034#include "mirror/string-alloc-inl.h"
Alex Light49af7042019-05-29 18:30:33 -070035#include "mirror/throwable.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000036#include "nth_caller_visitor.h"
Ian Rogersf72a11d2014-10-30 15:41:08 -070037#include "safe_math.h"
Vladimir Marko6ec2a1b2018-05-22 15:33:48 +010038#include "shadow_frame-inl.h"
Alex Light0aa7a5a2018-10-10 15:58:14 +000039#include "thread.h"
Alex Light49af7042019-05-29 18:30:33 -070040#include "verifier/method_verifier.h"
Sebastien Hertz8ece0502013-08-07 11:26:41 +020041
42namespace art {
43namespace interpreter {
44
David Srbecky6da82472018-10-23 14:03:08 +010045// Short-lived helper class which executes single DEX bytecode. It is inlined by compiler.
46//
47// The function names must match the names from dex_instruction_list.h and have no arguments.
48//
49// Any relevant execution information is stored in the fields - it should be kept to minimum.
50//
David Srbecky47ad3762018-10-31 12:43:40 +000051// Helper methods may return boolean value - in which case 'false' always means
52// "stop executing current opcode" (which does not necessarily exit the interpreter loop).
53//
David Srbecky436f6c12019-05-22 13:28:42 +010054template<bool do_access_check, bool transaction_active, Instruction::Format kFormat>
David Srbecky6da82472018-10-23 14:03:08 +010055class InstructionHandler {
56 public:
Alex Light49af7042019-05-29 18:30:33 -070057 template <bool kMonitorCounting>
58 static NO_INLINE void UnlockHeldMonitors(Thread* self, ShadowFrame* shadow_frame)
59 REQUIRES_SHARED(Locks::mutator_lock_) {
60 DCHECK(shadow_frame->GetForcePopFrame());
61 // Unlock all monitors.
62 if (kMonitorCounting && shadow_frame->GetMethod()->MustCountLocks()) {
63 // Get the monitors from the shadow-frame monitor-count data.
64 shadow_frame->GetLockCountData().VisitMonitors(
65 [&](mirror::Object** obj) REQUIRES_SHARED(Locks::mutator_lock_) {
66 // Since we don't use the 'obj' pointer after the DoMonitorExit everything should be fine
67 // WRT suspension.
68 DoMonitorExit<do_assignability_check>(self, shadow_frame, *obj);
69 });
70 } else {
71 std::vector<verifier::MethodVerifier::DexLockInfo> locks;
72 verifier::MethodVerifier::FindLocksAtDexPc(shadow_frame->GetMethod(),
73 shadow_frame->GetDexPC(),
74 &locks,
75 Runtime::Current()->GetTargetSdkVersion());
76 for (const auto& reg : locks) {
77 if (UNLIKELY(reg.dex_registers.empty())) {
78 LOG(ERROR) << "Unable to determine reference locked by "
79 << shadow_frame->GetMethod()->PrettyMethod() << " at pc "
80 << shadow_frame->GetDexPC();
81 } else {
82 DoMonitorExit<do_assignability_check>(
83 self, shadow_frame, shadow_frame->GetVRegReference(*reg.dex_registers.begin()));
84 }
85 }
86 }
87 }
88
David Srbecky47ad3762018-10-31 12:43:40 +000089 ALWAYS_INLINE WARN_UNUSED bool CheckForceReturn()
90 REQUIRES_SHARED(Locks::mutator_lock_) {
91 if (UNLIKELY(shadow_frame.GetForcePopFrame())) {
92 DCHECK(PrevFrameWillRetry(self, shadow_frame))
93 << "Pop frame forced without previous frame ready to retry instruction!";
94 DCHECK(Runtime::Current()->AreNonStandardExitsEnabled());
Alex Light49af7042019-05-29 18:30:33 -070095 UnlockHeldMonitors<do_assignability_check>(self, &shadow_frame);
96 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame);
David Srbecky47ad3762018-10-31 12:43:40 +000097 if (UNLIKELY(NeedsMethodExitEvent(instrumentation))) {
98 SendMethodExitEvents(self,
99 instrumentation,
100 shadow_frame,
101 shadow_frame.GetThisObject(Accessor().InsSize()),
102 shadow_frame.GetMethod(),
103 inst->GetDexPc(Insns()),
104 JValue());
105 }
106 ctx->result = JValue(); /* Handled in caller. */
107 exit_interpreter_loop = true;
108 return false;
109 }
110 return true;
111 }
112
David Srbecky5f250012018-11-08 14:16:38 +0000113 NO_INLINE WARN_UNUSED bool HandlePendingExceptionWithInstrumentationImpl(
David Srbecky47ad3762018-10-31 12:43:40 +0000114 const instrumentation::Instrumentation* instr)
115 REQUIRES_SHARED(Locks::mutator_lock_) {
116 DCHECK(self->IsExceptionPending());
117 self->AllowThreadSuspension();
118 if (!CheckForceReturn()) {
119 return false;
120 }
121 if (!MoveToExceptionHandler(self, shadow_frame, instr)) {
122 /* Structured locking is to be enforced for abnormal termination, too. */
123 DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame);
124 if (ctx->interpret_one_instruction) {
125 /* Signal mterp to return to caller */
126 shadow_frame.SetDexPC(dex::kDexNoIndex);
127 }
128 ctx->result = JValue(); /* Handled in caller. */
129 exit_interpreter_loop = true;
130 return false; // Return to caller.
131 }
132 if (!CheckForceReturn()) {
133 return false;
134 }
135 int32_t displacement =
136 static_cast<int32_t>(shadow_frame.GetDexPC()) - static_cast<int32_t>(dex_pc);
137 inst = inst->RelativeAt(displacement);
138 return false; // Stop executing this opcode and continue in the exception handler.
139 }
140
David Srbecky5f250012018-11-08 14:16:38 +0000141 // Forwards the call to the NO_INLINE HandlePendingExceptionWithInstrumentationImpl.
142 ALWAYS_INLINE WARN_UNUSED bool HandlePendingExceptionWithInstrumentation(
143 const instrumentation::Instrumentation* instr)
144 REQUIRES_SHARED(Locks::mutator_lock_) {
145 // We need to help the compiler a bit to make the NO_INLINE call efficient.
146 // * All handler fields should be in registers, so we do not want to take the object
147 // address (for 'this' argument). Make a copy of the handler just for the slow path.
148 // * The modifiable fields should also be in registers, so we don't want to store their
149 // address even in the handler copy. Make a copy of them just for the call as well.
150 const Instruction* inst_copy = inst;
151 bool exit_loop_copy = exit_interpreter_loop;
David Srbecky436f6c12019-05-22 13:28:42 +0100152 InstructionHandler<do_access_check, transaction_active, kFormat> handler_copy(
David Srbecky5f250012018-11-08 14:16:38 +0000153 ctx, instrumentation, self, shadow_frame, dex_pc, inst_copy, inst_data, exit_loop_copy);
154 bool result = handler_copy.HandlePendingExceptionWithInstrumentationImpl(instr);
155 inst = inst_copy;
156 exit_interpreter_loop = exit_loop_copy;
157 return result;
158 }
159
David Srbecky47ad3762018-10-31 12:43:40 +0000160 ALWAYS_INLINE WARN_UNUSED bool HandlePendingException()
161 REQUIRES_SHARED(Locks::mutator_lock_) {
162 return HandlePendingExceptionWithInstrumentation(instrumentation);
163 }
164
165 ALWAYS_INLINE WARN_UNUSED bool PossiblyHandlePendingExceptionOnInvokeImpl(
166 bool is_exception_pending,
167 const Instruction* next_inst)
168 REQUIRES_SHARED(Locks::mutator_lock_) {
169 if (UNLIKELY(shadow_frame.GetForceRetryInstruction())) {
170 /* Don't need to do anything except clear the flag and exception. We leave the */
171 /* instruction the same so it will be re-executed on the next go-around. */
172 DCHECK(inst->IsInvoke());
173 shadow_frame.SetForceRetryInstruction(false);
174 if (UNLIKELY(is_exception_pending)) {
175 DCHECK(self->IsExceptionPending());
176 if (kIsDebugBuild) {
177 LOG(WARNING) << "Suppressing exception for instruction-retry: "
178 << self->GetException()->Dump();
179 }
180 self->ClearException();
181 }
182 } else if (UNLIKELY(is_exception_pending)) {
183 /* Should have succeeded. */
184 DCHECK(!shadow_frame.GetForceRetryInstruction());
185 if (!HandlePendingException()) {
186 return false;
187 }
188 } else {
189 inst = next_inst;
190 }
191 return true;
192 }
193
194 ALWAYS_INLINE WARN_UNUSED bool PossiblyHandlePendingException(
195 bool is_exception_pending,
196 const Instruction* next_inst)
197 REQUIRES_SHARED(Locks::mutator_lock_) {
198 /* Should only be on invoke instructions. */
199 DCHECK(!shadow_frame.GetForceRetryInstruction());
200 if (UNLIKELY(is_exception_pending)) {
201 if (!HandlePendingException()) {
202 return false;
203 }
204 } else {
205 inst = next_inst;
206 }
207 return true;
208 }
209
210 ALWAYS_INLINE WARN_UNUSED bool HandleMonitorChecks()
211 REQUIRES_SHARED(Locks::mutator_lock_) {
212 if (!DoMonitorCheckOnExit<do_assignability_check>(self, &shadow_frame)) {
213 if (!HandlePendingException()) {
214 return false;
215 }
216 }
217 return true;
218 }
219
220 // Code to run before each dex instruction.
David Srbeckya4a96af2018-10-31 16:34:58 +0000221 ALWAYS_INLINE WARN_UNUSED bool Preamble()
David Srbecky47ad3762018-10-31 12:43:40 +0000222 REQUIRES_SHARED(Locks::mutator_lock_) {
223 /* We need to put this before & after the instrumentation to avoid having to put in a */
224 /* post-script macro. */
225 if (!CheckForceReturn()) {
226 return false;
227 }
228 if (UNLIKELY(instrumentation->HasDexPcListeners())) {
David Srbeckya4a96af2018-10-31 16:34:58 +0000229 uint8_t opcode = inst->Opcode(inst_data);
230 bool is_move_result_object = (opcode == Instruction::MOVE_RESULT_OBJECT);
231 JValue* save_ref = is_move_result_object ? &ctx->result_register : nullptr;
David Srbecky47ad3762018-10-31 12:43:40 +0000232 if (UNLIKELY(!DoDexPcMoveEvent(self,
233 Accessor(),
234 shadow_frame,
235 dex_pc,
236 instrumentation,
237 save_ref))) {
238 if (!HandlePendingException()) {
239 return false;
240 }
241 }
242 if (!CheckForceReturn()) {
243 return false;
244 }
245 }
246 return true;
247 }
248
249 ALWAYS_INLINE WARN_UNUSED bool BranchInstrumentation(int32_t offset)
250 REQUIRES_SHARED(Locks::mutator_lock_) {
251 if (UNLIKELY(instrumentation->HasBranchListeners())) {
252 instrumentation->Branch(self, shadow_frame.GetMethod(), dex_pc, offset);
253 }
254 JValue result;
255 if (jit::Jit::MaybeDoOnStackReplacement(self,
256 shadow_frame.GetMethod(),
257 dex_pc,
258 offset,
259 &result)) {
260 if (ctx->interpret_one_instruction) {
261 /* OSR has completed execution of the method. Signal mterp to return to caller */
262 shadow_frame.SetDexPC(dex::kDexNoIndex);
263 }
264 ctx->result = result;
265 exit_interpreter_loop = true;
266 return false;
267 }
268 return true;
269 }
270
271 ALWAYS_INLINE void HotnessUpdate()
272 REQUIRES_SHARED(Locks::mutator_lock_) {
273 jit::Jit* jit = Runtime::Current()->GetJit();
274 if (jit != nullptr) {
275 jit->AddSamples(self, shadow_frame.GetMethod(), 1, /*with_backedges=*/ true);
276 }
277 }
278
279 ALWAYS_INLINE WARN_UNUSED bool HandleAsyncException()
280 REQUIRES_SHARED(Locks::mutator_lock_) {
281 if (UNLIKELY(self->ObserveAsyncException())) {
282 if (!HandlePendingException()) {
283 return false;
284 }
285 }
286 return true;
287 }
288
289 ALWAYS_INLINE void HandleBackwardBranch(int32_t offset)
290 REQUIRES_SHARED(Locks::mutator_lock_) {
291 if (IsBackwardBranch(offset)) {
292 HotnessUpdate();
293 /* Record new dex pc early to have consistent suspend point at loop header. */
294 shadow_frame.SetDexPC(inst->GetDexPc(Insns()));
295 self->AllowThreadSuspension();
296 }
297 }
298
299 // Unlike most other events the DexPcMovedEvent can be sent when there is a pending exception (if
300 // the next instruction is MOVE_EXCEPTION). This means it needs to be handled carefully to be able
301 // to detect exceptions thrown by the DexPcMovedEvent itself. These exceptions could be thrown by
302 // jvmti-agents while handling breakpoint or single step events. We had to move this into its own
303 // function because it was making ExecuteSwitchImpl have too large a stack.
304 NO_INLINE static bool DoDexPcMoveEvent(Thread* self,
305 const CodeItemDataAccessor& accessor,
306 const ShadowFrame& shadow_frame,
307 uint32_t dex_pc,
308 const instrumentation::Instrumentation* instrumentation,
309 JValue* save_ref)
310 REQUIRES_SHARED(Locks::mutator_lock_) {
311 DCHECK(instrumentation->HasDexPcListeners());
312 StackHandleScope<2> hs(self);
313 Handle<mirror::Throwable> thr(hs.NewHandle(self->GetException()));
314 mirror::Object* null_obj = nullptr;
315 HandleWrapper<mirror::Object> h(
316 hs.NewHandleWrapper(LIKELY(save_ref == nullptr) ? &null_obj : save_ref->GetGCRoot()));
317 self->ClearException();
318 instrumentation->DexPcMovedEvent(self,
319 shadow_frame.GetThisObject(accessor.InsSize()),
320 shadow_frame.GetMethod(),
321 dex_pc);
322 if (UNLIKELY(self->IsExceptionPending())) {
323 // We got a new exception in the dex-pc-moved event.
324 // We just let this exception replace the old one.
325 // TODO It would be good to add the old exception to the
326 // suppressed exceptions of the new one if possible.
327 return false;
328 } else {
329 if (UNLIKELY(!thr.IsNull())) {
330 self->SetException(thr.Get());
331 }
332 return true;
333 }
334 }
335
336 static bool NeedsMethodExitEvent(const instrumentation::Instrumentation* ins)
337 REQUIRES_SHARED(Locks::mutator_lock_) {
338 return ins->HasMethodExitListeners() || ins->HasWatchedFramePopListeners();
339 }
340
341 // Sends the normal method exit event.
342 // Returns true if the events succeeded and false if there is a pending exception.
343 NO_INLINE static bool SendMethodExitEvents(
344 Thread* self,
345 const instrumentation::Instrumentation* instrumentation,
346 const ShadowFrame& frame,
347 ObjPtr<mirror::Object> thiz,
348 ArtMethod* method,
349 uint32_t dex_pc,
350 const JValue& result)
351 REQUIRES_SHARED(Locks::mutator_lock_) {
352 bool had_event = false;
353 // We don't send method-exit if it's a pop-frame. We still send frame_popped though.
354 if (UNLIKELY(instrumentation->HasMethodExitListeners() && !frame.GetForcePopFrame())) {
355 had_event = true;
Vladimir Marko19711d42019-04-12 14:05:34 +0100356 instrumentation->MethodExitEvent(self, thiz, method, dex_pc, result);
David Srbecky47ad3762018-10-31 12:43:40 +0000357 }
358 if (UNLIKELY(frame.NeedsNotifyPop() && instrumentation->HasWatchedFramePopListeners())) {
359 had_event = true;
360 instrumentation->WatchedFramePopped(self, frame);
361 }
362 if (UNLIKELY(had_event)) {
363 return !self->IsExceptionPending();
364 } else {
365 return true;
366 }
367 }
368
369#define BRANCH_INSTRUMENTATION(offset) \
370 if (!BranchInstrumentation(offset)) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100371 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000372 }
373
374#define HANDLE_PENDING_EXCEPTION() \
375 if (!HandlePendingException()) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100376 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000377 }
378
379#define POSSIBLY_HANDLE_PENDING_EXCEPTION(is_exception_pending, next_function) \
380 if (!PossiblyHandlePendingException(is_exception_pending, inst->next_function())) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100381 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000382 }
383
384#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(is_exception_pending) \
385 if (!PossiblyHandlePendingExceptionOnInvokeImpl(is_exception_pending, inst->Next_4xx())) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100386 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000387 }
388
389#define POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(is_exception_pending) \
390 if (!PossiblyHandlePendingExceptionOnInvokeImpl(is_exception_pending, inst->Next_3xx())) { \
David Srbeckybd613ec2019-05-30 15:39:38 +0100391 return false; \
David Srbecky47ad3762018-10-31 12:43:40 +0000392 }
393
David Srbeckybd613ec2019-05-30 15:39:38 +0100394 ALWAYS_INLINE bool NOP() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100395 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100396 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100397 }
398
David Srbeckybd613ec2019-05-30 15:39:38 +0100399 ALWAYS_INLINE bool MOVE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100400 SetVReg(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100401 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100402 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100403 }
404
David Srbeckybd613ec2019-05-30 15:39:38 +0100405 ALWAYS_INLINE bool MOVE_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100406 SetVReg(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100407 inst = inst->Next_2xx();
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_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100412 SetVReg(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100413 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100414 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100415 }
416
David Srbeckybd613ec2019-05-30 15:39:38 +0100417 ALWAYS_INLINE bool MOVE_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100418 SetVRegLong(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100419 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100420 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100421 }
422
David Srbeckybd613ec2019-05-30 15:39:38 +0100423 ALWAYS_INLINE bool MOVE_WIDE_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100424 SetVRegLong(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100425 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100426 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100427 }
428
David Srbeckybd613ec2019-05-30 15:39:38 +0100429 ALWAYS_INLINE bool MOVE_WIDE_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100430 SetVRegLong(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100431 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100432 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100433 }
434
David Srbeckybd613ec2019-05-30 15:39:38 +0100435 ALWAYS_INLINE bool MOVE_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100436 SetVRegReference(A(), GetVRegReference(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100437 inst = inst->Next_1xx();
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_OBJECT_FROM16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100442 SetVRegReference(A(), GetVRegReference(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100443 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100444 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100445 }
446
David Srbeckybd613ec2019-05-30 15:39:38 +0100447 ALWAYS_INLINE bool MOVE_OBJECT_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100448 SetVRegReference(A(), GetVRegReference(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100449 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100450 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100451 }
452
David Srbeckybd613ec2019-05-30 15:39:38 +0100453 ALWAYS_INLINE bool MOVE_RESULT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100454 SetVReg(A(), ResultRegister()->GetI());
David Srbecky6da82472018-10-23 14:03:08 +0100455 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100456 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100457 }
458
David Srbeckybd613ec2019-05-30 15:39:38 +0100459 ALWAYS_INLINE bool MOVE_RESULT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100460 SetVRegLong(A(), ResultRegister()->GetJ());
David Srbecky6da82472018-10-23 14:03:08 +0100461 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100462 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100463 }
464
David Srbeckybd613ec2019-05-30 15:39:38 +0100465 ALWAYS_INLINE bool MOVE_RESULT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100466 SetVRegReference(A(), ResultRegister()->GetL());
David Srbecky6da82472018-10-23 14:03:08 +0100467 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100468 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100469 }
470
David Srbeckybd613ec2019-05-30 15:39:38 +0100471 ALWAYS_INLINE bool MOVE_EXCEPTION() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100472 ObjPtr<mirror::Throwable> exception = self->GetException();
473 DCHECK(exception != nullptr) << "No pending exception on MOVE_EXCEPTION instruction";
David Srbecky6baf6442019-05-30 14:57:43 +0100474 SetVRegReference(A(), exception);
David Srbecky6da82472018-10-23 14:03:08 +0100475 self->ClearException();
476 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100477 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100478 }
479
David Srbeckybd613ec2019-05-30 15:39:38 +0100480 ALWAYS_INLINE bool RETURN_VOID_NO_BARRIER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100481 JValue result;
482 self->AllowThreadSuspension();
David Srbecky47ad3762018-10-31 12:43:40 +0000483 if (!HandleMonitorChecks()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100484 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000485 }
David Srbecky6da82472018-10-23 14:03:08 +0100486 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
487 !SendMethodExitEvents(self,
488 instrumentation,
489 shadow_frame,
490 shadow_frame.GetThisObject(Accessor().InsSize()),
491 shadow_frame.GetMethod(),
492 inst->GetDexPc(Insns()),
493 result))) {
David Srbecky47ad3762018-10-31 12:43:40 +0000494 if (!HandlePendingExceptionWithInstrumentation(nullptr)) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100495 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000496 }
David Srbecky6da82472018-10-23 14:03:08 +0100497 }
498 if (ctx->interpret_one_instruction) {
499 /* Signal mterp to return to caller */
500 shadow_frame.SetDexPC(dex::kDexNoIndex);
501 }
502 ctx->result = result;
503 exit_interpreter_loop = true;
David Srbeckybd613ec2019-05-30 15:39:38 +0100504 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100505 }
506
David Srbeckybd613ec2019-05-30 15:39:38 +0100507 ALWAYS_INLINE bool RETURN_VOID() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100508 QuasiAtomic::ThreadFenceForConstructor();
509 JValue result;
510 self->AllowThreadSuspension();
David Srbecky47ad3762018-10-31 12:43:40 +0000511 if (!HandleMonitorChecks()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100512 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000513 }
David Srbecky6da82472018-10-23 14:03:08 +0100514 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
515 !SendMethodExitEvents(self,
516 instrumentation,
517 shadow_frame,
518 shadow_frame.GetThisObject(Accessor().InsSize()),
519 shadow_frame.GetMethod(),
520 inst->GetDexPc(Insns()),
521 result))) {
David Srbecky47ad3762018-10-31 12:43:40 +0000522 if (!HandlePendingExceptionWithInstrumentation(nullptr)) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100523 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000524 }
David Srbecky6da82472018-10-23 14:03:08 +0100525 }
526 if (ctx->interpret_one_instruction) {
527 /* Signal mterp to return to caller */
528 shadow_frame.SetDexPC(dex::kDexNoIndex);
529 }
530 ctx->result = result;
531 exit_interpreter_loop = true;
David Srbeckybd613ec2019-05-30 15:39:38 +0100532 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100533 }
534
David Srbeckybd613ec2019-05-30 15:39:38 +0100535 ALWAYS_INLINE bool RETURN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100536 JValue result;
537 result.SetJ(0);
David Srbecky6baf6442019-05-30 14:57:43 +0100538 result.SetI(GetVReg(A()));
David Srbecky6da82472018-10-23 14:03:08 +0100539 self->AllowThreadSuspension();
David Srbecky47ad3762018-10-31 12:43:40 +0000540 if (!HandleMonitorChecks()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100541 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000542 }
David Srbecky6da82472018-10-23 14:03:08 +0100543 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
544 !SendMethodExitEvents(self,
545 instrumentation,
546 shadow_frame,
547 shadow_frame.GetThisObject(Accessor().InsSize()),
548 shadow_frame.GetMethod(),
549 inst->GetDexPc(Insns()),
550 result))) {
David Srbecky47ad3762018-10-31 12:43:40 +0000551 if (!HandlePendingExceptionWithInstrumentation(nullptr)) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100552 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000553 }
David Srbecky6da82472018-10-23 14:03:08 +0100554 }
555 if (ctx->interpret_one_instruction) {
556 /* Signal mterp to return to caller */
557 shadow_frame.SetDexPC(dex::kDexNoIndex);
558 }
559 ctx->result = result;
560 exit_interpreter_loop = true;
David Srbeckybd613ec2019-05-30 15:39:38 +0100561 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100562 }
563
David Srbeckybd613ec2019-05-30 15:39:38 +0100564 ALWAYS_INLINE bool RETURN_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100565 JValue result;
David Srbecky6baf6442019-05-30 14:57:43 +0100566 result.SetJ(GetVRegLong(A()));
David Srbecky6da82472018-10-23 14:03:08 +0100567 self->AllowThreadSuspension();
David Srbecky47ad3762018-10-31 12:43:40 +0000568 if (!HandleMonitorChecks()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100569 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000570 }
David Srbecky6da82472018-10-23 14:03:08 +0100571 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
572 !SendMethodExitEvents(self,
573 instrumentation,
574 shadow_frame,
575 shadow_frame.GetThisObject(Accessor().InsSize()),
576 shadow_frame.GetMethod(),
577 inst->GetDexPc(Insns()),
578 result))) {
David Srbecky47ad3762018-10-31 12:43:40 +0000579 if (!HandlePendingExceptionWithInstrumentation(nullptr)) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100580 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000581 }
David Srbecky6da82472018-10-23 14:03:08 +0100582 }
583 if (ctx->interpret_one_instruction) {
584 /* Signal mterp to return to caller */
585 shadow_frame.SetDexPC(dex::kDexNoIndex);
586 }
587 ctx->result = result;
588 exit_interpreter_loop = true;
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 RETURN_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100593 JValue result;
594 self->AllowThreadSuspension();
David Srbecky47ad3762018-10-31 12:43:40 +0000595 if (!HandleMonitorChecks()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100596 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000597 }
David Srbeckyd6f579c2019-05-29 18:09:30 +0100598 const size_t ref_idx = A();
David Srbecky6baf6442019-05-30 14:57:43 +0100599 ObjPtr<mirror::Object> obj_result = GetVRegReference(ref_idx);
David Srbecky6da82472018-10-23 14:03:08 +0100600 if (do_assignability_check && obj_result != nullptr) {
601 ObjPtr<mirror::Class> return_type = shadow_frame.GetMethod()->ResolveReturnType();
602 // Re-load since it might have moved.
David Srbecky6baf6442019-05-30 14:57:43 +0100603 obj_result = GetVRegReference(ref_idx);
David Srbecky6da82472018-10-23 14:03:08 +0100604 if (return_type == nullptr) {
605 // Return the pending exception.
606 HANDLE_PENDING_EXCEPTION();
607 }
608 if (!obj_result->VerifierInstanceOf(return_type)) {
609 // This should never happen.
610 std::string temp1, temp2;
611 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
612 "Returning '%s' that is not instance of return type '%s'",
613 obj_result->GetClass()->GetDescriptor(&temp1),
614 return_type->GetDescriptor(&temp2));
615 HANDLE_PENDING_EXCEPTION();
616 }
617 }
618 result.SetL(obj_result);
619 if (UNLIKELY(NeedsMethodExitEvent(instrumentation) &&
620 !SendMethodExitEvents(self,
621 instrumentation,
622 shadow_frame,
623 shadow_frame.GetThisObject(Accessor().InsSize()),
624 shadow_frame.GetMethod(),
625 inst->GetDexPc(Insns()),
626 result))) {
David Srbecky47ad3762018-10-31 12:43:40 +0000627 if (!HandlePendingExceptionWithInstrumentation(nullptr)) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100628 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000629 }
David Srbecky6da82472018-10-23 14:03:08 +0100630 }
631 // Re-load since it might have moved during the MethodExitEvent.
David Srbecky6baf6442019-05-30 14:57:43 +0100632 result.SetL(GetVRegReference(ref_idx));
David Srbecky6da82472018-10-23 14:03:08 +0100633 if (ctx->interpret_one_instruction) {
634 /* Signal mterp to return to caller */
635 shadow_frame.SetDexPC(dex::kDexNoIndex);
636 }
637 ctx->result = result;
638 exit_interpreter_loop = true;
David Srbeckybd613ec2019-05-30 15:39:38 +0100639 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100640 }
641
David Srbeckybd613ec2019-05-30 15:39:38 +0100642 ALWAYS_INLINE bool CONST_4() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100643 uint4_t dst = inst->VRegA_11n(inst_data);
644 int4_t val = inst->VRegB_11n(inst_data);
David Srbecky6baf6442019-05-30 14:57:43 +0100645 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100646 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100647 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100648 }
649 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100650 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100651 }
652
David Srbeckybd613ec2019-05-30 15:39:38 +0100653 ALWAYS_INLINE bool CONST_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100654 uint8_t dst = A();
655 int16_t val = B();
David Srbecky6baf6442019-05-30 14:57:43 +0100656 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100657 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100658 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100659 }
660 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100661 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100662 }
663
David Srbeckybd613ec2019-05-30 15:39:38 +0100664 ALWAYS_INLINE bool CONST() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100665 uint8_t dst = A();
666 int32_t val = B();
David Srbecky6baf6442019-05-30 14:57:43 +0100667 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100668 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100669 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100670 }
671 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100672 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100673 }
674
David Srbeckybd613ec2019-05-30 15:39:38 +0100675 ALWAYS_INLINE bool CONST_HIGH16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100676 uint8_t dst = A();
677 int32_t val = static_cast<int32_t>(B() << 16);
David Srbecky6baf6442019-05-30 14:57:43 +0100678 SetVReg(dst, val);
David Srbecky6da82472018-10-23 14:03:08 +0100679 if (val == 0) {
David Srbecky6baf6442019-05-30 14:57:43 +0100680 SetVRegReference(dst, nullptr);
David Srbecky6da82472018-10-23 14:03:08 +0100681 }
682 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100683 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100684 }
685
David Srbeckybd613ec2019-05-30 15:39:38 +0100686 ALWAYS_INLINE bool CONST_WIDE_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100687 SetVRegLong(A(), B());
David Srbecky6da82472018-10-23 14:03:08 +0100688 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100689 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100690 }
691
David Srbeckybd613ec2019-05-30 15:39:38 +0100692 ALWAYS_INLINE bool CONST_WIDE_32() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100693 SetVRegLong(A(), B());
David Srbecky6da82472018-10-23 14:03:08 +0100694 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100695 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100696 }
697
David Srbeckybd613ec2019-05-30 15:39:38 +0100698 ALWAYS_INLINE bool CONST_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100699 SetVRegLong(A(), inst->WideVRegB());
David Srbecky6da82472018-10-23 14:03:08 +0100700 inst = inst->Next_51l();
David Srbeckybd613ec2019-05-30 15:39:38 +0100701 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100702 }
703
David Srbeckybd613ec2019-05-30 15:39:38 +0100704 ALWAYS_INLINE bool CONST_WIDE_HIGH16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100705 SetVRegLong(A(), static_cast<uint64_t>(B()) << 48);
David Srbecky6da82472018-10-23 14:03:08 +0100706 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100707 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100708 }
709
David Srbeckybd613ec2019-05-30 15:39:38 +0100710 ALWAYS_INLINE bool CONST_STRING() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100711 ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, dex::StringIndex(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100712 if (UNLIKELY(s == nullptr)) {
713 HANDLE_PENDING_EXCEPTION();
714 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100715 SetVRegReference(A(), s);
David Srbecky6da82472018-10-23 14:03:08 +0100716 inst = inst->Next_2xx();
717 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100718 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100719 }
720
David Srbeckybd613ec2019-05-30 15:39:38 +0100721 ALWAYS_INLINE bool CONST_STRING_JUMBO() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100722 ObjPtr<mirror::String> s = ResolveString(self, shadow_frame, dex::StringIndex(B()));
David Srbecky6da82472018-10-23 14:03:08 +0100723 if (UNLIKELY(s == nullptr)) {
724 HANDLE_PENDING_EXCEPTION();
725 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100726 SetVRegReference(A(), s);
David Srbecky6da82472018-10-23 14:03:08 +0100727 inst = inst->Next_3xx();
728 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100729 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100730 }
731
David Srbeckybd613ec2019-05-30 15:39:38 +0100732 ALWAYS_INLINE bool CONST_CLASS() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100733 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100734 shadow_frame.GetMethod(),
735 self,
736 false,
737 do_access_check);
738 if (UNLIKELY(c == nullptr)) {
739 HANDLE_PENDING_EXCEPTION();
740 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100741 SetVRegReference(A(), c);
David Srbecky6da82472018-10-23 14:03:08 +0100742 inst = inst->Next_2xx();
743 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100744 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100745 }
746
David Srbeckybd613ec2019-05-30 15:39:38 +0100747 ALWAYS_INLINE bool CONST_METHOD_HANDLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100748 ClassLinker* cl = Runtime::Current()->GetClassLinker();
749 ObjPtr<mirror::MethodHandle> mh = cl->ResolveMethodHandle(self,
David Srbeckyd6f579c2019-05-29 18:09:30 +0100750 B(),
David Srbecky6da82472018-10-23 14:03:08 +0100751 shadow_frame.GetMethod());
752 if (UNLIKELY(mh == nullptr)) {
753 HANDLE_PENDING_EXCEPTION();
754 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100755 SetVRegReference(A(), mh);
David Srbecky6da82472018-10-23 14:03:08 +0100756 inst = inst->Next_2xx();
757 }
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 CONST_METHOD_TYPE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100762 ClassLinker* cl = Runtime::Current()->GetClassLinker();
763 ObjPtr<mirror::MethodType> mt = cl->ResolveMethodType(self,
David Srbeckyd6f579c2019-05-29 18:09:30 +0100764 dex::ProtoIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100765 shadow_frame.GetMethod());
766 if (UNLIKELY(mt == nullptr)) {
767 HANDLE_PENDING_EXCEPTION();
768 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100769 SetVRegReference(A(), mt);
David Srbecky6da82472018-10-23 14:03:08 +0100770 inst = inst->Next_2xx();
771 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100772 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100773 }
774
David Srbeckybd613ec2019-05-30 15:39:38 +0100775 ALWAYS_INLINE bool MONITOR_ENTER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000776 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100777 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000778 }
David Srbecky6baf6442019-05-30 14:57:43 +0100779 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100780 if (UNLIKELY(obj == nullptr)) {
781 ThrowNullPointerExceptionFromInterpreter();
782 HANDLE_PENDING_EXCEPTION();
783 } else {
784 DoMonitorEnter<do_assignability_check>(self, &shadow_frame, obj);
785 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
786 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100787 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100788 }
789
David Srbeckybd613ec2019-05-30 15:39:38 +0100790 ALWAYS_INLINE bool MONITOR_EXIT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000791 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100792 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000793 }
David Srbecky6baf6442019-05-30 14:57:43 +0100794 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100795 if (UNLIKELY(obj == nullptr)) {
796 ThrowNullPointerExceptionFromInterpreter();
797 HANDLE_PENDING_EXCEPTION();
798 } else {
799 DoMonitorExit<do_assignability_check>(self, &shadow_frame, obj);
800 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
801 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100802 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100803 }
804
David Srbeckybd613ec2019-05-30 15:39:38 +0100805 ALWAYS_INLINE bool CHECK_CAST() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100806 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100807 shadow_frame.GetMethod(),
808 self,
809 false,
810 do_access_check);
811 if (UNLIKELY(c == nullptr)) {
812 HANDLE_PENDING_EXCEPTION();
813 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100814 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100815 if (UNLIKELY(obj != nullptr && !obj->InstanceOf(c))) {
816 ThrowClassCastException(c, obj->GetClass());
817 HANDLE_PENDING_EXCEPTION();
818 } else {
819 inst = inst->Next_2xx();
820 }
821 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100822 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100823 }
824
David Srbeckybd613ec2019-05-30 15:39:38 +0100825 ALWAYS_INLINE bool INSTANCE_OF() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100826 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(C()),
David Srbecky6da82472018-10-23 14:03:08 +0100827 shadow_frame.GetMethod(),
828 self,
829 false,
830 do_access_check);
831 if (UNLIKELY(c == nullptr)) {
832 HANDLE_PENDING_EXCEPTION();
833 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100834 ObjPtr<mirror::Object> obj = GetVRegReference(B());
835 SetVReg(A(), (obj != nullptr && obj->InstanceOf(c)) ? 1 : 0);
David Srbecky6da82472018-10-23 14:03:08 +0100836 inst = inst->Next_2xx();
837 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100838 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100839 }
840
David Srbeckybd613ec2019-05-30 15:39:38 +0100841 ALWAYS_INLINE bool ARRAY_LENGTH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100842 ObjPtr<mirror::Object> array = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +0100843 if (UNLIKELY(array == nullptr)) {
844 ThrowNullPointerExceptionFromInterpreter();
845 HANDLE_PENDING_EXCEPTION();
846 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100847 SetVReg(A(), array->AsArray()->GetLength());
David Srbecky6da82472018-10-23 14:03:08 +0100848 inst = inst->Next_1xx();
849 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100850 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100851 }
852
David Srbeckybd613ec2019-05-30 15:39:38 +0100853 ALWAYS_INLINE bool NEW_INSTANCE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100854 ObjPtr<mirror::Object> obj = nullptr;
David Srbeckyd6f579c2019-05-29 18:09:30 +0100855 ObjPtr<mirror::Class> c = ResolveVerifyAndClinit(dex::TypeIndex(B()),
David Srbecky6da82472018-10-23 14:03:08 +0100856 shadow_frame.GetMethod(),
857 self,
858 false,
859 do_access_check);
860 if (LIKELY(c != nullptr)) {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100861 gc::AllocatorType allocator_type = Runtime::Current()->GetHeap()->GetCurrentAllocator();
David Srbecky6da82472018-10-23 14:03:08 +0100862 if (UNLIKELY(c->IsStringClass())) {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100863 obj = mirror::String::AllocEmptyString(self, allocator_type);
David Srbecky6da82472018-10-23 14:03:08 +0100864 } else {
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100865 obj = AllocObjectFromCode(c, self, allocator_type);
David Srbecky6da82472018-10-23 14:03:08 +0100866 }
867 }
868 if (UNLIKELY(obj == nullptr)) {
869 HANDLE_PENDING_EXCEPTION();
870 } else {
871 obj->GetClass()->AssertInitializedOrInitializingInThread(self);
872 // Don't allow finalizable objects to be allocated during a transaction since these can't
873 // be finalized without a started runtime.
874 if (transaction_active && obj->GetClass()->IsFinalizable()) {
875 AbortTransactionF(self, "Allocating finalizable object in transaction: %s",
876 obj->PrettyTypeOf().c_str());
877 HANDLE_PENDING_EXCEPTION();
878 }
David Srbecky6baf6442019-05-30 14:57:43 +0100879 SetVRegReference(A(), obj);
David Srbecky6da82472018-10-23 14:03:08 +0100880 inst = inst->Next_2xx();
881 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100882 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100883 }
884
David Srbeckybd613ec2019-05-30 15:39:38 +0100885 ALWAYS_INLINE bool NEW_ARRAY() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +0100886 int32_t length = GetVReg(B());
Vladimir Marko9b81ac32019-05-16 16:47:08 +0100887 ObjPtr<mirror::Object> obj = AllocArrayFromCode<do_access_check>(
David Srbeckyd6f579c2019-05-29 18:09:30 +0100888 dex::TypeIndex(C()),
David Srbecky6da82472018-10-23 14:03:08 +0100889 length,
890 shadow_frame.GetMethod(),
891 self,
892 Runtime::Current()->GetHeap()->GetCurrentAllocator());
893 if (UNLIKELY(obj == nullptr)) {
894 HANDLE_PENDING_EXCEPTION();
895 } else {
David Srbecky6baf6442019-05-30 14:57:43 +0100896 SetVRegReference(A(), obj);
David Srbecky6da82472018-10-23 14:03:08 +0100897 inst = inst->Next_2xx();
898 }
David Srbeckybd613ec2019-05-30 15:39:38 +0100899 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100900 }
901
David Srbeckybd613ec2019-05-30 15:39:38 +0100902 ALWAYS_INLINE bool FILLED_NEW_ARRAY() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100903 bool success =
904 DoFilledNewArray<false, do_access_check, transaction_active>(inst, shadow_frame, self,
905 ResultRegister());
906 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
David Srbeckybd613ec2019-05-30 15:39:38 +0100907 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100908 }
909
David Srbeckybd613ec2019-05-30 15:39:38 +0100910 ALWAYS_INLINE bool FILLED_NEW_ARRAY_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100911 bool success =
912 DoFilledNewArray<true, do_access_check, transaction_active>(inst, shadow_frame,
913 self, ResultRegister());
914 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx);
David Srbeckybd613ec2019-05-30 15:39:38 +0100915 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100916 }
917
David Srbeckybd613ec2019-05-30 15:39:38 +0100918 ALWAYS_INLINE bool FILL_ARRAY_DATA() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +0100919 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + B();
David Srbecky6da82472018-10-23 14:03:08 +0100920 const Instruction::ArrayDataPayload* payload =
921 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr);
David Srbecky6baf6442019-05-30 14:57:43 +0100922 ObjPtr<mirror::Object> obj = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100923 bool success = FillArrayData(obj, payload);
924 if (!success) {
925 HANDLE_PENDING_EXCEPTION();
926 }
927 if (transaction_active) {
928 RecordArrayElementsInTransaction(obj->AsArray(), payload->element_count);
929 }
930 inst = inst->Next_3xx();
David Srbeckybd613ec2019-05-30 15:39:38 +0100931 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100932 }
933
David Srbeckybd613ec2019-05-30 15:39:38 +0100934 ALWAYS_INLINE bool THROW() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000935 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100936 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000937 }
David Srbecky6baf6442019-05-30 14:57:43 +0100938 ObjPtr<mirror::Object> exception = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +0100939 if (UNLIKELY(exception == nullptr)) {
940 ThrowNullPointerException("throw with null exception");
941 } else if (do_assignability_check && !exception->GetClass()->IsThrowableClass()) {
942 // This should never happen.
943 std::string temp;
944 self->ThrowNewExceptionF("Ljava/lang/InternalError;",
945 "Throwing '%s' that is not instance of Throwable",
946 exception->GetClass()->GetDescriptor(&temp));
947 } else {
948 self->SetException(exception->AsThrowable());
949 }
950 HANDLE_PENDING_EXCEPTION();
David Srbeckybd613ec2019-05-30 15:39:38 +0100951 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100952 }
953
David Srbeckybd613ec2019-05-30 15:39:38 +0100954 ALWAYS_INLINE bool GOTO() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000955 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100956 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000957 }
David Srbeckyd6f579c2019-05-29 18:09:30 +0100958 int8_t offset = A();
David Srbecky6da82472018-10-23 14:03:08 +0100959 BRANCH_INSTRUMENTATION(offset);
960 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +0000961 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +0100962 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100963 }
964
David Srbeckybd613ec2019-05-30 15:39:38 +0100965 ALWAYS_INLINE bool GOTO_16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000966 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100967 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000968 }
David Srbeckyd6f579c2019-05-29 18:09:30 +0100969 int16_t offset = A();
David Srbecky6da82472018-10-23 14:03:08 +0100970 BRANCH_INSTRUMENTATION(offset);
971 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +0000972 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +0100973 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100974 }
975
David Srbeckybd613ec2019-05-30 15:39:38 +0100976 ALWAYS_INLINE bool GOTO_32() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky47ad3762018-10-31 12:43:40 +0000977 if (!HandleAsyncException()) {
David Srbeckybd613ec2019-05-30 15:39:38 +0100978 return false;
David Srbecky47ad3762018-10-31 12:43:40 +0000979 }
David Srbeckyd6f579c2019-05-29 18:09:30 +0100980 int32_t offset = A();
David Srbecky6da82472018-10-23 14:03:08 +0100981 BRANCH_INSTRUMENTATION(offset);
982 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +0000983 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +0100984 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100985 }
986
David Srbeckybd613ec2019-05-30 15:39:38 +0100987 ALWAYS_INLINE bool PACKED_SWITCH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100988 int32_t offset = DoPackedSwitch(inst, shadow_frame, inst_data);
989 BRANCH_INSTRUMENTATION(offset);
990 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +0000991 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +0100992 return true;
David Srbecky6da82472018-10-23 14:03:08 +0100993 }
994
David Srbeckybd613ec2019-05-30 15:39:38 +0100995 ALWAYS_INLINE bool SPARSE_SWITCH() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +0100996 int32_t offset = DoSparseSwitch(inst, shadow_frame, inst_data);
997 BRANCH_INSTRUMENTATION(offset);
998 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +0000999 HandleBackwardBranch(offset);
David Srbeckybd613ec2019-05-30 15:39:38 +01001000 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001001 }
1002
1003#pragma clang diagnostic push
1004#pragma clang diagnostic ignored "-Wfloat-equal"
1005
David Srbeckybd613ec2019-05-30 15:39:38 +01001006 ALWAYS_INLINE bool CMPL_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001007 float val1 = GetVRegFloat(B());
1008 float val2 = GetVRegFloat(C());
David Srbecky6da82472018-10-23 14:03:08 +01001009 int32_t result;
1010 if (val1 > val2) {
1011 result = 1;
1012 } else if (val1 == val2) {
1013 result = 0;
1014 } else {
1015 result = -1;
1016 }
David Srbecky6baf6442019-05-30 14:57:43 +01001017 SetVReg(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001018 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001019 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001020 }
1021
David Srbeckybd613ec2019-05-30 15:39:38 +01001022 ALWAYS_INLINE bool CMPG_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001023 float val1 = GetVRegFloat(B());
1024 float val2 = GetVRegFloat(C());
David Srbecky6da82472018-10-23 14:03:08 +01001025 int32_t result;
1026 if (val1 < val2) {
1027 result = -1;
1028 } else if (val1 == val2) {
1029 result = 0;
1030 } else {
1031 result = 1;
1032 }
David Srbecky6baf6442019-05-30 14:57:43 +01001033 SetVReg(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001034 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001035 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001036 }
1037
David Srbeckybd613ec2019-05-30 15:39:38 +01001038 ALWAYS_INLINE bool CMPL_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001039 double val1 = GetVRegDouble(B());
1040 double val2 = GetVRegDouble(C());
David Srbecky6da82472018-10-23 14:03:08 +01001041 int32_t result;
1042 if (val1 > val2) {
1043 result = 1;
1044 } else if (val1 == val2) {
1045 result = 0;
1046 } else {
1047 result = -1;
1048 }
David Srbecky6baf6442019-05-30 14:57:43 +01001049 SetVReg(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001050 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001051 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001052 }
1053
David Srbeckybd613ec2019-05-30 15:39:38 +01001054 ALWAYS_INLINE bool CMPG_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001055 double val1 = GetVRegDouble(B());
1056 double val2 = GetVRegDouble(C());
David Srbecky6da82472018-10-23 14:03:08 +01001057 int32_t result;
1058 if (val1 < val2) {
1059 result = -1;
1060 } else if (val1 == val2) {
1061 result = 0;
1062 } else {
1063 result = 1;
1064 }
David Srbecky6baf6442019-05-30 14:57:43 +01001065 SetVReg(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001066 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001067 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001068 }
1069
1070#pragma clang diagnostic pop
1071
David Srbeckybd613ec2019-05-30 15:39:38 +01001072 ALWAYS_INLINE bool CMP_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001073 int64_t val1 = GetVRegLong(B());
1074 int64_t val2 = GetVRegLong(C());
David Srbecky6da82472018-10-23 14:03:08 +01001075 int32_t result;
1076 if (val1 > val2) {
1077 result = 1;
1078 } else if (val1 == val2) {
1079 result = 0;
1080 } else {
1081 result = -1;
1082 }
David Srbecky6baf6442019-05-30 14:57:43 +01001083 SetVReg(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001084 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001085 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001086 }
1087
David Srbeckybd613ec2019-05-30 15:39:38 +01001088 ALWAYS_INLINE bool IF_EQ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001089 if (GetVReg(A()) == GetVReg(B())) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001090 int16_t offset = C();
David Srbecky6da82472018-10-23 14:03:08 +01001091 BRANCH_INSTRUMENTATION(offset);
1092 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001093 HandleBackwardBranch(offset);
David Srbecky6da82472018-10-23 14:03:08 +01001094 } else {
1095 BRANCH_INSTRUMENTATION(2);
1096 inst = inst->Next_2xx();
1097 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001098 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001099 }
1100
David Srbeckybd613ec2019-05-30 15:39:38 +01001101 ALWAYS_INLINE bool IF_NE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001102 if (GetVReg(A()) != GetVReg(B())) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001103 int16_t offset = C();
David Srbecky6da82472018-10-23 14:03:08 +01001104 BRANCH_INSTRUMENTATION(offset);
1105 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001106 HandleBackwardBranch(offset);
David Srbecky6da82472018-10-23 14:03:08 +01001107 } else {
1108 BRANCH_INSTRUMENTATION(2);
1109 inst = inst->Next_2xx();
1110 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001111 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001112 }
1113
David Srbeckybd613ec2019-05-30 15:39:38 +01001114 ALWAYS_INLINE bool IF_LT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001115 if (GetVReg(A()) < GetVReg(B())) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001116 int16_t offset = C();
David Srbecky6da82472018-10-23 14:03:08 +01001117 BRANCH_INSTRUMENTATION(offset);
1118 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001119 HandleBackwardBranch(offset);
David Srbecky6da82472018-10-23 14:03:08 +01001120 } else {
1121 BRANCH_INSTRUMENTATION(2);
1122 inst = inst->Next_2xx();
1123 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001124 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001125 }
1126
David Srbeckybd613ec2019-05-30 15:39:38 +01001127 ALWAYS_INLINE bool IF_GE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001128 if (GetVReg(A()) >= GetVReg(B())) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001129 int16_t offset = C();
David Srbecky6da82472018-10-23 14:03:08 +01001130 BRANCH_INSTRUMENTATION(offset);
1131 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001132 HandleBackwardBranch(offset);
David Srbecky6da82472018-10-23 14:03:08 +01001133 } else {
1134 BRANCH_INSTRUMENTATION(2);
1135 inst = inst->Next_2xx();
1136 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001137 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001138 }
1139
David Srbeckybd613ec2019-05-30 15:39:38 +01001140 ALWAYS_INLINE bool IF_GT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001141 if (GetVReg(A()) > GetVReg(B())) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001142 int16_t offset = C();
David Srbecky6da82472018-10-23 14:03:08 +01001143 BRANCH_INSTRUMENTATION(offset);
1144 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001145 HandleBackwardBranch(offset);
David Srbecky6da82472018-10-23 14:03:08 +01001146 } else {
1147 BRANCH_INSTRUMENTATION(2);
1148 inst = inst->Next_2xx();
1149 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001150 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001151 }
1152
David Srbeckybd613ec2019-05-30 15:39:38 +01001153 ALWAYS_INLINE bool IF_LE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001154 if (GetVReg(A()) <= GetVReg(B())) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001155 int16_t offset = C();
David Srbecky6da82472018-10-23 14:03:08 +01001156 BRANCH_INSTRUMENTATION(offset);
1157 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001158 HandleBackwardBranch(offset);
David Srbecky6da82472018-10-23 14:03:08 +01001159 } else {
1160 BRANCH_INSTRUMENTATION(2);
1161 inst = inst->Next_2xx();
1162 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001163 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001164 }
1165
David Srbeckybd613ec2019-05-30 15:39:38 +01001166 ALWAYS_INLINE bool IF_EQZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001167 if (GetVReg(A()) == 0) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001168 int16_t offset = B();
David Srbecky6da82472018-10-23 14:03:08 +01001169 BRANCH_INSTRUMENTATION(offset);
1170 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001171 HandleBackwardBranch(offset);
David Srbecky6da82472018-10-23 14:03:08 +01001172 } else {
1173 BRANCH_INSTRUMENTATION(2);
1174 inst = inst->Next_2xx();
1175 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001176 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001177 }
1178
David Srbeckybd613ec2019-05-30 15:39:38 +01001179 ALWAYS_INLINE bool IF_NEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001180 if (GetVReg(A()) != 0) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001181 int16_t offset = B();
David Srbecky6da82472018-10-23 14:03:08 +01001182 BRANCH_INSTRUMENTATION(offset);
1183 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001184 HandleBackwardBranch(offset);
David Srbecky6da82472018-10-23 14:03:08 +01001185 } else {
1186 BRANCH_INSTRUMENTATION(2);
1187 inst = inst->Next_2xx();
1188 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001189 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001190 }
1191
David Srbeckybd613ec2019-05-30 15:39:38 +01001192 ALWAYS_INLINE bool IF_LTZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001193 if (GetVReg(A()) < 0) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001194 int16_t offset = B();
David Srbecky6da82472018-10-23 14:03:08 +01001195 BRANCH_INSTRUMENTATION(offset);
1196 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001197 HandleBackwardBranch(offset);
David Srbecky6da82472018-10-23 14:03:08 +01001198 } else {
1199 BRANCH_INSTRUMENTATION(2);
1200 inst = inst->Next_2xx();
1201 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001202 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001203 }
1204
David Srbeckybd613ec2019-05-30 15:39:38 +01001205 ALWAYS_INLINE bool IF_GEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001206 if (GetVReg(A()) >= 0) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001207 int16_t offset = B();
David Srbecky6da82472018-10-23 14:03:08 +01001208 BRANCH_INSTRUMENTATION(offset);
1209 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001210 HandleBackwardBranch(offset);
David Srbecky6da82472018-10-23 14:03:08 +01001211 } else {
1212 BRANCH_INSTRUMENTATION(2);
1213 inst = inst->Next_2xx();
1214 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001215 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001216 }
1217
David Srbeckybd613ec2019-05-30 15:39:38 +01001218 ALWAYS_INLINE bool IF_GTZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001219 if (GetVReg(A()) > 0) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001220 int16_t offset = B();
David Srbecky6da82472018-10-23 14:03:08 +01001221 BRANCH_INSTRUMENTATION(offset);
1222 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001223 HandleBackwardBranch(offset);
David Srbecky6da82472018-10-23 14:03:08 +01001224 } else {
1225 BRANCH_INSTRUMENTATION(2);
1226 inst = inst->Next_2xx();
1227 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001228 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001229 }
1230
David Srbeckybd613ec2019-05-30 15:39:38 +01001231 ALWAYS_INLINE bool IF_LEZ() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001232 if (GetVReg(A()) <= 0) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01001233 int16_t offset = B();
David Srbecky6da82472018-10-23 14:03:08 +01001234 BRANCH_INSTRUMENTATION(offset);
1235 inst = inst->RelativeAt(offset);
David Srbecky47ad3762018-10-31 12:43:40 +00001236 HandleBackwardBranch(offset);
David Srbecky6da82472018-10-23 14:03:08 +01001237 } else {
1238 BRANCH_INSTRUMENTATION(2);
1239 inst = inst->Next_2xx();
1240 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001241 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001242 }
1243
David Srbeckybd613ec2019-05-30 15:39:38 +01001244 ALWAYS_INLINE bool AGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001245 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001246 if (UNLIKELY(a == nullptr)) {
1247 ThrowNullPointerExceptionFromInterpreter();
1248 HANDLE_PENDING_EXCEPTION();
1249 }
David Srbecky6baf6442019-05-30 14:57:43 +01001250 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001251 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
1252 if (array->CheckIsValidIndex(index)) {
David Srbecky6baf6442019-05-30 14:57:43 +01001253 SetVReg(A(), array->GetWithoutChecks(index));
David Srbecky6da82472018-10-23 14:03:08 +01001254 inst = inst->Next_2xx();
1255 } else {
1256 HANDLE_PENDING_EXCEPTION();
1257 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001258 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001259 }
1260
David Srbeckybd613ec2019-05-30 15:39:38 +01001261 ALWAYS_INLINE bool AGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001262 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001263 if (UNLIKELY(a == nullptr)) {
1264 ThrowNullPointerExceptionFromInterpreter();
1265 HANDLE_PENDING_EXCEPTION();
1266 }
David Srbecky6baf6442019-05-30 14:57:43 +01001267 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001268 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
1269 if (array->CheckIsValidIndex(index)) {
David Srbecky6baf6442019-05-30 14:57:43 +01001270 SetVReg(A(), array->GetWithoutChecks(index));
David Srbecky6da82472018-10-23 14:03:08 +01001271 inst = inst->Next_2xx();
1272 } else {
1273 HANDLE_PENDING_EXCEPTION();
1274 }
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 AGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001279 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001280 if (UNLIKELY(a == nullptr)) {
1281 ThrowNullPointerExceptionFromInterpreter();
1282 HANDLE_PENDING_EXCEPTION();
1283 }
David Srbecky6baf6442019-05-30 14:57:43 +01001284 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001285 ObjPtr<mirror::CharArray> array = a->AsCharArray();
1286 if (array->CheckIsValidIndex(index)) {
David Srbecky6baf6442019-05-30 14:57:43 +01001287 SetVReg(A(), array->GetWithoutChecks(index));
David Srbecky6da82472018-10-23 14:03:08 +01001288 inst = inst->Next_2xx();
1289 } else {
1290 HANDLE_PENDING_EXCEPTION();
1291 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001292 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001293 }
1294
David Srbeckybd613ec2019-05-30 15:39:38 +01001295 ALWAYS_INLINE bool AGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001296 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001297 if (UNLIKELY(a == nullptr)) {
1298 ThrowNullPointerExceptionFromInterpreter();
1299 HANDLE_PENDING_EXCEPTION();
1300 }
David Srbecky6baf6442019-05-30 14:57:43 +01001301 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001302 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
1303 if (array->CheckIsValidIndex(index)) {
David Srbecky6baf6442019-05-30 14:57:43 +01001304 SetVReg(A(), array->GetWithoutChecks(index));
David Srbecky6da82472018-10-23 14:03:08 +01001305 inst = inst->Next_2xx();
1306 } else {
1307 HANDLE_PENDING_EXCEPTION();
1308 }
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 AGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001313 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001314 if (UNLIKELY(a == nullptr)) {
1315 ThrowNullPointerExceptionFromInterpreter();
1316 HANDLE_PENDING_EXCEPTION();
1317 }
David Srbecky6baf6442019-05-30 14:57:43 +01001318 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001319 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
1320 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
1321 if (array->CheckIsValidIndex(index)) {
David Srbecky6baf6442019-05-30 14:57:43 +01001322 SetVReg(A(), array->GetWithoutChecks(index));
David Srbecky6da82472018-10-23 14:03:08 +01001323 inst = inst->Next_2xx();
1324 } else {
1325 HANDLE_PENDING_EXCEPTION();
1326 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001327 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001328 }
1329
David Srbeckybd613ec2019-05-30 15:39:38 +01001330 ALWAYS_INLINE bool AGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001331 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001332 if (UNLIKELY(a == nullptr)) {
1333 ThrowNullPointerExceptionFromInterpreter();
1334 HANDLE_PENDING_EXCEPTION();
1335 }
David Srbecky6baf6442019-05-30 14:57:43 +01001336 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001337 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
1338 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
1339 if (array->CheckIsValidIndex(index)) {
David Srbecky6baf6442019-05-30 14:57:43 +01001340 SetVRegLong(A(), array->GetWithoutChecks(index));
David Srbecky6da82472018-10-23 14:03:08 +01001341 inst = inst->Next_2xx();
1342 } else {
1343 HANDLE_PENDING_EXCEPTION();
1344 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001345 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001346 }
1347
David Srbeckybd613ec2019-05-30 15:39:38 +01001348 ALWAYS_INLINE bool AGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001349 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001350 if (UNLIKELY(a == nullptr)) {
1351 ThrowNullPointerExceptionFromInterpreter();
1352 HANDLE_PENDING_EXCEPTION();
1353 }
David Srbecky6baf6442019-05-30 14:57:43 +01001354 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001355 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
1356 if (array->CheckIsValidIndex(index)) {
David Srbecky6baf6442019-05-30 14:57:43 +01001357 SetVRegReference(A(), array->GetWithoutChecks(index));
David Srbecky6da82472018-10-23 14:03:08 +01001358 inst = inst->Next_2xx();
1359 } else {
1360 HANDLE_PENDING_EXCEPTION();
1361 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001362 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001363 }
1364
David Srbeckybd613ec2019-05-30 15:39:38 +01001365 ALWAYS_INLINE bool APUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001366 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001367 if (UNLIKELY(a == nullptr)) {
1368 ThrowNullPointerExceptionFromInterpreter();
1369 HANDLE_PENDING_EXCEPTION();
1370 }
David Srbecky6baf6442019-05-30 14:57:43 +01001371 uint8_t val = GetVReg(A());
1372 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001373 ObjPtr<mirror::BooleanArray> array = a->AsBooleanArray();
1374 if (array->CheckIsValidIndex(index)) {
1375 array->SetWithoutChecks<transaction_active>(index, val);
1376 inst = inst->Next_2xx();
1377 } else {
1378 HANDLE_PENDING_EXCEPTION();
1379 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001380 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001381 }
1382
David Srbeckybd613ec2019-05-30 15:39:38 +01001383 ALWAYS_INLINE bool APUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001384 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001385 if (UNLIKELY(a == nullptr)) {
1386 ThrowNullPointerExceptionFromInterpreter();
1387 HANDLE_PENDING_EXCEPTION();
1388 }
David Srbecky6baf6442019-05-30 14:57:43 +01001389 int8_t val = GetVReg(A());
1390 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001391 ObjPtr<mirror::ByteArray> array = a->AsByteArray();
1392 if (array->CheckIsValidIndex(index)) {
1393 array->SetWithoutChecks<transaction_active>(index, val);
1394 inst = inst->Next_2xx();
1395 } else {
1396 HANDLE_PENDING_EXCEPTION();
1397 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001398 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001399 }
1400
David Srbeckybd613ec2019-05-30 15:39:38 +01001401 ALWAYS_INLINE bool APUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001402 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001403 if (UNLIKELY(a == nullptr)) {
1404 ThrowNullPointerExceptionFromInterpreter();
1405 HANDLE_PENDING_EXCEPTION();
1406 }
David Srbecky6baf6442019-05-30 14:57:43 +01001407 uint16_t val = GetVReg(A());
1408 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001409 ObjPtr<mirror::CharArray> array = a->AsCharArray();
1410 if (array->CheckIsValidIndex(index)) {
1411 array->SetWithoutChecks<transaction_active>(index, val);
1412 inst = inst->Next_2xx();
1413 } else {
1414 HANDLE_PENDING_EXCEPTION();
1415 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001416 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001417 }
1418
David Srbeckybd613ec2019-05-30 15:39:38 +01001419 ALWAYS_INLINE bool APUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001420 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001421 if (UNLIKELY(a == nullptr)) {
1422 ThrowNullPointerExceptionFromInterpreter();
1423 HANDLE_PENDING_EXCEPTION();
1424 }
David Srbecky6baf6442019-05-30 14:57:43 +01001425 int16_t val = GetVReg(A());
1426 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001427 ObjPtr<mirror::ShortArray> array = a->AsShortArray();
1428 if (array->CheckIsValidIndex(index)) {
1429 array->SetWithoutChecks<transaction_active>(index, val);
1430 inst = inst->Next_2xx();
1431 } else {
1432 HANDLE_PENDING_EXCEPTION();
1433 }
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 APUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001438 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001439 if (UNLIKELY(a == nullptr)) {
1440 ThrowNullPointerExceptionFromInterpreter();
1441 HANDLE_PENDING_EXCEPTION();
1442 }
David Srbecky6baf6442019-05-30 14:57:43 +01001443 int32_t val = GetVReg(A());
1444 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001445 DCHECK(a->IsIntArray() || a->IsFloatArray()) << a->PrettyTypeOf();
1446 ObjPtr<mirror::IntArray> array = ObjPtr<mirror::IntArray>::DownCast(a);
1447 if (array->CheckIsValidIndex(index)) {
1448 array->SetWithoutChecks<transaction_active>(index, val);
1449 inst = inst->Next_2xx();
1450 } else {
1451 HANDLE_PENDING_EXCEPTION();
1452 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001453 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001454 }
1455
David Srbeckybd613ec2019-05-30 15:39:38 +01001456 ALWAYS_INLINE bool APUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001457 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001458 if (UNLIKELY(a == nullptr)) {
1459 ThrowNullPointerExceptionFromInterpreter();
1460 HANDLE_PENDING_EXCEPTION();
1461 }
David Srbecky6baf6442019-05-30 14:57:43 +01001462 int64_t val = GetVRegLong(A());
1463 int32_t index = GetVReg(C());
David Srbecky6da82472018-10-23 14:03:08 +01001464 DCHECK(a->IsLongArray() || a->IsDoubleArray()) << a->PrettyTypeOf();
1465 ObjPtr<mirror::LongArray> array = ObjPtr<mirror::LongArray>::DownCast(a);
1466 if (array->CheckIsValidIndex(index)) {
1467 array->SetWithoutChecks<transaction_active>(index, val);
1468 inst = inst->Next_2xx();
1469 } else {
1470 HANDLE_PENDING_EXCEPTION();
1471 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001472 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001473 }
1474
David Srbeckybd613ec2019-05-30 15:39:38 +01001475 ALWAYS_INLINE bool APUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001476 ObjPtr<mirror::Object> a = GetVRegReference(B());
David Srbecky6da82472018-10-23 14:03:08 +01001477 if (UNLIKELY(a == nullptr)) {
1478 ThrowNullPointerExceptionFromInterpreter();
1479 HANDLE_PENDING_EXCEPTION();
1480 }
David Srbecky6baf6442019-05-30 14:57:43 +01001481 int32_t index = GetVReg(C());
1482 ObjPtr<mirror::Object> val = GetVRegReference(A());
David Srbecky6da82472018-10-23 14:03:08 +01001483 ObjPtr<mirror::ObjectArray<mirror::Object>> array = a->AsObjectArray<mirror::Object>();
1484 if (array->CheckIsValidIndex(index) && array->CheckAssignable(val)) {
1485 array->SetWithoutChecks<transaction_active>(index, val);
1486 inst = inst->Next_2xx();
1487 } else {
1488 HANDLE_PENDING_EXCEPTION();
1489 }
David Srbeckybd613ec2019-05-30 15:39:38 +01001490 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001491 }
1492
David Srbeckybd613ec2019-05-30 15:39:38 +01001493 ALWAYS_INLINE bool IGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001494 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(
1495 self, shadow_frame, inst, inst_data);
1496 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001497 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001498 }
1499
David Srbeckybd613ec2019-05-30 15:39:38 +01001500 ALWAYS_INLINE bool IGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001501 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(
1502 self, shadow_frame, inst, inst_data);
1503 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001504 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001505 }
1506
David Srbeckybd613ec2019-05-30 15:39:38 +01001507 ALWAYS_INLINE bool IGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001508 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(
1509 self, shadow_frame, inst, inst_data);
1510 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
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 IGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001515 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(
1516 self, shadow_frame, inst, inst_data);
1517 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001518 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001519 }
1520
David Srbeckybd613ec2019-05-30 15:39:38 +01001521 ALWAYS_INLINE bool IGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001522 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(
1523 self, shadow_frame, inst, inst_data);
1524 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001525 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001526 }
1527
David Srbeckybd613ec2019-05-30 15:39:38 +01001528 ALWAYS_INLINE bool IGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001529 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(
1530 self, shadow_frame, inst, inst_data);
1531 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001532 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001533 }
1534
David Srbeckybd613ec2019-05-30 15:39:38 +01001535 ALWAYS_INLINE bool IGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001536 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(
1537 self, shadow_frame, inst, inst_data);
1538 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
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 IGET_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001543 bool success = DoIGetQuick<Primitive::kPrimInt>(shadow_frame, inst, inst_data);
1544 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
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 IGET_WIDE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001549 bool success = DoIGetQuick<Primitive::kPrimLong>(shadow_frame, inst, inst_data);
1550 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
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 IGET_OBJECT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001555 bool success = DoIGetQuick<Primitive::kPrimNot>(shadow_frame, inst, inst_data);
1556 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
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 IGET_BOOLEAN_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001561 bool success = DoIGetQuick<Primitive::kPrimBoolean>(shadow_frame, inst, inst_data);
1562 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
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 IGET_BYTE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001567 bool success = DoIGetQuick<Primitive::kPrimByte>(shadow_frame, inst, inst_data);
1568 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
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 IGET_CHAR_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001573 bool success = DoIGetQuick<Primitive::kPrimChar>(shadow_frame, inst, inst_data);
1574 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
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 IGET_SHORT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001579 bool success = DoIGetQuick<Primitive::kPrimShort>(shadow_frame, inst, inst_data);
1580 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
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 SGET_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001585 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check,
1586 transaction_active>(self, shadow_frame, inst, inst_data);
1587 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001588 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001589 }
1590
David Srbeckybd613ec2019-05-30 15:39:38 +01001591 ALWAYS_INLINE bool SGET_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001592 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check,
1593 transaction_active>(self, shadow_frame, inst, inst_data);
1594 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001595 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001596 }
1597
David Srbeckybd613ec2019-05-30 15:39:38 +01001598 ALWAYS_INLINE bool SGET_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001599 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check,
1600 transaction_active>(self, shadow_frame, inst, inst_data);
1601 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001602 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001603 }
1604
David Srbeckybd613ec2019-05-30 15:39:38 +01001605 ALWAYS_INLINE bool SGET_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001606 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check,
1607 transaction_active>(self, shadow_frame, inst, inst_data);
1608 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
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 SGET() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001613 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check,
1614 transaction_active>(self, shadow_frame, inst, inst_data);
1615 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001616 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001617 }
1618
David Srbeckybd613ec2019-05-30 15:39:38 +01001619 ALWAYS_INLINE bool SGET_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001620 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check,
1621 transaction_active>(self, shadow_frame, inst, inst_data);
1622 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001623 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001624 }
1625
David Srbeckybd613ec2019-05-30 15:39:38 +01001626 ALWAYS_INLINE bool SGET_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001627 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check,
1628 transaction_active>(self, shadow_frame, inst, inst_data);
1629 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001630 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001631 }
1632
David Srbeckybd613ec2019-05-30 15:39:38 +01001633 ALWAYS_INLINE bool IPUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001634 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1635 transaction_active>(self, shadow_frame, inst, inst_data);
1636 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001637 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001638 }
1639
David Srbeckybd613ec2019-05-30 15:39:38 +01001640 ALWAYS_INLINE bool IPUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001641 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check,
1642 transaction_active>(self, shadow_frame, inst, inst_data);
1643 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001644 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001645 }
1646
David Srbeckybd613ec2019-05-30 15:39:38 +01001647 ALWAYS_INLINE bool IPUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001648 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check,
1649 transaction_active>(self, shadow_frame, inst, inst_data);
1650 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
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 IPUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001655 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check,
1656 transaction_active>(self, shadow_frame, inst, inst_data);
1657 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001658 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001659 }
1660
David Srbeckybd613ec2019-05-30 15:39:38 +01001661 ALWAYS_INLINE bool IPUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001662 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check,
1663 transaction_active>(self, shadow_frame, inst, inst_data);
1664 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001665 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001666 }
1667
David Srbeckybd613ec2019-05-30 15:39:38 +01001668 ALWAYS_INLINE bool IPUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001669 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check,
1670 transaction_active>(self, shadow_frame, inst, inst_data);
1671 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001672 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001673 }
1674
David Srbeckybd613ec2019-05-30 15:39:38 +01001675 ALWAYS_INLINE bool IPUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001676 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check,
1677 transaction_active>(self, shadow_frame, inst, inst_data);
1678 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001679 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001680 }
1681
David Srbeckybd613ec2019-05-30 15:39:38 +01001682 ALWAYS_INLINE bool IPUT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001683 bool success = DoIPutQuick<Primitive::kPrimInt, transaction_active>(
1684 shadow_frame, inst, inst_data);
1685 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001686 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001687 }
1688
David Srbeckybd613ec2019-05-30 15:39:38 +01001689 ALWAYS_INLINE bool IPUT_BOOLEAN_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001690 bool success = DoIPutQuick<Primitive::kPrimBoolean, transaction_active>(
1691 shadow_frame, inst, inst_data);
1692 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001693 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001694 }
1695
David Srbeckybd613ec2019-05-30 15:39:38 +01001696 ALWAYS_INLINE bool IPUT_BYTE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001697 bool success = DoIPutQuick<Primitive::kPrimByte, transaction_active>(
1698 shadow_frame, inst, inst_data);
1699 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001700 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001701 }
1702
David Srbeckybd613ec2019-05-30 15:39:38 +01001703 ALWAYS_INLINE bool IPUT_CHAR_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001704 bool success = DoIPutQuick<Primitive::kPrimChar, transaction_active>(
1705 shadow_frame, inst, inst_data);
1706 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001707 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001708 }
1709
David Srbeckybd613ec2019-05-30 15:39:38 +01001710 ALWAYS_INLINE bool IPUT_SHORT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001711 bool success = DoIPutQuick<Primitive::kPrimShort, transaction_active>(
1712 shadow_frame, inst, inst_data);
1713 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001714 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001715 }
1716
David Srbeckybd613ec2019-05-30 15:39:38 +01001717 ALWAYS_INLINE bool IPUT_WIDE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001718 bool success = DoIPutQuick<Primitive::kPrimLong, transaction_active>(
1719 shadow_frame, inst, inst_data);
1720 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001721 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001722 }
1723
David Srbeckybd613ec2019-05-30 15:39:38 +01001724 ALWAYS_INLINE bool IPUT_OBJECT_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001725 bool success = DoIPutQuick<Primitive::kPrimNot, transaction_active>(
1726 shadow_frame, inst, inst_data);
1727 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001728 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001729 }
1730
David Srbeckybd613ec2019-05-30 15:39:38 +01001731 ALWAYS_INLINE bool SPUT_BOOLEAN() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001732 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check,
1733 transaction_active>(self, shadow_frame, inst, inst_data);
1734 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
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 SPUT_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001739 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check,
1740 transaction_active>(self, shadow_frame, inst, inst_data);
1741 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001742 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001743 }
1744
David Srbeckybd613ec2019-05-30 15:39:38 +01001745 ALWAYS_INLINE bool SPUT_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001746 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check,
1747 transaction_active>(self, shadow_frame, inst, inst_data);
1748 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001749 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001750 }
1751
David Srbeckybd613ec2019-05-30 15:39:38 +01001752 ALWAYS_INLINE bool SPUT_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001753 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check,
1754 transaction_active>(self, shadow_frame, inst, inst_data);
1755 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001756 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001757 }
1758
David Srbeckybd613ec2019-05-30 15:39:38 +01001759 ALWAYS_INLINE bool SPUT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001760 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check,
1761 transaction_active>(self, shadow_frame, inst, inst_data);
1762 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
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 SPUT_WIDE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001767 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check,
1768 transaction_active>(self, shadow_frame, inst, inst_data);
1769 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001770 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001771 }
1772
David Srbeckybd613ec2019-05-30 15:39:38 +01001773 ALWAYS_INLINE bool SPUT_OBJECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001774 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check,
1775 transaction_active>(self, shadow_frame, inst, inst_data);
1776 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01001777 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001778 }
1779
David Srbeckybd613ec2019-05-30 15:39:38 +01001780 ALWAYS_INLINE bool INVOKE_VIRTUAL() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001781 bool success = DoInvoke<kVirtual, false, do_access_check, /*is_mterp=*/ false>(
1782 self, shadow_frame, inst, inst_data, ResultRegister());
1783 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001784 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001785 }
1786
David Srbeckybd613ec2019-05-30 15:39:38 +01001787 ALWAYS_INLINE bool INVOKE_VIRTUAL_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001788 bool success = DoInvoke<kVirtual, true, do_access_check, /*is_mterp=*/ false>(
1789 self, shadow_frame, inst, inst_data, ResultRegister());
1790 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001791 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001792 }
1793
David Srbeckybd613ec2019-05-30 15:39:38 +01001794 ALWAYS_INLINE bool INVOKE_SUPER() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001795 bool success = DoInvoke<kSuper, false, do_access_check, /*is_mterp=*/ false>(
1796 self, shadow_frame, inst, inst_data, ResultRegister());
1797 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001798 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001799 }
1800
David Srbeckybd613ec2019-05-30 15:39:38 +01001801 ALWAYS_INLINE bool INVOKE_SUPER_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001802 bool success = DoInvoke<kSuper, true, do_access_check, /*is_mterp=*/ false>(
1803 self, shadow_frame, inst, inst_data, ResultRegister());
1804 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001805 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001806 }
1807
David Srbeckybd613ec2019-05-30 15:39:38 +01001808 ALWAYS_INLINE bool INVOKE_DIRECT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001809 bool success = DoInvoke<kDirect, false, do_access_check, /*is_mterp=*/ false>(
1810 self, shadow_frame, inst, inst_data, ResultRegister());
1811 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001812 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001813 }
1814
David Srbeckybd613ec2019-05-30 15:39:38 +01001815 ALWAYS_INLINE bool INVOKE_DIRECT_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001816 bool success = DoInvoke<kDirect, true, do_access_check, /*is_mterp=*/ false>(
1817 self, shadow_frame, inst, inst_data, ResultRegister());
1818 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001819 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001820 }
1821
David Srbeckybd613ec2019-05-30 15:39:38 +01001822 ALWAYS_INLINE bool INVOKE_INTERFACE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001823 bool success = DoInvoke<kInterface, false, do_access_check, /*is_mterp=*/ false>(
1824 self, shadow_frame, inst, inst_data, ResultRegister());
1825 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001826 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001827 }
1828
David Srbeckybd613ec2019-05-30 15:39:38 +01001829 ALWAYS_INLINE bool INVOKE_INTERFACE_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001830 bool success = DoInvoke<kInterface, true, do_access_check, /*is_mterp=*/ false>(
1831 self, shadow_frame, inst, inst_data, ResultRegister());
1832 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001833 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001834 }
1835
David Srbeckybd613ec2019-05-30 15:39:38 +01001836 ALWAYS_INLINE bool INVOKE_STATIC() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001837 bool success = DoInvoke<kStatic, false, do_access_check, /*is_mterp=*/ false>(
1838 self, shadow_frame, inst, inst_data, ResultRegister());
1839 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001840 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001841 }
1842
David Srbeckybd613ec2019-05-30 15:39:38 +01001843 ALWAYS_INLINE bool INVOKE_STATIC_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001844 bool success = DoInvoke<kStatic, true, do_access_check, /*is_mterp=*/ false>(
1845 self, shadow_frame, inst, inst_data, ResultRegister());
1846 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001847 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001848 }
1849
David Srbeckybd613ec2019-05-30 15:39:38 +01001850 ALWAYS_INLINE bool INVOKE_VIRTUAL_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001851 bool success = DoInvoke<kVirtual, false, do_access_check, /*is_mterp=*/ false,
1852 /*is_quick=*/ true>(self, shadow_frame, inst, inst_data, ResultRegister());
1853 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001854 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001855 }
1856
David Srbeckybd613ec2019-05-30 15:39:38 +01001857 ALWAYS_INLINE bool INVOKE_VIRTUAL_RANGE_QUICK() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001858 bool success = DoInvoke<kVirtual, true, do_access_check, /*is_mterp=*/ false,
1859 /*is_quick=*/ true>(self, shadow_frame, inst, inst_data, ResultRegister());
1860 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001861 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001862 }
1863
David Srbeckybd613ec2019-05-30 15:39:38 +01001864 ALWAYS_INLINE bool INVOKE_POLYMORPHIC() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001865 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1866 bool success = DoInvokePolymorphic</* is_range= */ false>(
1867 self, shadow_frame, inst, inst_data, ResultRegister());
1868 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001869 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001870 }
1871
David Srbeckybd613ec2019-05-30 15:39:38 +01001872 ALWAYS_INLINE bool INVOKE_POLYMORPHIC_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001873 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1874 bool success = DoInvokePolymorphic</* is_range= */ true>(
1875 self, shadow_frame, inst, inst_data, ResultRegister());
1876 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001877 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001878 }
1879
David Srbeckybd613ec2019-05-30 15:39:38 +01001880 ALWAYS_INLINE bool INVOKE_CUSTOM() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001881 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1882 bool success = DoInvokeCustom</* is_range= */ false>(
1883 self, shadow_frame, inst, inst_data, ResultRegister());
1884 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001885 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001886 }
1887
David Srbeckybd613ec2019-05-30 15:39:38 +01001888 ALWAYS_INLINE bool INVOKE_CUSTOM_RANGE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01001889 DCHECK(Runtime::Current()->IsMethodHandlesEnabled());
1890 bool success = DoInvokeCustom</* is_range= */ true>(
1891 self, shadow_frame, inst, inst_data, ResultRegister());
1892 POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE(!success);
David Srbeckybd613ec2019-05-30 15:39:38 +01001893 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001894 }
1895
David Srbeckybd613ec2019-05-30 15:39:38 +01001896 ALWAYS_INLINE bool NEG_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001897 SetVReg(A(), -GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001898 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001899 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001900 }
1901
David Srbeckybd613ec2019-05-30 15:39:38 +01001902 ALWAYS_INLINE bool NOT_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001903 SetVReg(A(), ~GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001904 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001905 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001906 }
1907
David Srbeckybd613ec2019-05-30 15:39:38 +01001908 ALWAYS_INLINE bool NEG_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001909 SetVRegLong(A(), -GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001910 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001911 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001912 }
1913
David Srbeckybd613ec2019-05-30 15:39:38 +01001914 ALWAYS_INLINE bool NOT_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001915 SetVRegLong(A(), ~GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001916 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001917 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001918 }
1919
David Srbeckybd613ec2019-05-30 15:39:38 +01001920 ALWAYS_INLINE bool NEG_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001921 SetVRegFloat(A(), -GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001922 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001923 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001924 }
1925
David Srbeckybd613ec2019-05-30 15:39:38 +01001926 ALWAYS_INLINE bool NEG_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001927 SetVRegDouble(A(), -GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001928 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001929 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001930 }
1931
David Srbeckybd613ec2019-05-30 15:39:38 +01001932 ALWAYS_INLINE bool INT_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001933 SetVRegLong(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001934 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001935 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001936 }
1937
David Srbeckybd613ec2019-05-30 15:39:38 +01001938 ALWAYS_INLINE bool INT_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001939 SetVRegFloat(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001940 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001941 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001942 }
1943
David Srbeckybd613ec2019-05-30 15:39:38 +01001944 ALWAYS_INLINE bool INT_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001945 SetVRegDouble(A(), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001946 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001947 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001948 }
1949
David Srbeckybd613ec2019-05-30 15:39:38 +01001950 ALWAYS_INLINE bool LONG_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001951 SetVReg(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001952 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001953 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001954 }
1955
David Srbeckybd613ec2019-05-30 15:39:38 +01001956 ALWAYS_INLINE bool LONG_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001957 SetVRegFloat(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001958 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001959 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001960 }
1961
David Srbeckybd613ec2019-05-30 15:39:38 +01001962 ALWAYS_INLINE bool LONG_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001963 SetVRegDouble(A(), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001964 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001965 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001966 }
1967
David Srbeckybd613ec2019-05-30 15:39:38 +01001968 ALWAYS_INLINE bool FLOAT_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001969 float val = GetVRegFloat(B());
David Srbecky6da82472018-10-23 14:03:08 +01001970 int32_t result = art_float_to_integral<int32_t, float>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001971 SetVReg(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001972 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001973 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001974 }
1975
David Srbeckybd613ec2019-05-30 15:39:38 +01001976 ALWAYS_INLINE bool FLOAT_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001977 float val = GetVRegFloat(B());
David Srbecky6da82472018-10-23 14:03:08 +01001978 int64_t result = art_float_to_integral<int64_t, float>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001979 SetVRegLong(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001980 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001981 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001982 }
1983
David Srbeckybd613ec2019-05-30 15:39:38 +01001984 ALWAYS_INLINE bool FLOAT_TO_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001985 SetVRegDouble(A(), GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01001986 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001987 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001988 }
1989
David Srbeckybd613ec2019-05-30 15:39:38 +01001990 ALWAYS_INLINE bool DOUBLE_TO_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001991 double val = GetVRegDouble(B());
David Srbecky6da82472018-10-23 14:03:08 +01001992 int32_t result = art_float_to_integral<int32_t, double>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01001993 SetVReg(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01001994 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01001995 return true;
David Srbecky6da82472018-10-23 14:03:08 +01001996 }
1997
David Srbeckybd613ec2019-05-30 15:39:38 +01001998 ALWAYS_INLINE bool DOUBLE_TO_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01001999 double val = GetVRegDouble(B());
David Srbecky6da82472018-10-23 14:03:08 +01002000 int64_t result = art_float_to_integral<int64_t, double>(val);
David Srbecky6baf6442019-05-30 14:57:43 +01002001 SetVRegLong(A(), result);
David Srbecky6da82472018-10-23 14:03:08 +01002002 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002003 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002004 }
2005
David Srbeckybd613ec2019-05-30 15:39:38 +01002006 ALWAYS_INLINE bool DOUBLE_TO_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002007 SetVRegFloat(A(), GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002008 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002009 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002010 }
2011
David Srbeckybd613ec2019-05-30 15:39:38 +01002012 ALWAYS_INLINE bool INT_TO_BYTE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002013 SetVReg(A(), static_cast<int8_t>(GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002014 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002015 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002016 }
2017
David Srbeckybd613ec2019-05-30 15:39:38 +01002018 ALWAYS_INLINE bool INT_TO_CHAR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002019 SetVReg(A(), static_cast<uint16_t>(GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002020 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002021 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002022 }
2023
David Srbeckybd613ec2019-05-30 15:39:38 +01002024 ALWAYS_INLINE bool INT_TO_SHORT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002025 SetVReg(A(), static_cast<int16_t>(GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002026 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002027 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002028 }
2029
David Srbeckybd613ec2019-05-30 15:39:38 +01002030 ALWAYS_INLINE bool ADD_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002031 SetVReg(A(), SafeAdd(GetVReg(B()), GetVReg(C())));
David Srbecky6da82472018-10-23 14:03:08 +01002032 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002033 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002034 }
2035
David Srbeckybd613ec2019-05-30 15:39:38 +01002036 ALWAYS_INLINE bool SUB_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002037 SetVReg(A(), SafeSub(GetVReg(B()), GetVReg(C())));
David Srbecky6da82472018-10-23 14:03:08 +01002038 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002039 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002040 }
2041
David Srbeckybd613ec2019-05-30 15:39:38 +01002042 ALWAYS_INLINE bool MUL_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002043 SetVReg(A(), SafeMul(GetVReg(B()), GetVReg(C())));
David Srbecky6da82472018-10-23 14:03:08 +01002044 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002045 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002046 }
2047
David Srbeckybd613ec2019-05-30 15:39:38 +01002048 ALWAYS_INLINE bool DIV_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002049 bool success = DoIntDivide(shadow_frame, A(), GetVReg(B()), GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002050 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002051 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002052 }
2053
David Srbeckybd613ec2019-05-30 15:39:38 +01002054 ALWAYS_INLINE bool REM_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002055 bool success = DoIntRemainder(shadow_frame, A(), GetVReg(B()), GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002056 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002057 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002058 }
2059
David Srbeckybd613ec2019-05-30 15:39:38 +01002060 ALWAYS_INLINE bool SHL_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002061 SetVReg(A(), GetVReg(B()) << (GetVReg(C()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002062 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002063 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002064 }
2065
David Srbeckybd613ec2019-05-30 15:39:38 +01002066 ALWAYS_INLINE bool SHR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002067 SetVReg(A(), GetVReg(B()) >> (GetVReg(C()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002068 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002069 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002070 }
2071
David Srbeckybd613ec2019-05-30 15:39:38 +01002072 ALWAYS_INLINE bool USHR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002073 SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (GetVReg(C()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002074 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002075 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002076 }
2077
David Srbeckybd613ec2019-05-30 15:39:38 +01002078 ALWAYS_INLINE bool AND_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002079 SetVReg(A(), GetVReg(B()) & GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002080 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002081 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002082 }
2083
David Srbeckybd613ec2019-05-30 15:39:38 +01002084 ALWAYS_INLINE bool OR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002085 SetVReg(A(), GetVReg(B()) | GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002086 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002087 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002088 }
2089
David Srbeckybd613ec2019-05-30 15:39:38 +01002090 ALWAYS_INLINE bool XOR_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002091 SetVReg(A(), GetVReg(B()) ^ GetVReg(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002092 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002093 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002094 }
2095
David Srbeckybd613ec2019-05-30 15:39:38 +01002096 ALWAYS_INLINE bool ADD_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002097 SetVRegLong(A(), SafeAdd(GetVRegLong(B()), GetVRegLong(C())));
David Srbecky6da82472018-10-23 14:03:08 +01002098 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002099 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002100 }
2101
David Srbeckybd613ec2019-05-30 15:39:38 +01002102 ALWAYS_INLINE bool SUB_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002103 SetVRegLong(A(), SafeSub(GetVRegLong(B()), GetVRegLong(C())));
David Srbecky6da82472018-10-23 14:03:08 +01002104 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002105 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002106 }
2107
David Srbeckybd613ec2019-05-30 15:39:38 +01002108 ALWAYS_INLINE bool MUL_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002109 SetVRegLong(A(), SafeMul(GetVRegLong(B()), GetVRegLong(C())));
David Srbecky6da82472018-10-23 14:03:08 +01002110 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002111 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002112 }
2113
David Srbeckybd613ec2019-05-30 15:39:38 +01002114 ALWAYS_INLINE bool DIV_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002115 DoLongDivide(shadow_frame, A(), GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002116 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002117 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002118 }
2119
David Srbeckybd613ec2019-05-30 15:39:38 +01002120 ALWAYS_INLINE bool REM_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002121 DoLongRemainder(shadow_frame, A(), GetVRegLong(B()), GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002122 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002123 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002124 }
2125
David Srbeckybd613ec2019-05-30 15:39:38 +01002126 ALWAYS_INLINE bool AND_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002127 SetVRegLong(A(), GetVRegLong(B()) & GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002128 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002129 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002130 }
2131
David Srbeckybd613ec2019-05-30 15:39:38 +01002132 ALWAYS_INLINE bool OR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002133 SetVRegLong(A(), GetVRegLong(B()) | GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002134 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002135 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002136 }
2137
David Srbeckybd613ec2019-05-30 15:39:38 +01002138 ALWAYS_INLINE bool XOR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002139 SetVRegLong(A(), GetVRegLong(B()) ^ GetVRegLong(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002140 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002141 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002142 }
2143
David Srbeckybd613ec2019-05-30 15:39:38 +01002144 ALWAYS_INLINE bool SHL_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002145 SetVRegLong(A(), GetVRegLong(B()) << (GetVReg(C()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01002146 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002147 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002148 }
2149
David Srbeckybd613ec2019-05-30 15:39:38 +01002150 ALWAYS_INLINE bool SHR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002151 SetVRegLong(A(), GetVRegLong(B()) >> (GetVReg(C()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01002152 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002153 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002154 }
2155
David Srbeckybd613ec2019-05-30 15:39:38 +01002156 ALWAYS_INLINE bool USHR_LONG() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002157 SetVRegLong(A(), static_cast<uint64_t>(GetVRegLong(B())) >> (GetVReg(C()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01002158 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002159 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002160 }
2161
David Srbeckybd613ec2019-05-30 15:39:38 +01002162 ALWAYS_INLINE bool ADD_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002163 SetVRegFloat(A(), GetVRegFloat(B()) + GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002164 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002165 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002166 }
2167
David Srbeckybd613ec2019-05-30 15:39:38 +01002168 ALWAYS_INLINE bool SUB_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002169 SetVRegFloat(A(), GetVRegFloat(B()) - GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002170 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002171 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002172 }
2173
David Srbeckybd613ec2019-05-30 15:39:38 +01002174 ALWAYS_INLINE bool MUL_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002175 SetVRegFloat(A(), GetVRegFloat(B()) * GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002176 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002177 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002178 }
2179
David Srbeckybd613ec2019-05-30 15:39:38 +01002180 ALWAYS_INLINE bool DIV_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002181 SetVRegFloat(A(), GetVRegFloat(B()) / GetVRegFloat(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002182 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002183 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002184 }
2185
David Srbeckybd613ec2019-05-30 15:39:38 +01002186 ALWAYS_INLINE bool REM_FLOAT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002187 SetVRegFloat(A(), fmodf(GetVRegFloat(B()), GetVRegFloat(C())));
David Srbecky6da82472018-10-23 14:03:08 +01002188 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002189 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002190 }
2191
David Srbeckybd613ec2019-05-30 15:39:38 +01002192 ALWAYS_INLINE bool ADD_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002193 SetVRegDouble(A(), GetVRegDouble(B()) + GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002194 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002195 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002196 }
2197
David Srbeckybd613ec2019-05-30 15:39:38 +01002198 ALWAYS_INLINE bool SUB_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002199 SetVRegDouble(A(), GetVRegDouble(B()) - GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002200 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002201 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002202 }
2203
David Srbeckybd613ec2019-05-30 15:39:38 +01002204 ALWAYS_INLINE bool MUL_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002205 SetVRegDouble(A(), GetVRegDouble(B()) * GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002206 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002207 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002208 }
2209
David Srbeckybd613ec2019-05-30 15:39:38 +01002210 ALWAYS_INLINE bool DIV_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002211 SetVRegDouble(A(), GetVRegDouble(B()) / GetVRegDouble(C()));
David Srbecky6da82472018-10-23 14:03:08 +01002212 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002213 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002214 }
2215
David Srbeckybd613ec2019-05-30 15:39:38 +01002216 ALWAYS_INLINE bool REM_DOUBLE() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002217 SetVRegDouble(A(), fmod(GetVRegDouble(B()), GetVRegDouble(C())));
David Srbecky6da82472018-10-23 14:03:08 +01002218 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002219 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002220 }
2221
David Srbeckybd613ec2019-05-30 15:39:38 +01002222 ALWAYS_INLINE bool ADD_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002223 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002224 SetVReg(vregA, SafeAdd(GetVReg(vregA), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002225 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002226 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002227 }
2228
David Srbeckybd613ec2019-05-30 15:39:38 +01002229 ALWAYS_INLINE bool SUB_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002230 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002231 SetVReg(vregA, SafeSub(GetVReg(vregA), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002232 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002233 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002234 }
2235
David Srbeckybd613ec2019-05-30 15:39:38 +01002236 ALWAYS_INLINE bool MUL_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002237 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002238 SetVReg(vregA, SafeMul(GetVReg(vregA), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002239 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002240 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002241 }
2242
David Srbeckybd613ec2019-05-30 15:39:38 +01002243 ALWAYS_INLINE bool DIV_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002244 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002245 bool success = DoIntDivide(shadow_frame, vregA, GetVReg(vregA), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002246 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002247 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002248 }
2249
David Srbeckybd613ec2019-05-30 15:39:38 +01002250 ALWAYS_INLINE bool REM_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002251 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002252 bool success = DoIntRemainder(shadow_frame, vregA, GetVReg(vregA), GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002253 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002254 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002255 }
2256
David Srbeckybd613ec2019-05-30 15:39:38 +01002257 ALWAYS_INLINE bool SHL_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002258 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002259 SetVReg(vregA, GetVReg(vregA) << (GetVReg(B()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002260 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002261 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002262 }
2263
David Srbeckybd613ec2019-05-30 15:39:38 +01002264 ALWAYS_INLINE bool SHR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002265 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002266 SetVReg(vregA, GetVReg(vregA) >> (GetVReg(B()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002267 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002268 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002269 }
2270
David Srbeckybd613ec2019-05-30 15:39:38 +01002271 ALWAYS_INLINE bool USHR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002272 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002273 SetVReg(vregA, static_cast<uint32_t>(GetVReg(vregA)) >> (GetVReg(B()) & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002274 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002275 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002276 }
2277
David Srbeckybd613ec2019-05-30 15:39:38 +01002278 ALWAYS_INLINE bool AND_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002279 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002280 SetVReg(vregA, GetVReg(vregA) & GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002281 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002282 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002283 }
2284
David Srbeckybd613ec2019-05-30 15:39:38 +01002285 ALWAYS_INLINE bool OR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002286 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002287 SetVReg(vregA, GetVReg(vregA) | GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002288 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002289 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002290 }
2291
David Srbeckybd613ec2019-05-30 15:39:38 +01002292 ALWAYS_INLINE bool XOR_INT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002293 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002294 SetVReg(vregA, GetVReg(vregA) ^ GetVReg(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002295 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002296 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002297 }
2298
David Srbeckybd613ec2019-05-30 15:39:38 +01002299 ALWAYS_INLINE bool ADD_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002300 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002301 SetVRegLong(vregA, SafeAdd(GetVRegLong(vregA), GetVRegLong(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002302 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002303 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002304 }
2305
David Srbeckybd613ec2019-05-30 15:39:38 +01002306 ALWAYS_INLINE bool SUB_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002307 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002308 SetVRegLong(vregA, SafeSub(GetVRegLong(vregA), GetVRegLong(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002309 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002310 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002311 }
2312
David Srbeckybd613ec2019-05-30 15:39:38 +01002313 ALWAYS_INLINE bool MUL_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002314 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002315 SetVRegLong(vregA, SafeMul(GetVRegLong(vregA), GetVRegLong(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002316 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002317 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002318 }
2319
David Srbeckybd613ec2019-05-30 15:39:38 +01002320 ALWAYS_INLINE bool DIV_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002321 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002322 DoLongDivide(shadow_frame, vregA, GetVRegLong(vregA), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002323 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002324 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002325 }
2326
David Srbeckybd613ec2019-05-30 15:39:38 +01002327 ALWAYS_INLINE bool REM_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002328 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002329 DoLongRemainder(shadow_frame, vregA, GetVRegLong(vregA), GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002330 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002331 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002332 }
2333
David Srbeckybd613ec2019-05-30 15:39:38 +01002334 ALWAYS_INLINE bool AND_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002335 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002336 SetVRegLong(vregA, GetVRegLong(vregA) & GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002337 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002338 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002339 }
2340
David Srbeckybd613ec2019-05-30 15:39:38 +01002341 ALWAYS_INLINE bool OR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002342 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002343 SetVRegLong(vregA, GetVRegLong(vregA) | GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002344 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002345 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002346 }
2347
David Srbeckybd613ec2019-05-30 15:39:38 +01002348 ALWAYS_INLINE bool XOR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002349 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002350 SetVRegLong(vregA, GetVRegLong(vregA) ^ GetVRegLong(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002351 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002352 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002353 }
2354
David Srbeckybd613ec2019-05-30 15:39:38 +01002355 ALWAYS_INLINE bool SHL_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002356 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002357 SetVRegLong(vregA, GetVRegLong(vregA) << (GetVReg(B()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01002358 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002359 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002360 }
2361
David Srbeckybd613ec2019-05-30 15:39:38 +01002362 ALWAYS_INLINE bool SHR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002363 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002364 SetVRegLong(vregA, GetVRegLong(vregA) >> (GetVReg(B()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01002365 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002366 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002367 }
2368
David Srbeckybd613ec2019-05-30 15:39:38 +01002369 ALWAYS_INLINE bool USHR_LONG_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002370 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002371 SetVRegLong(vregA, static_cast<uint64_t>(GetVRegLong(vregA)) >> (GetVReg(B()) & 0x3f));
David Srbecky6da82472018-10-23 14:03:08 +01002372 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002373 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002374 }
2375
David Srbeckybd613ec2019-05-30 15:39:38 +01002376 ALWAYS_INLINE bool ADD_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002377 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002378 SetVRegFloat(vregA, GetVRegFloat(vregA) + GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002379 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002380 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002381 }
2382
David Srbeckybd613ec2019-05-30 15:39:38 +01002383 ALWAYS_INLINE bool SUB_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002384 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002385 SetVRegFloat(vregA, GetVRegFloat(vregA) - GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002386 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002387 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002388 }
2389
David Srbeckybd613ec2019-05-30 15:39:38 +01002390 ALWAYS_INLINE bool MUL_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002391 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002392 SetVRegFloat(vregA, GetVRegFloat(vregA) * GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002393 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002394 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002395 }
2396
David Srbeckybd613ec2019-05-30 15:39:38 +01002397 ALWAYS_INLINE bool DIV_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002398 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002399 SetVRegFloat(vregA, GetVRegFloat(vregA) / GetVRegFloat(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002400 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002401 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002402 }
2403
David Srbeckybd613ec2019-05-30 15:39:38 +01002404 ALWAYS_INLINE bool REM_FLOAT_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002405 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002406 SetVRegFloat(vregA, fmodf(GetVRegFloat(vregA), GetVRegFloat(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002407 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002408 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002409 }
2410
David Srbeckybd613ec2019-05-30 15:39:38 +01002411 ALWAYS_INLINE bool ADD_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002412 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002413 SetVRegDouble(vregA, GetVRegDouble(vregA) + GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002414 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002415 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002416 }
2417
David Srbeckybd613ec2019-05-30 15:39:38 +01002418 ALWAYS_INLINE bool SUB_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002419 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002420 SetVRegDouble(vregA, GetVRegDouble(vregA) - GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002421 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002422 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002423 }
2424
David Srbeckybd613ec2019-05-30 15:39:38 +01002425 ALWAYS_INLINE bool MUL_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002426 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002427 SetVRegDouble(vregA, GetVRegDouble(vregA) * GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002428 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002429 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002430 }
2431
David Srbeckybd613ec2019-05-30 15:39:38 +01002432 ALWAYS_INLINE bool DIV_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002433 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002434 SetVRegDouble(vregA, GetVRegDouble(vregA) / GetVRegDouble(B()));
David Srbecky6da82472018-10-23 14:03:08 +01002435 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002436 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002437 }
2438
David Srbeckybd613ec2019-05-30 15:39:38 +01002439 ALWAYS_INLINE bool REM_DOUBLE_2ADDR() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbeckyd6f579c2019-05-29 18:09:30 +01002440 uint4_t vregA = A();
David Srbecky6baf6442019-05-30 14:57:43 +01002441 SetVRegDouble(vregA, fmod(GetVRegDouble(vregA), GetVRegDouble(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002442 inst = inst->Next_1xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002443 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002444 }
2445
David Srbeckybd613ec2019-05-30 15:39:38 +01002446 ALWAYS_INLINE bool ADD_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002447 SetVReg(A(), SafeAdd(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01002448 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002449 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002450 }
2451
David Srbeckybd613ec2019-05-30 15:39:38 +01002452 ALWAYS_INLINE bool RSUB_INT() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002453 SetVReg(A(), SafeSub(C(), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002454 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002455 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002456 }
2457
David Srbeckybd613ec2019-05-30 15:39:38 +01002458 ALWAYS_INLINE bool MUL_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002459 SetVReg(A(), SafeMul(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01002460 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002461 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002462 }
2463
David Srbeckybd613ec2019-05-30 15:39:38 +01002464 ALWAYS_INLINE bool DIV_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002465 bool success = DoIntDivide(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01002466 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002467 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002468 }
2469
David Srbeckybd613ec2019-05-30 15:39:38 +01002470 ALWAYS_INLINE bool REM_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002471 bool success = DoIntRemainder(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01002472 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002473 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002474 }
2475
David Srbeckybd613ec2019-05-30 15:39:38 +01002476 ALWAYS_INLINE bool AND_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002477 SetVReg(A(), GetVReg(B()) & C());
David Srbecky6da82472018-10-23 14:03:08 +01002478 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002479 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002480 }
2481
David Srbeckybd613ec2019-05-30 15:39:38 +01002482 ALWAYS_INLINE bool OR_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002483 SetVReg(A(), GetVReg(B()) | C());
David Srbecky6da82472018-10-23 14:03:08 +01002484 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002485 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002486 }
2487
David Srbeckybd613ec2019-05-30 15:39:38 +01002488 ALWAYS_INLINE bool XOR_INT_LIT16() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002489 SetVReg(A(), GetVReg(B()) ^ C());
David Srbecky6da82472018-10-23 14:03:08 +01002490 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002491 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002492 }
2493
David Srbeckybd613ec2019-05-30 15:39:38 +01002494 ALWAYS_INLINE bool ADD_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002495 SetVReg(A(), SafeAdd(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01002496 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002497 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002498 }
2499
David Srbeckybd613ec2019-05-30 15:39:38 +01002500 ALWAYS_INLINE bool RSUB_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002501 SetVReg(A(), SafeSub(C(), GetVReg(B())));
David Srbecky6da82472018-10-23 14:03:08 +01002502 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002503 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002504 }
2505
David Srbeckybd613ec2019-05-30 15:39:38 +01002506 ALWAYS_INLINE bool MUL_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002507 SetVReg(A(), SafeMul(GetVReg(B()), C()));
David Srbecky6da82472018-10-23 14:03:08 +01002508 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002509 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002510 }
2511
David Srbeckybd613ec2019-05-30 15:39:38 +01002512 ALWAYS_INLINE bool DIV_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002513 bool success = DoIntDivide(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01002514 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002515 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002516 }
2517
David Srbeckybd613ec2019-05-30 15:39:38 +01002518 ALWAYS_INLINE bool REM_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002519 bool success = DoIntRemainder(shadow_frame, A(), GetVReg(B()), C());
David Srbecky6da82472018-10-23 14:03:08 +01002520 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx);
David Srbeckybd613ec2019-05-30 15:39:38 +01002521 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002522 }
2523
David Srbeckybd613ec2019-05-30 15:39:38 +01002524 ALWAYS_INLINE bool AND_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002525 SetVReg(A(), GetVReg(B()) & C());
David Srbecky6da82472018-10-23 14:03:08 +01002526 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002527 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002528 }
2529
David Srbeckybd613ec2019-05-30 15:39:38 +01002530 ALWAYS_INLINE bool OR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002531 SetVReg(A(), GetVReg(B()) | C());
David Srbecky6da82472018-10-23 14:03:08 +01002532 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002533 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002534 }
2535
David Srbeckybd613ec2019-05-30 15:39:38 +01002536 ALWAYS_INLINE bool XOR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002537 SetVReg(A(), GetVReg(B()) ^ C());
David Srbecky6da82472018-10-23 14:03:08 +01002538 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002539 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002540 }
2541
David Srbeckybd613ec2019-05-30 15:39:38 +01002542 ALWAYS_INLINE bool SHL_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002543 SetVReg(A(), GetVReg(B()) << (C() & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002544 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002545 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002546 }
2547
David Srbeckybd613ec2019-05-30 15:39:38 +01002548 ALWAYS_INLINE bool SHR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002549 SetVReg(A(), GetVReg(B()) >> (C() & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002550 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002551 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002552 }
2553
David Srbeckybd613ec2019-05-30 15:39:38 +01002554 ALWAYS_INLINE bool USHR_INT_LIT8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6baf6442019-05-30 14:57:43 +01002555 SetVReg(A(), static_cast<uint32_t>(GetVReg(B())) >> (C() & 0x1f));
David Srbecky6da82472018-10-23 14:03:08 +01002556 inst = inst->Next_2xx();
David Srbeckybd613ec2019-05-30 15:39:38 +01002557 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002558 }
2559
David Srbeckybd613ec2019-05-30 15:39:38 +01002560 ALWAYS_INLINE bool UNUSED_3E() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002561 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002562 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002563 }
2564
David Srbeckybd613ec2019-05-30 15:39:38 +01002565 ALWAYS_INLINE bool UNUSED_3F() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002566 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002567 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002568 }
2569
David Srbeckybd613ec2019-05-30 15:39:38 +01002570 ALWAYS_INLINE bool UNUSED_40() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002571 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002572 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002573 }
2574
David Srbeckybd613ec2019-05-30 15:39:38 +01002575 ALWAYS_INLINE bool UNUSED_41() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002576 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002577 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002578 }
2579
David Srbeckybd613ec2019-05-30 15:39:38 +01002580 ALWAYS_INLINE bool UNUSED_42() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002581 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002582 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002583 }
2584
David Srbeckybd613ec2019-05-30 15:39:38 +01002585 ALWAYS_INLINE bool UNUSED_43() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002586 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002587 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002588 }
2589
David Srbeckybd613ec2019-05-30 15:39:38 +01002590 ALWAYS_INLINE bool UNUSED_79() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002591 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002592 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002593 }
2594
David Srbeckybd613ec2019-05-30 15:39:38 +01002595 ALWAYS_INLINE bool UNUSED_7A() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002596 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002597 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002598 }
2599
David Srbeckybd613ec2019-05-30 15:39:38 +01002600 ALWAYS_INLINE bool UNUSED_F3() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002601 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002602 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002603 }
2604
David Srbeckybd613ec2019-05-30 15:39:38 +01002605 ALWAYS_INLINE bool UNUSED_F4() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002606 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002607 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002608 }
2609
David Srbeckybd613ec2019-05-30 15:39:38 +01002610 ALWAYS_INLINE bool UNUSED_F5() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002611 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002612 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002613 }
2614
David Srbeckybd613ec2019-05-30 15:39:38 +01002615 ALWAYS_INLINE bool UNUSED_F6() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002616 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002617 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002618 }
2619
David Srbeckybd613ec2019-05-30 15:39:38 +01002620 ALWAYS_INLINE bool UNUSED_F7() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002621 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002622 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002623 }
2624
David Srbeckybd613ec2019-05-30 15:39:38 +01002625 ALWAYS_INLINE bool UNUSED_F8() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002626 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002627 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002628 }
2629
David Srbeckybd613ec2019-05-30 15:39:38 +01002630 ALWAYS_INLINE bool UNUSED_F9() REQUIRES_SHARED(Locks::mutator_lock_) {
David Srbecky6da82472018-10-23 14:03:08 +01002631 UnexpectedOpcode(inst, shadow_frame);
David Srbeckybd613ec2019-05-30 15:39:38 +01002632 return true;
David Srbecky6da82472018-10-23 14:03:08 +01002633 }
2634
2635 ALWAYS_INLINE InstructionHandler(SwitchImplContext* ctx,
2636 const instrumentation::Instrumentation* instrumentation,
2637 Thread* self,
2638 ShadowFrame& shadow_frame,
2639 uint16_t dex_pc,
2640 const Instruction*& inst,
2641 uint16_t inst_data,
2642 bool& exit_interpreter_loop)
2643 : ctx(ctx),
2644 instrumentation(instrumentation),
2645 self(self),
2646 shadow_frame(shadow_frame),
2647 dex_pc(dex_pc),
2648 inst(inst),
2649 inst_data(inst_data),
2650 exit_interpreter_loop(exit_interpreter_loop) {
2651 }
2652
2653 private:
2654 static constexpr bool do_assignability_check = do_access_check;
2655
2656 const CodeItemDataAccessor& Accessor() { return ctx->accessor; }
2657 const uint16_t* Insns() { return ctx->accessor.Insns(); }
2658 JValue* ResultRegister() { return &ctx->result_register; }
2659
David Srbecky436f6c12019-05-22 13:28:42 +01002660 ALWAYS_INLINE int32_t A() { return inst->VRegA(kFormat, inst_data); }
2661 ALWAYS_INLINE int32_t B() { return inst->VRegB(kFormat, inst_data); }
2662 ALWAYS_INLINE int32_t C() { return inst->VRegC(kFormat); }
2663
David Srbecky6baf6442019-05-30 14:57:43 +01002664 int32_t GetVReg(size_t i) const { return shadow_frame.GetVReg(i); }
2665 int64_t GetVRegLong(size_t i) const { return shadow_frame.GetVRegLong(i); }
2666 float GetVRegFloat(size_t i) const { return shadow_frame.GetVRegFloat(i); }
2667 double GetVRegDouble(size_t i) const { return shadow_frame.GetVRegDouble(i); }
2668 ObjPtr<mirror::Object> GetVRegReference(size_t i) const REQUIRES_SHARED(Locks::mutator_lock_) {
2669 return shadow_frame.GetVRegReference(i);
2670 }
2671
2672 void SetVReg(size_t i, int32_t val) { shadow_frame.SetVReg(i, val); }
2673 void SetVRegLong(size_t i, int64_t val) { shadow_frame.SetVRegLong(i, val); }
2674 void SetVRegFloat(size_t i, float val) { shadow_frame.SetVRegFloat(i, val); }
2675 void SetVRegDouble(size_t i, double val) { shadow_frame.SetVRegDouble(i, val); }
2676 void SetVRegReference(size_t i, ObjPtr<mirror::Object> val)
2677 REQUIRES_SHARED(Locks::mutator_lock_) {
2678 shadow_frame.SetVRegReference(i, val);
2679 }
2680
David Srbecky6da82472018-10-23 14:03:08 +01002681 SwitchImplContext* const ctx;
2682 const instrumentation::Instrumentation* const instrumentation;
2683 Thread* const self;
2684 ShadowFrame& shadow_frame;
2685 uint32_t const dex_pc;
2686 const Instruction*& inst;
2687 uint16_t const inst_data;
2688 bool& exit_interpreter_loop;
2689};
2690
David Srbecky6da82472018-10-23 14:03:08 +01002691#undef BRANCH_INSTRUMENTATION
David Srbecky6da82472018-10-23 14:03:08 +01002692#undef POSSIBLY_HANDLE_PENDING_EXCEPTION
2693#undef POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE
2694#undef POSSIBLY_HANDLE_PENDING_EXCEPTION_ON_INVOKE_POLYMORPHIC
David Srbecky6da82472018-10-23 14:03:08 +01002695#undef HANDLE_PENDING_EXCEPTION
David Srbecky6da82472018-10-23 14:03:08 +01002696
Alex Light6f22e062018-10-05 15:05:12 -07002697// TODO On ASAN builds this function gets a huge stack frame. Since normally we run in the mterp
2698// this shouldn't cause any problems for stack overflow detection. Remove this once b/117341496 is
2699// fixed.
Sebastien Hertzd2fe10a2014-01-15 10:20:56 +01002700template<bool do_access_check, bool transaction_active>
Alex Light6f22e062018-10-05 15:05:12 -07002701ATTRIBUTE_NO_SANITIZE_ADDRESS void ExecuteSwitchImplCpp(SwitchImplContext* ctx) {
David Srbecky946bb092018-03-09 17:23:01 +00002702 Thread* self = ctx->self;
2703 const CodeItemDataAccessor& accessor = ctx->accessor;
2704 ShadowFrame& shadow_frame = ctx->shadow_frame;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002705 if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
2706 LOG(FATAL) << "Invalid shadow frame for interpreter use";
David Srbecky946bb092018-03-09 17:23:01 +00002707 ctx->result = JValue();
2708 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002709 }
2710 self->VerifyStack();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002711
2712 uint32_t dex_pc = shadow_frame.GetDexPC();
Mathieu Chartier2cebb242015-04-21 16:50:40 -07002713 const auto* const instrumentation = Runtime::Current()->GetInstrumentation();
Mathieu Chartier808c7a52017-12-15 11:19:33 -08002714 const uint16_t* const insns = accessor.Insns();
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002715 const Instruction* inst = Instruction::At(insns + dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002716 uint16_t inst_data;
Igor Murashkin6918bf12015-09-27 19:19:06 -07002717
Alex Light0aa7a5a2018-10-10 15:58:14 +00002718 DCHECK(!shadow_frame.GetForceRetryInstruction())
2719 << "Entered interpreter from invoke without retry instruction being handled!";
2720
David Srbecky6da82472018-10-23 14:03:08 +01002721 bool const interpret_one_instruction = ctx->interpret_one_instruction;
2722 while (true) {
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002723 dex_pc = inst->GetDexPc(insns);
2724 shadow_frame.SetDexPC(dex_pc);
Ian Rogerse94652f2014-12-02 11:13:19 -08002725 TraceExecution(shadow_frame, inst, dex_pc);
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002726 inst_data = inst->Fetch16(0);
David Srbeckya4a96af2018-10-31 16:34:58 +00002727 {
2728 bool exit_loop = false;
David Srbecky436f6c12019-05-22 13:28:42 +01002729 InstructionHandler<do_access_check, transaction_active, Instruction::kInvalidFormat> handler(
David Srbeckya4a96af2018-10-31 16:34:58 +00002730 ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, exit_loop);
2731 if (!handler.Preamble()) {
2732 if (UNLIKELY(exit_loop)) {
2733 return;
2734 }
2735 if (UNLIKELY(interpret_one_instruction)) {
2736 break;
2737 }
2738 continue;
2739 }
2740 }
Sebastien Hertz3b588e02013-09-11 14:33:18 +02002741 switch (inst->Opcode(inst_data)) {
David Srbecky436f6c12019-05-22 13:28:42 +01002742#define OPCODE_CASE(OPCODE, OPCODE_NAME, pname, FORMAT, i, a, e, v) \
David Srbecky6da82472018-10-23 14:03:08 +01002743 case OPCODE: { \
2744 bool exit_loop = false; \
David Srbecky436f6c12019-05-22 13:28:42 +01002745 InstructionHandler<do_access_check, transaction_active, Instruction::FORMAT> handler( \
David Srbecky6da82472018-10-23 14:03:08 +01002746 ctx, instrumentation, self, shadow_frame, dex_pc, inst, inst_data, exit_loop); \
David Srbeckya4a96af2018-10-31 16:34:58 +00002747 handler.OPCODE_NAME(); \
David Srbecky6da82472018-10-23 14:03:08 +01002748 /* TODO: Advance 'inst' here, instead of explicitly in each handler */ \
2749 if (UNLIKELY(exit_loop)) { \
2750 return; \
2751 } \
2752 break; \
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002753 }
David Srbecky6da82472018-10-23 14:03:08 +01002754DEX_INSTRUCTION_LIST(OPCODE_CASE)
2755#undef OPCODE_CASE
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002756 }
David Srbecky6da82472018-10-23 14:03:08 +01002757 if (UNLIKELY(interpret_one_instruction)) {
David Srbeckya4a96af2018-10-31 16:34:58 +00002758 break;
David Srbecky6da82472018-10-23 14:03:08 +01002759 }
2760 }
David Srbeckya4a96af2018-10-31 16:34:58 +00002761 // Record where we stopped.
2762 shadow_frame.SetDexPC(inst->GetDexPc(insns));
2763 ctx->result = ctx->result_register;
2764 return;
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002765} // NOLINT(readability/fn_size)
2766
Sebastien Hertz8ece0502013-08-07 11:26:41 +02002767} // namespace interpreter
2768} // namespace art
David Srbecky2ee09ff2018-10-24 13:24:22 +01002769
2770#endif // ART_RUNTIME_INTERPRETER_INTERPRETER_SWITCH_IMPL_INL_H_