interpreter.cc revision 848871b4d8481229c32e0d048a9856e5a9a17ef9
1/* 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 17#include "interpreter.h" 18 19#include <math.h> 20 21#include "base/logging.h" 22#include "class_linker-inl.h" 23#include "common_throws.h" 24#include "dex_file-inl.h" 25#include "dex_instruction-inl.h" 26#include "dex_instruction.h" 27#include "entrypoints/entrypoint_utils.h" 28#include "gc/accounting/card_table-inl.h" 29#include "invoke_arg_array_builder.h" 30#include "nth_caller_visitor.h" 31#include "mirror/class.h" 32#include "mirror/class-inl.h" 33#include "mirror/field-inl.h" 34#include "mirror/abstract_method.h" 35#include "mirror/abstract_method-inl.h" 36#include "mirror/object-inl.h" 37#include "mirror/object_array-inl.h" 38#include "object_utils.h" 39#include "ScopedLocalRef.h" 40#include "scoped_thread_state_change.h" 41#include "thread.h" 42 43using ::art::mirror::AbstractMethod; 44using ::art::mirror::Array; 45using ::art::mirror::BooleanArray; 46using ::art::mirror::ByteArray; 47using ::art::mirror::CharArray; 48using ::art::mirror::Class; 49using ::art::mirror::ClassLoader; 50using ::art::mirror::Field; 51using ::art::mirror::IntArray; 52using ::art::mirror::LongArray; 53using ::art::mirror::Object; 54using ::art::mirror::ObjectArray; 55using ::art::mirror::ShortArray; 56using ::art::mirror::String; 57using ::art::mirror::Throwable; 58 59namespace art { 60 61namespace interpreter { 62 63static const int32_t kMaxInt = std::numeric_limits<int32_t>::max(); 64static const int32_t kMinInt = std::numeric_limits<int32_t>::min(); 65static const int64_t kMaxLong = std::numeric_limits<int64_t>::max(); 66static const int64_t kMinLong = std::numeric_limits<int64_t>::min(); 67 68static void UnstartedRuntimeInvoke(Thread* self, MethodHelper& mh, 69 const DexFile::CodeItem* code_item, ShadowFrame* shadow_frame, 70 JValue* result, size_t arg_offset) 71 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 72 // In a runtime that's not started we intercept certain methods to avoid complicated dependency 73 // problems in core libraries. 74 std::string name(PrettyMethod(shadow_frame->GetMethod())); 75 if (name == "java.lang.Class java.lang.Class.forName(java.lang.String)") { 76 std::string descriptor(DotToDescriptor(shadow_frame->GetVRegReference(arg_offset)->AsString()->ToModifiedUtf8().c_str())); 77 ClassLoader* class_loader = NULL; // shadow_frame.GetMethod()->GetDeclaringClass()->GetClassLoader(); 78 Class* found = Runtime::Current()->GetClassLinker()->FindClass(descriptor.c_str(), 79 class_loader); 80 CHECK(found != NULL) << "Class.forName failed in un-started runtime for class: " 81 << PrettyDescriptor(descriptor); 82 result->SetL(found); 83 } else if (name == "java.lang.Object java.lang.Class.newInstance()") { 84 Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass(); 85 AbstractMethod* c = klass->FindDeclaredDirectMethod("<init>", "()V"); 86 CHECK(c != NULL); 87 Object* obj = klass->AllocObject(self); 88 CHECK(obj != NULL); 89 EnterInterpreterFromInvoke(self, c, obj, NULL, NULL); 90 result->SetL(obj); 91 } else if (name == "java.lang.reflect.Field java.lang.Class.getDeclaredField(java.lang.String)") { 92 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail 93 // going the reflective Dex way. 94 Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass(); 95 String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString(); 96 Field* found = NULL; 97 FieldHelper fh; 98 ObjectArray<Field>* fields = klass->GetIFields(); 99 for (int32_t i = 0; i < fields->GetLength() && found == NULL; ++i) { 100 Field* f = fields->Get(i); 101 fh.ChangeField(f); 102 if (name->Equals(fh.GetName())) { 103 found = f; 104 } 105 } 106 if (found == NULL) { 107 fields = klass->GetSFields(); 108 for (int32_t i = 0; i < fields->GetLength() && found == NULL; ++i) { 109 Field* f = fields->Get(i); 110 fh.ChangeField(f); 111 if (name->Equals(fh.GetName())) { 112 found = f; 113 } 114 } 115 } 116 CHECK(found != NULL) 117 << "Failed to find field in Class.getDeclaredField in un-started runtime. name=" 118 << name->ToModifiedUtf8() << " class=" << PrettyDescriptor(klass); 119 // TODO: getDeclaredField calls GetType once the field is found to ensure a 120 // NoClassDefFoundError is thrown if the field's type cannot be resolved. 121 result->SetL(found); 122 } else if (name == "void java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int)") { 123 // Special case array copying without initializing System. 124 Class* ctype = shadow_frame->GetVRegReference(arg_offset)->GetClass()->GetComponentType(); 125 jint srcPos = shadow_frame->GetVReg(arg_offset + 1); 126 jint dstPos = shadow_frame->GetVReg(arg_offset + 3); 127 jint length = shadow_frame->GetVReg(arg_offset + 4); 128 if (!ctype->IsPrimitive()) { 129 ObjectArray<Object>* src = shadow_frame->GetVRegReference(arg_offset)->AsObjectArray<Object>(); 130 ObjectArray<Object>* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<Object>(); 131 for (jint i = 0; i < length; ++i) { 132 dst->Set(dstPos + i, src->Get(srcPos + i)); 133 } 134 } else if (ctype->IsPrimitiveChar()) { 135 CharArray* src = shadow_frame->GetVRegReference(arg_offset)->AsCharArray(); 136 CharArray* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray(); 137 for (jint i = 0; i < length; ++i) { 138 dst->Set(dstPos + i, src->Get(srcPos + i)); 139 } 140 } else if (ctype->IsPrimitiveInt()) { 141 IntArray* src = shadow_frame->GetVRegReference(arg_offset)->AsIntArray(); 142 IntArray* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsIntArray(); 143 for (jint i = 0; i < length; ++i) { 144 dst->Set(dstPos + i, src->Get(srcPos + i)); 145 } 146 } else { 147 UNIMPLEMENTED(FATAL) << "System.arraycopy of unexpected type: " << PrettyDescriptor(ctype); 148 } 149 } else { 150 // Not special, continue with regular interpreter execution. 151 artInterpreterToInterpreterBridge(self, mh, code_item, shadow_frame, result); 152 } 153} 154 155// Hand select a number of methods to be run in a not yet started runtime without using JNI. 156static void UnstartedRuntimeJni(Thread* self, AbstractMethod* method, 157 Object* receiver, uint32_t* args, JValue* result) 158 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 159 std::string name(PrettyMethod(method)); 160 if (name == "java.lang.ClassLoader dalvik.system.VMStack.getCallingClassLoader()") { 161 result->SetL(NULL); 162 } else if (name == "java.lang.Class dalvik.system.VMStack.getStackClass2()") { 163 NthCallerVisitor visitor(self, 3); 164 visitor.WalkStack(); 165 result->SetL(visitor.caller->GetDeclaringClass()); 166 } else if (name == "double java.lang.Math.log(double)") { 167 JValue value; 168 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]); 169 result->SetD(log(value.GetD())); 170 } else if (name == "java.lang.String java.lang.Class.getNameNative()") { 171 result->SetL(receiver->AsClass()->ComputeName()); 172 } else if (name == "int java.lang.Float.floatToRawIntBits(float)") { 173 result->SetI(args[0]); 174 } else if (name == "float java.lang.Float.intBitsToFloat(int)") { 175 result->SetI(args[0]); 176 } else if (name == "double java.lang.Math.exp(double)") { 177 JValue value; 178 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]); 179 result->SetD(exp(value.GetD())); 180 } else if (name == "java.lang.Object java.lang.Object.internalClone()") { 181 result->SetL(receiver->Clone(self)); 182 } else if (name == "void java.lang.Object.notifyAll()") { 183 receiver->NotifyAll(self); 184 } else if (name == "int java.lang.String.compareTo(java.lang.String)") { 185 String* rhs = reinterpret_cast<Object*>(args[0])->AsString(); 186 CHECK(rhs != NULL); 187 result->SetI(receiver->AsString()->CompareTo(rhs)); 188 } else if (name == "java.lang.String java.lang.String.intern()") { 189 result->SetL(receiver->AsString()->Intern()); 190 } else if (name == "int java.lang.String.fastIndexOf(int, int)") { 191 result->SetI(receiver->AsString()->FastIndexOf(args[0], args[1])); 192 } else if (name == "java.lang.Object java.lang.reflect.Array.createMultiArray(java.lang.Class, int[])") { 193 result->SetL(Array::CreateMultiArray(self, reinterpret_cast<Object*>(args[0])->AsClass(), reinterpret_cast<Object*>(args[1])->AsIntArray())); 194 } else if (name == "java.lang.Object java.lang.Throwable.nativeFillInStackTrace()") { 195 ScopedObjectAccessUnchecked soa(self); 196 result->SetL(soa.Decode<Object*>(self->CreateInternalStackTrace(soa))); 197 } else if (name == "boolean java.nio.ByteOrder.isLittleEndian()") { 198 result->SetJ(JNI_TRUE); 199 } else if (name == "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)") { 200 Object* obj = reinterpret_cast<Object*>(args[0]); 201 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1]; 202 jint expectedValue = args[3]; 203 jint newValue = args[4]; 204 byte* raw_addr = reinterpret_cast<byte*>(obj) + offset; 205 volatile int32_t* address = reinterpret_cast<volatile int32_t*>(raw_addr); 206 // Note: android_atomic_release_cas() returns 0 on success, not failure. 207 int r = android_atomic_release_cas(expectedValue, newValue, address); 208 result->SetZ(r == 0); 209 } else if (name == "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)") { 210 Object* obj = reinterpret_cast<Object*>(args[0]); 211 Object* newValue = reinterpret_cast<Object*>(args[3]); 212 obj->SetFieldObject(MemberOffset((static_cast<uint64_t>(args[2]) << 32) | args[1]), newValue, false); 213 } else { 214 LOG(FATAL) << "Attempt to invoke native method in non-started runtime: " << name; 215 } 216} 217 218static void InterpreterJni(Thread* self, AbstractMethod* method, StringPiece shorty, 219 Object* receiver, uint32_t* args, JValue* result) 220 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 221 // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler, 222 // it should be removed and JNI compiled stubs used instead. 223 ScopedObjectAccessUnchecked soa(self); 224 if (method->IsStatic()) { 225 if (shorty == "L") { 226 typedef jobject (fnptr)(JNIEnv*, jclass); 227 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 228 ScopedLocalRef<jclass> klass(soa.Env(), 229 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 230 jobject jresult; 231 { 232 ScopedThreadStateChange tsc(self, kNative); 233 jresult = fn(soa.Env(), klass.get()); 234 } 235 result->SetL(soa.Decode<Object*>(jresult)); 236 } else if (shorty == "V") { 237 typedef void (fnptr)(JNIEnv*, jclass); 238 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 239 ScopedLocalRef<jclass> klass(soa.Env(), 240 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 241 ScopedThreadStateChange tsc(self, kNative); 242 fn(soa.Env(), klass.get()); 243 } else if (shorty == "Z") { 244 typedef jboolean (fnptr)(JNIEnv*, jclass); 245 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 246 ScopedLocalRef<jclass> klass(soa.Env(), 247 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 248 ScopedThreadStateChange tsc(self, kNative); 249 result->SetZ(fn(soa.Env(), klass.get())); 250 } else if (shorty == "BI") { 251 typedef jbyte (fnptr)(JNIEnv*, jclass, jint); 252 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 253 ScopedLocalRef<jclass> klass(soa.Env(), 254 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 255 ScopedThreadStateChange tsc(self, kNative); 256 result->SetB(fn(soa.Env(), klass.get(), args[0])); 257 } else if (shorty == "II") { 258 typedef jint (fnptr)(JNIEnv*, jclass, jint); 259 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 260 ScopedLocalRef<jclass> klass(soa.Env(), 261 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 262 ScopedThreadStateChange tsc(self, kNative); 263 result->SetI(fn(soa.Env(), klass.get(), args[0])); 264 } else if (shorty == "LL") { 265 typedef jobject (fnptr)(JNIEnv*, jclass, jobject); 266 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 267 ScopedLocalRef<jclass> klass(soa.Env(), 268 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 269 ScopedLocalRef<jobject> arg0(soa.Env(), 270 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 271 jobject jresult; 272 { 273 ScopedThreadStateChange tsc(self, kNative); 274 jresult = fn(soa.Env(), klass.get(), arg0.get()); 275 } 276 result->SetL(soa.Decode<Object*>(jresult)); 277 } else if (shorty == "IIZ") { 278 typedef jint (fnptr)(JNIEnv*, jclass, jint, jboolean); 279 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 280 ScopedLocalRef<jclass> klass(soa.Env(), 281 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 282 ScopedThreadStateChange tsc(self, kNative); 283 result->SetI(fn(soa.Env(), klass.get(), args[0], args[1])); 284 } else if (shorty == "ILI") { 285 typedef jint (fnptr)(JNIEnv*, jclass, jobject, jint); 286 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 287 ScopedLocalRef<jclass> klass(soa.Env(), 288 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 289 ScopedLocalRef<jobject> arg0(soa.Env(), 290 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 291 ScopedThreadStateChange tsc(self, kNative); 292 result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1])); 293 } else if (shorty == "SIZ") { 294 typedef jshort (fnptr)(JNIEnv*, jclass, jint, jboolean); 295 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 296 ScopedLocalRef<jclass> klass(soa.Env(), 297 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 298 ScopedThreadStateChange tsc(self, kNative); 299 result->SetS(fn(soa.Env(), klass.get(), args[0], args[1])); 300 } else if (shorty == "VIZ") { 301 typedef void (fnptr)(JNIEnv*, jclass, jint, jboolean); 302 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 303 ScopedLocalRef<jclass> klass(soa.Env(), 304 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 305 ScopedThreadStateChange tsc(self, kNative); 306 fn(soa.Env(), klass.get(), args[0], args[1]); 307 } else if (shorty == "ZLL") { 308 typedef jboolean (fnptr)(JNIEnv*, jclass, jobject, jobject); 309 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 310 ScopedLocalRef<jclass> klass(soa.Env(), 311 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 312 ScopedLocalRef<jobject> arg0(soa.Env(), 313 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 314 ScopedLocalRef<jobject> arg1(soa.Env(), 315 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 316 ScopedThreadStateChange tsc(self, kNative); 317 result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get())); 318 } else if (shorty == "ZILL") { 319 typedef jboolean (fnptr)(JNIEnv*, jclass, jint, jobject, jobject); 320 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 321 ScopedLocalRef<jclass> klass(soa.Env(), 322 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 323 ScopedLocalRef<jobject> arg1(soa.Env(), 324 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 325 ScopedLocalRef<jobject> arg2(soa.Env(), 326 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[2]))); 327 ScopedThreadStateChange tsc(self, kNative); 328 result->SetZ(fn(soa.Env(), klass.get(), args[0], arg1.get(), arg2.get())); 329 } else if (shorty == "VILII") { 330 typedef void (fnptr)(JNIEnv*, jclass, jint, jobject, jint, jint); 331 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 332 ScopedLocalRef<jclass> klass(soa.Env(), 333 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 334 ScopedLocalRef<jobject> arg1(soa.Env(), 335 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 336 ScopedThreadStateChange tsc(self, kNative); 337 fn(soa.Env(), klass.get(), args[0], arg1.get(), args[2], args[3]); 338 } else if (shorty == "VLILII") { 339 typedef void (fnptr)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint); 340 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 341 ScopedLocalRef<jclass> klass(soa.Env(), 342 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 343 ScopedLocalRef<jobject> arg0(soa.Env(), 344 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 345 ScopedLocalRef<jobject> arg2(soa.Env(), 346 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[2]))); 347 ScopedThreadStateChange tsc(self, kNative); 348 fn(soa.Env(), klass.get(), arg0.get(), args[1], arg2.get(), args[3], args[4]); 349 } else { 350 LOG(FATAL) << "Do something with static native method: " << PrettyMethod(method) 351 << " shorty: " << shorty; 352 } 353 } else { 354 if (shorty == "L") { 355 typedef jobject (fnptr)(JNIEnv*, jobject); 356 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 357 ScopedLocalRef<jobject> rcvr(soa.Env(), 358 soa.AddLocalReference<jobject>(receiver)); 359 jobject jresult; 360 { 361 ScopedThreadStateChange tsc(self, kNative); 362 jresult = fn(soa.Env(), rcvr.get()); 363 } 364 result->SetL(soa.Decode<Object*>(jresult)); 365 } else if (shorty == "V") { 366 typedef void (fnptr)(JNIEnv*, jobject); 367 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 368 ScopedLocalRef<jobject> rcvr(soa.Env(), 369 soa.AddLocalReference<jobject>(receiver)); 370 ScopedThreadStateChange tsc(self, kNative); 371 fn(soa.Env(), rcvr.get()); 372 } else if (shorty == "LL") { 373 typedef jobject (fnptr)(JNIEnv*, jobject, jobject); 374 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 375 ScopedLocalRef<jobject> rcvr(soa.Env(), 376 soa.AddLocalReference<jobject>(receiver)); 377 ScopedLocalRef<jobject> arg0(soa.Env(), 378 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 379 jobject jresult; 380 { 381 ScopedThreadStateChange tsc(self, kNative); 382 jresult = fn(soa.Env(), rcvr.get(), arg0.get()); 383 } 384 result->SetL(soa.Decode<Object*>(jresult)); 385 ScopedThreadStateChange tsc(self, kNative); 386 } else if (shorty == "III") { 387 typedef jint (fnptr)(JNIEnv*, jobject, jint, jint); 388 const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 389 ScopedLocalRef<jobject> rcvr(soa.Env(), 390 soa.AddLocalReference<jobject>(receiver)); 391 ScopedThreadStateChange tsc(self, kNative); 392 result->SetI(fn(soa.Env(), rcvr.get(), args[0], args[1])); 393 } else { 394 LOG(FATAL) << "Do something with native method: " << PrettyMethod(method) 395 << " shorty: " << shorty; 396 } 397 } 398} 399 400static void DoMonitorEnter(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS { 401 ref->MonitorEnter(self); 402} 403 404static void DoMonitorExit(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS { 405 ref->MonitorExit(self); 406} 407 408// TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template 409// specialization. 410template<InvokeType type, bool is_range, bool do_access_check> 411static bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, 412 const Instruction* inst, JValue* result) NO_THREAD_SAFETY_ANALYSIS; 413 414template<InvokeType type, bool is_range, bool do_access_check> 415static bool DoInvoke(Thread* self, ShadowFrame& shadow_frame, 416 const Instruction* inst, JValue* result) { 417 uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); 418 uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c(); 419 Object* receiver = (type == kStatic) ? NULL : shadow_frame.GetVRegReference(vregC); 420 AbstractMethod* method = FindMethodFromCode(method_idx, receiver, shadow_frame.GetMethod(), self, 421 do_access_check, type); 422 if (UNLIKELY(method == NULL)) { 423 CHECK(self->IsExceptionPending()); 424 result->SetJ(0); 425 return false; 426 } else if (UNLIKELY(method->IsAbstract())) { 427 ThrowAbstractMethodError(method); 428 result->SetJ(0); 429 return false; 430 } 431 432 MethodHelper mh(method); 433 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 434 uint16_t num_regs; 435 uint16_t num_ins; 436 if (LIKELY(code_item != NULL)) { 437 num_regs = code_item->registers_size_; 438 num_ins = code_item->ins_size_; 439 } else { 440 DCHECK(method->IsNative() || method->IsProxyMethod()); 441 num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty()); 442 if (!method->IsStatic()) { 443 num_regs++; 444 num_ins++; 445 } 446 } 447 448 void* memory = alloca(ShadowFrame::ComputeSize(num_regs)); 449 ShadowFrame* new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame, method, 0, memory)); 450 size_t cur_reg = num_regs - num_ins; 451 if (receiver != NULL) { 452 new_shadow_frame->SetVRegReference(cur_reg, receiver); 453 ++cur_reg; 454 } 455 456 size_t arg_offset = (receiver == NULL) ? 0 : 1; 457 const char* shorty = mh.GetShorty(); 458 uint32_t arg[5]; 459 if (!is_range) { 460 inst->GetArgs(arg); 461 } 462 for (size_t shorty_pos = 0; cur_reg < num_regs; ++shorty_pos, cur_reg++, arg_offset++) { 463 DCHECK_LT(shorty_pos + 1, mh.GetShortyLength()); 464 size_t arg_pos = is_range ? vregC + arg_offset : arg[arg_offset]; 465 switch (shorty[shorty_pos + 1]) { 466 case 'L': { 467 Object* o = shadow_frame.GetVRegReference(arg_pos); 468 new_shadow_frame->SetVRegReference(cur_reg, o); 469 break; 470 } 471 case 'J': case 'D': { 472 uint64_t wide_value = (static_cast<uint64_t>(shadow_frame.GetVReg(arg_pos + 1)) << 32) | 473 static_cast<uint32_t>(shadow_frame.GetVReg(arg_pos)); 474 new_shadow_frame->SetVRegLong(cur_reg, wide_value); 475 cur_reg++; 476 arg_offset++; 477 break; 478 } 479 default: 480 new_shadow_frame->SetVReg(cur_reg, shadow_frame.GetVReg(arg_pos)); 481 break; 482 } 483 } 484 485 if (LIKELY(Runtime::Current()->IsStarted())) { 486 (method->GetEntryPointFromInterpreter())(self, mh, code_item, new_shadow_frame, result); 487 } else { 488 UnstartedRuntimeInvoke(self, mh, code_item, new_shadow_frame, result, num_regs - num_ins); 489 } 490 return !self->IsExceptionPending(); 491} 492 493// TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template 494// specialization. 495template<bool is_range> 496static bool DoInvokeVirtualQuick(Thread* self, ShadowFrame& shadow_frame, 497 const Instruction* inst, JValue* result) 498 NO_THREAD_SAFETY_ANALYSIS; 499 500template<bool is_range> 501static bool DoInvokeVirtualQuick(Thread* self, ShadowFrame& shadow_frame, 502 const Instruction* inst, JValue* result) { 503 uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c(); 504 Object* receiver = shadow_frame.GetVRegReference(vregC); 505 if (UNLIKELY(receiver == NULL)) { 506 // We lost the reference to the method index so we cannot get a more 507 // precised exception message. 508 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 509 return false; 510 } 511 uint32_t vtable_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); 512 // TODO: use ObjectArray<T>::GetWithoutChecks ? 513 AbstractMethod* method = receiver->GetClass()->GetVTable()->Get(vtable_idx); 514 if (UNLIKELY(method == NULL)) { 515 CHECK(self->IsExceptionPending()); 516 result->SetJ(0); 517 return false; 518 } else if (UNLIKELY(method->IsAbstract())) { 519 ThrowAbstractMethodError(method); 520 result->SetJ(0); 521 return false; 522 } 523 524 MethodHelper mh(method); 525 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 526 uint16_t num_regs; 527 uint16_t num_ins; 528 if (code_item != NULL) { 529 num_regs = code_item->registers_size_; 530 num_ins = code_item->ins_size_; 531 } else { 532 DCHECK(method->IsNative() || method->IsProxyMethod()); 533 num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty()); 534 if (!method->IsStatic()) { 535 num_regs++; 536 num_ins++; 537 } 538 } 539 540 void* memory = alloca(ShadowFrame::ComputeSize(num_regs)); 541 ShadowFrame* new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame, 542 method, 0, memory)); 543 size_t cur_reg = num_regs - num_ins; 544 if (receiver != NULL) { 545 new_shadow_frame->SetVRegReference(cur_reg, receiver); 546 ++cur_reg; 547 } 548 549 size_t arg_offset = (receiver == NULL) ? 0 : 1; 550 const char* shorty = mh.GetShorty(); 551 uint32_t arg[5]; 552 if (!is_range) { 553 inst->GetArgs(arg); 554 } 555 for (size_t shorty_pos = 0; cur_reg < num_regs; ++shorty_pos, cur_reg++, arg_offset++) { 556 DCHECK_LT(shorty_pos + 1, mh.GetShortyLength()); 557 size_t arg_pos = is_range ? vregC + arg_offset : arg[arg_offset]; 558 switch (shorty[shorty_pos + 1]) { 559 case 'L': { 560 Object* o = shadow_frame.GetVRegReference(arg_pos); 561 new_shadow_frame->SetVRegReference(cur_reg, o); 562 break; 563 } 564 case 'J': case 'D': { 565 uint64_t wide_value = (static_cast<uint64_t>(shadow_frame.GetVReg(arg_pos + 1)) << 32) | 566 static_cast<uint32_t>(shadow_frame.GetVReg(arg_pos)); 567 new_shadow_frame->SetVRegLong(cur_reg, wide_value); 568 cur_reg++; 569 arg_offset++; 570 break; 571 } 572 default: 573 new_shadow_frame->SetVReg(cur_reg, shadow_frame.GetVReg(arg_pos)); 574 break; 575 } 576 } 577 578 if (LIKELY(Runtime::Current()->IsStarted())) { 579 (method->GetEntryPointFromInterpreter())(self, mh, code_item, new_shadow_frame, result); 580 } else { 581 UnstartedRuntimeInvoke(self, mh, code_item, new_shadow_frame, result, num_regs - num_ins); 582 } 583 return !self->IsExceptionPending(); 584} 585 586// We use template functions to optimize compiler inlining process. Otherwise, 587// some parts of the code (like a switch statement) which depend on a constant 588// parameter would not be inlined while it should be. These constant parameters 589// are now part of the template arguments. 590// Note these template functions are static and inlined so they should not be 591// part of the final object file. 592// TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template 593// specialization. 594template<FindFieldType find_type, Primitive::Type field_type, bool do_access_check> 595static bool DoFieldGet(Thread* self, ShadowFrame& shadow_frame, 596 const Instruction* inst) 597 NO_THREAD_SAFETY_ANALYSIS ALWAYS_INLINE; 598 599template<FindFieldType find_type, Primitive::Type field_type, bool do_access_check> 600static inline bool DoFieldGet(Thread* self, ShadowFrame& shadow_frame, 601 const Instruction* inst) { 602 bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead); 603 uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c(); 604 Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self, 605 find_type, Primitive::FieldSize(field_type), 606 do_access_check); 607 if (UNLIKELY(f == NULL)) { 608 CHECK(self->IsExceptionPending()); 609 return false; 610 } 611 Object* obj; 612 if (is_static) { 613 obj = f->GetDeclaringClass(); 614 } else { 615 obj = shadow_frame.GetVRegReference(inst->VRegB_22c()); 616 if (UNLIKELY(obj == NULL)) { 617 ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(), f, true); 618 return false; 619 } 620 } 621 uint32_t vregA = is_static ? inst->VRegA_21c() : inst->VRegA_22c(); 622 switch (field_type) { 623 case Primitive::kPrimBoolean: 624 shadow_frame.SetVReg(vregA, f->GetBoolean(obj)); 625 break; 626 case Primitive::kPrimByte: 627 shadow_frame.SetVReg(vregA, f->GetByte(obj)); 628 break; 629 case Primitive::kPrimChar: 630 shadow_frame.SetVReg(vregA, f->GetChar(obj)); 631 break; 632 case Primitive::kPrimShort: 633 shadow_frame.SetVReg(vregA, f->GetShort(obj)); 634 break; 635 case Primitive::kPrimInt: 636 shadow_frame.SetVReg(vregA, f->GetInt(obj)); 637 break; 638 case Primitive::kPrimLong: 639 shadow_frame.SetVRegLong(vregA, f->GetLong(obj)); 640 break; 641 case Primitive::kPrimNot: 642 shadow_frame.SetVRegReference(vregA, f->GetObject(obj)); 643 break; 644 default: 645 LOG(FATAL) << "Unreachable: " << field_type; 646 } 647 return true; 648} 649 650// TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template 651// specialization. 652template<Primitive::Type field_type> 653static bool DoIGetQuick(Thread* self, ShadowFrame& shadow_frame, 654 const Instruction* inst) 655 NO_THREAD_SAFETY_ANALYSIS ALWAYS_INLINE; 656 657template<Primitive::Type field_type> 658static inline bool DoIGetQuick(Thread* self, ShadowFrame& shadow_frame, 659 const Instruction* inst) { 660 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c()); 661 if (UNLIKELY(obj == NULL)) { 662 // We lost the reference to the field index so we cannot get a more 663 // precised exception message. 664 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 665 return false; 666 } 667 MemberOffset field_offset(inst->VRegC_22c()); 668 const bool is_volatile = false; // iget-x-quick only on non volatile fields. 669 const uint32_t vregA = inst->VRegA_22c(); 670 switch (field_type) { 671 case Primitive::kPrimInt: 672 shadow_frame.SetVReg(vregA, static_cast<int32_t>(obj->GetField32(field_offset, is_volatile))); 673 break; 674 case Primitive::kPrimLong: 675 shadow_frame.SetVRegLong(vregA, static_cast<int64_t>(obj->GetField64(field_offset, is_volatile))); 676 break; 677 case Primitive::kPrimNot: 678 shadow_frame.SetVRegReference(vregA, obj->GetFieldObject<mirror::Object*>(field_offset, is_volatile)); 679 break; 680 default: 681 LOG(FATAL) << "Unreachable: " << field_type; 682 } 683 return true; 684} 685 686// TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template 687// specialization. 688template<FindFieldType find_type, Primitive::Type field_type, bool do_access_check> 689static bool DoFieldPut(Thread* self, const ShadowFrame& shadow_frame, 690 const Instruction* inst) 691 NO_THREAD_SAFETY_ANALYSIS ALWAYS_INLINE; 692 693template<FindFieldType find_type, Primitive::Type field_type, bool do_access_check> 694static inline bool DoFieldPut(Thread* self, const ShadowFrame& shadow_frame, 695 const Instruction* inst) { 696 bool is_static = (find_type == StaticObjectWrite) || (find_type == StaticPrimitiveWrite); 697 uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c(); 698 Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self, 699 find_type, Primitive::FieldSize(field_type), 700 do_access_check); 701 if (UNLIKELY(f == NULL)) { 702 CHECK(self->IsExceptionPending()); 703 return false; 704 } 705 Object* obj; 706 if (is_static) { 707 obj = f->GetDeclaringClass(); 708 } else { 709 obj = shadow_frame.GetVRegReference(inst->VRegB_22c()); 710 if (UNLIKELY(obj == NULL)) { 711 ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(), 712 f, false); 713 return false; 714 } 715 } 716 uint32_t vregA = is_static ? inst->VRegA_21c() : inst->VRegA_22c(); 717 switch (field_type) { 718 case Primitive::kPrimBoolean: 719 f->SetBoolean(obj, shadow_frame.GetVReg(vregA)); 720 break; 721 case Primitive::kPrimByte: 722 f->SetByte(obj, shadow_frame.GetVReg(vregA)); 723 break; 724 case Primitive::kPrimChar: 725 f->SetChar(obj, shadow_frame.GetVReg(vregA)); 726 break; 727 case Primitive::kPrimShort: 728 f->SetShort(obj, shadow_frame.GetVReg(vregA)); 729 break; 730 case Primitive::kPrimInt: 731 f->SetInt(obj, shadow_frame.GetVReg(vregA)); 732 break; 733 case Primitive::kPrimLong: 734 f->SetLong(obj, shadow_frame.GetVRegLong(vregA)); 735 break; 736 case Primitive::kPrimNot: 737 f->SetObj(obj, shadow_frame.GetVRegReference(vregA)); 738 break; 739 default: 740 LOG(FATAL) << "Unreachable: " << field_type; 741 } 742 return true; 743} 744 745// TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template 746// specialization. 747template<Primitive::Type field_type> 748static bool DoIPutQuick(Thread* self, ShadowFrame& shadow_frame, 749 const Instruction* inst) 750 NO_THREAD_SAFETY_ANALYSIS ALWAYS_INLINE; 751 752template<Primitive::Type field_type> 753static inline bool DoIPutQuick(Thread* self, ShadowFrame& shadow_frame, 754 const Instruction* inst) { 755 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c()); 756 if (UNLIKELY(obj == NULL)) { 757 // We lost the reference to the field index so we cannot get a more 758 // precised exception message. 759 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 760 return false; 761 } 762 MemberOffset field_offset(inst->VRegC_22c()); 763 const bool is_volatile = false; // iput-x-quick only on non volatile fields. 764 const uint32_t vregA = inst->VRegA_22c(); 765 switch (field_type) { 766 case Primitive::kPrimInt: 767 obj->SetField32(field_offset, shadow_frame.GetVReg(vregA), is_volatile); 768 break; 769 case Primitive::kPrimLong: 770 obj->SetField64(field_offset, shadow_frame.GetVRegLong(vregA), is_volatile); 771 break; 772 case Primitive::kPrimNot: 773 obj->SetFieldObject(field_offset, shadow_frame.GetVRegReference(vregA), is_volatile); 774 break; 775 default: 776 LOG(FATAL) << "Unreachable: " << field_type; 777 } 778 return true; 779} 780 781static inline String* ResolveString(Thread* self, MethodHelper& mh, uint32_t string_idx) 782 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 783 Class* java_lang_string_class = String::GetJavaLangString(); 784 if (UNLIKELY(!java_lang_string_class->IsInitialized())) { 785 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 786 if (UNLIKELY(!class_linker->EnsureInitialized(java_lang_string_class, 787 true, true))) { 788 DCHECK(self->IsExceptionPending()); 789 return NULL; 790 } 791 } 792 return mh.ResolveString(string_idx); 793} 794 795static inline bool DoIntDivide(ShadowFrame& shadow_frame, size_t result_reg, 796 int32_t dividend, int32_t divisor) 797 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 798 if (UNLIKELY(divisor == 0)) { 799 ThrowArithmeticExceptionDivideByZero(); 800 return false; 801 } 802 if (UNLIKELY(dividend == kMinInt && divisor == -1)) { 803 shadow_frame.SetVReg(result_reg, kMinInt); 804 } else { 805 shadow_frame.SetVReg(result_reg, dividend / divisor); 806 } 807 return true; 808} 809 810static inline bool DoIntRemainder(ShadowFrame& shadow_frame, size_t result_reg, 811 int32_t dividend, int32_t divisor) 812 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 813 if (UNLIKELY(divisor == 0)) { 814 ThrowArithmeticExceptionDivideByZero(); 815 return false; 816 } 817 if (UNLIKELY(dividend == kMinInt && divisor == -1)) { 818 shadow_frame.SetVReg(result_reg, 0); 819 } else { 820 shadow_frame.SetVReg(result_reg, dividend % divisor); 821 } 822 return true; 823} 824 825static inline bool DoLongDivide(ShadowFrame& shadow_frame, size_t result_reg, 826 int64_t dividend, int64_t divisor) 827 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 828 if (UNLIKELY(divisor == 0)) { 829 ThrowArithmeticExceptionDivideByZero(); 830 return false; 831 } 832 if (UNLIKELY(dividend == kMinLong && divisor == -1)) { 833 shadow_frame.SetVRegLong(result_reg, kMinLong); 834 } else { 835 shadow_frame.SetVRegLong(result_reg, dividend / divisor); 836 } 837 return true; 838} 839 840static inline bool DoLongRemainder(ShadowFrame& shadow_frame, size_t result_reg, 841 int64_t dividend, int64_t divisor) 842 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 843 if (UNLIKELY(divisor == 0)) { 844 ThrowArithmeticExceptionDivideByZero(); 845 return false; 846 } 847 if (UNLIKELY(dividend == kMinLong && divisor == -1)) { 848 shadow_frame.SetVRegLong(result_reg, 0); 849 } else { 850 shadow_frame.SetVRegLong(result_reg, dividend % divisor); 851 } 852 return true; 853} 854 855// TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template 856// specialization. 857// Returns true on success, otherwise throws an exception and returns false. 858template <bool is_range, bool do_access_check> 859static bool DoFilledNewArray(const Instruction* inst, const ShadowFrame& shadow_frame, 860 Thread* self, JValue* result) 861 NO_THREAD_SAFETY_ANALYSIS ALWAYS_INLINE; 862 863template <bool is_range, bool do_access_check> 864static inline bool DoFilledNewArray(const Instruction* inst, 865 const ShadowFrame& shadow_frame, 866 Thread* self, JValue* result) { 867 DCHECK(inst->Opcode() == Instruction::FILLED_NEW_ARRAY || 868 inst->Opcode() == Instruction::FILLED_NEW_ARRAY_RANGE); 869 const int32_t length = is_range ? inst->VRegA_3rc() : inst->VRegA_35c(); 870 if (!is_range) { 871 // Checks FILLED_NEW_ARRAY's length does not exceed 5 arguments. 872 CHECK_LE(length, 5); 873 } 874 if (UNLIKELY(length < 0)) { 875 ThrowNegativeArraySizeException(length); 876 return false; 877 } 878 uint16_t type_idx = is_range ? inst->VRegB_3rc() : inst->VRegB_35c(); 879 Class* arrayClass = ResolveVerifyAndClinit(type_idx, shadow_frame.GetMethod(), 880 self, false, do_access_check); 881 if (UNLIKELY(arrayClass == NULL)) { 882 DCHECK(self->IsExceptionPending()); 883 return false; 884 } 885 CHECK(arrayClass->IsArrayClass()); 886 Class* componentClass = arrayClass->GetComponentType(); 887 if (UNLIKELY(componentClass->IsPrimitive() && !componentClass->IsPrimitiveInt())) { 888 if (componentClass->IsPrimitiveLong() || componentClass->IsPrimitiveDouble()) { 889 ThrowRuntimeException("Bad filled array request for type %s", 890 PrettyDescriptor(componentClass).c_str()); 891 } else { 892 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(), 893 "Ljava/lang/InternalError;", 894 "Found type %s; filled-new-array not implemented for anything but \'int\'", 895 PrettyDescriptor(componentClass).c_str()); 896 } 897 return false; 898 } 899 Object* newArray = Array::Alloc(self, arrayClass, length); 900 if (UNLIKELY(newArray == NULL)) { 901 DCHECK(self->IsExceptionPending()); 902 return false; 903 } 904 if (is_range) { 905 uint32_t vregC = inst->VRegC_3rc(); 906 const bool is_primitive_int_component = componentClass->IsPrimitiveInt(); 907 for (int32_t i = 0; i < length; ++i) { 908 if (is_primitive_int_component) { 909 newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(vregC + i)); 910 } else { 911 newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(vregC + i)); 912 } 913 } 914 } else { 915 uint32_t arg[5]; 916 inst->GetArgs(arg); 917 const bool is_primitive_int_component = componentClass->IsPrimitiveInt(); 918 for (int32_t i = 0; i < length; ++i) { 919 if (is_primitive_int_component) { 920 newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(arg[i])); 921 } else { 922 newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(arg[i])); 923 } 924 } 925 } 926 927 result->SetL(newArray); 928 return true; 929} 930 931static inline const Instruction* DoSparseSwitch(const Instruction* inst, 932 const ShadowFrame& shadow_frame) 933 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 934 DCHECK(inst->Opcode() == Instruction::SPARSE_SWITCH); 935 const uint16_t* switch_data = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t(); 936 int32_t test_val = shadow_frame.GetVReg(inst->VRegA_31t()); 937 DCHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature)); 938 uint16_t size = switch_data[1]; 939 DCHECK_GT(size, 0); 940 const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]); 941 DCHECK(IsAligned<4>(keys)); 942 const int32_t* entries = keys + size; 943 DCHECK(IsAligned<4>(entries)); 944 int lo = 0; 945 int hi = size - 1; 946 while (lo <= hi) { 947 int mid = (lo + hi) / 2; 948 int32_t foundVal = keys[mid]; 949 if (test_val < foundVal) { 950 hi = mid - 1; 951 } else if (test_val > foundVal) { 952 lo = mid + 1; 953 } else { 954 return inst->RelativeAt(entries[mid]); 955 } 956 } 957 return inst->Next_3xx(); 958} 959 960static inline const Instruction* FindNextInstructionFollowingException(Thread* self, 961 ShadowFrame& shadow_frame, 962 uint32_t dex_pc, 963 const uint16_t* insns, 964 SirtRef<Object>& this_object_ref, 965 instrumentation::Instrumentation* instrumentation) 966 ALWAYS_INLINE; 967 968static inline const Instruction* FindNextInstructionFollowingException(Thread* self, 969 ShadowFrame& shadow_frame, 970 uint32_t dex_pc, 971 const uint16_t* insns, 972 SirtRef<Object>& this_object_ref, 973 instrumentation::Instrumentation* instrumentation) 974 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 975 self->VerifyStack(); 976 ThrowLocation throw_location; 977 mirror::Throwable* exception = self->GetException(&throw_location); 978 bool clear_exception; 979 uint32_t found_dex_pc = shadow_frame.GetMethod()->FindCatchBlock(exception->GetClass(), dex_pc, 980 &clear_exception); 981 if (found_dex_pc == DexFile::kDexNoIndex) { 982 instrumentation->MethodUnwindEvent(self, this_object_ref.get(), 983 shadow_frame.GetMethod(), dex_pc); 984 return NULL; 985 } else { 986 instrumentation->ExceptionCaughtEvent(self, throw_location, 987 shadow_frame.GetMethod(), 988 found_dex_pc, exception); 989 if (clear_exception) { 990 self->ClearException(); 991 } 992 return Instruction::At(insns + found_dex_pc); 993 } 994} 995 996#define HANDLE_PENDING_EXCEPTION() \ 997 CHECK(self->IsExceptionPending()); \ 998 inst = FindNextInstructionFollowingException(self, shadow_frame, inst->GetDexPc(insns), insns, \ 999 this_object_ref, instrumentation); \ 1000 if (inst == NULL) { \ 1001 return JValue(); /* Handled in caller. */ \ 1002 } 1003 1004#define POSSIBLY_HANDLE_PENDING_EXCEPTION(is_exception_pending, next_function) \ 1005 if (UNLIKELY(is_exception_pending)) { \ 1006 HANDLE_PENDING_EXCEPTION(); \ 1007 } else { \ 1008 inst = inst->next_function(); \ 1009 } 1010 1011static void UnexpectedOpcode(const Instruction* inst, MethodHelper& mh) 1012 __attribute__((cold, noreturn, noinline)); 1013 1014static void UnexpectedOpcode(const Instruction* inst, MethodHelper& mh) 1015 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1016 LOG(FATAL) << "Unexpected instruction: " << inst->DumpString(&mh.GetDexFile()); 1017 exit(0); // Unreachable, keep GCC happy. 1018} 1019 1020// Code to run before each dex instruction. 1021#define PREAMBLE() 1022 1023// TODO: should be SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) which is failing due to template 1024// specialization. 1025template<bool do_access_check> 1026static JValue ExecuteImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 1027 ShadowFrame& shadow_frame, JValue result_register) 1028 NO_THREAD_SAFETY_ANALYSIS __attribute__((hot)); 1029 1030template<bool do_access_check> 1031static JValue ExecuteImpl(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 1032 ShadowFrame& shadow_frame, JValue result_register) { 1033 if (UNLIKELY(!shadow_frame.HasReferenceArray())) { 1034 LOG(FATAL) << "Invalid shadow frame for interpreter use"; 1035 return JValue(); 1036 } 1037 self->VerifyStack(); 1038 instrumentation::Instrumentation* const instrumentation = Runtime::Current()->GetInstrumentation(); 1039 1040 // As the 'this' object won't change during the execution of current code, we 1041 // want to cache it in local variables. Nevertheless, in order to let the 1042 // garbage collector access it, we store it into sirt references. 1043 SirtRef<Object> this_object_ref(self, shadow_frame.GetThisObject(code_item->ins_size_)); 1044 1045 uint32_t dex_pc = shadow_frame.GetDexPC(); 1046 if (LIKELY(dex_pc == 0)) { // We are entering the method as opposed to deoptimizing.. 1047 if (UNLIKELY(instrumentation->HasMethodEntryListeners())) { 1048 instrumentation->MethodEnterEvent(self, this_object_ref.get(), 1049 shadow_frame.GetMethod(), 0); 1050 } 1051 } 1052 const uint16_t* const insns = code_item->insns_; 1053 const Instruction* inst = Instruction::At(insns + dex_pc); 1054 while (true) { 1055 dex_pc = inst->GetDexPc(insns); 1056 shadow_frame.SetDexPC(dex_pc); 1057 if (UNLIKELY(self->TestAllFlags())) { 1058 CheckSuspend(self); 1059 } 1060 if (UNLIKELY(instrumentation->HasDexPcListeners())) { 1061 instrumentation->DexPcMovedEvent(self, this_object_ref.get(), 1062 shadow_frame.GetMethod(), dex_pc); 1063 } 1064 const bool kTracing = false; 1065 if (kTracing) { 1066#define TRACE_LOG std::cerr 1067 TRACE_LOG << PrettyMethod(shadow_frame.GetMethod()) 1068 << StringPrintf("\n0x%x: ", dex_pc) 1069 << inst->DumpString(&mh.GetDexFile()) << "\n"; 1070 for (size_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) { 1071 uint32_t raw_value = shadow_frame.GetVReg(i); 1072 Object* ref_value = shadow_frame.GetVRegReference(i); 1073 TRACE_LOG << StringPrintf(" vreg%d=0x%08X", i, raw_value); 1074 if (ref_value != NULL) { 1075 if (ref_value->GetClass()->IsStringClass() && 1076 ref_value->AsString()->GetCharArray() != NULL) { 1077 TRACE_LOG << "/java.lang.String \"" << ref_value->AsString()->ToModifiedUtf8() << "\""; 1078 } else { 1079 TRACE_LOG << "/" << PrettyTypeOf(ref_value); 1080 } 1081 } 1082 } 1083 TRACE_LOG << "\n"; 1084#undef TRACE_LOG 1085 } 1086 switch (inst->Opcode()) { 1087 case Instruction::NOP: 1088 PREAMBLE(); 1089 inst = inst->Next_1xx(); 1090 break; 1091 case Instruction::MOVE: 1092 PREAMBLE(); 1093 shadow_frame.SetVReg(inst->VRegA_12x(), 1094 shadow_frame.GetVReg(inst->VRegB_12x())); 1095 inst = inst->Next_1xx(); 1096 break; 1097 case Instruction::MOVE_FROM16: 1098 PREAMBLE(); 1099 shadow_frame.SetVReg(inst->VRegA_22x(), 1100 shadow_frame.GetVReg(inst->VRegB_22x())); 1101 inst = inst->Next_2xx(); 1102 break; 1103 case Instruction::MOVE_16: 1104 PREAMBLE(); 1105 shadow_frame.SetVReg(inst->VRegA_32x(), 1106 shadow_frame.GetVReg(inst->VRegB_32x())); 1107 inst = inst->Next_3xx(); 1108 break; 1109 case Instruction::MOVE_WIDE: 1110 PREAMBLE(); 1111 shadow_frame.SetVRegLong(inst->VRegA_12x(), 1112 shadow_frame.GetVRegLong(inst->VRegB_12x())); 1113 inst = inst->Next_1xx(); 1114 break; 1115 case Instruction::MOVE_WIDE_FROM16: 1116 PREAMBLE(); 1117 shadow_frame.SetVRegLong(inst->VRegA_22x(), 1118 shadow_frame.GetVRegLong(inst->VRegB_22x())); 1119 inst = inst->Next_2xx(); 1120 break; 1121 case Instruction::MOVE_WIDE_16: 1122 PREAMBLE(); 1123 shadow_frame.SetVRegLong(inst->VRegA_32x(), 1124 shadow_frame.GetVRegLong(inst->VRegB_32x())); 1125 inst = inst->Next_3xx(); 1126 break; 1127 case Instruction::MOVE_OBJECT: 1128 PREAMBLE(); 1129 shadow_frame.SetVRegReference(inst->VRegA_12x(), 1130 shadow_frame.GetVRegReference(inst->VRegB_12x())); 1131 inst = inst->Next_1xx(); 1132 break; 1133 case Instruction::MOVE_OBJECT_FROM16: 1134 PREAMBLE(); 1135 shadow_frame.SetVRegReference(inst->VRegA_22x(), 1136 shadow_frame.GetVRegReference(inst->VRegB_22x())); 1137 inst = inst->Next_2xx(); 1138 break; 1139 case Instruction::MOVE_OBJECT_16: 1140 PREAMBLE(); 1141 shadow_frame.SetVRegReference(inst->VRegA_32x(), 1142 shadow_frame.GetVRegReference(inst->VRegB_32x())); 1143 inst = inst->Next_3xx(); 1144 break; 1145 case Instruction::MOVE_RESULT: 1146 PREAMBLE(); 1147 shadow_frame.SetVReg(inst->VRegA_11x(), result_register.GetI()); 1148 inst = inst->Next_1xx(); 1149 break; 1150 case Instruction::MOVE_RESULT_WIDE: 1151 PREAMBLE(); 1152 shadow_frame.SetVRegLong(inst->VRegA_11x(), result_register.GetJ()); 1153 inst = inst->Next_1xx(); 1154 break; 1155 case Instruction::MOVE_RESULT_OBJECT: 1156 PREAMBLE(); 1157 shadow_frame.SetVRegReference(inst->VRegA_11x(), result_register.GetL()); 1158 inst = inst->Next_1xx(); 1159 break; 1160 case Instruction::MOVE_EXCEPTION: { 1161 PREAMBLE(); 1162 Throwable* exception = self->GetException(NULL); 1163 self->ClearException(); 1164 shadow_frame.SetVRegReference(inst->VRegA_11x(), exception); 1165 inst = inst->Next_1xx(); 1166 break; 1167 } 1168 case Instruction::RETURN_VOID: { 1169 PREAMBLE(); 1170 JValue result; 1171 if (UNLIKELY(instrumentation->HasMethodExitListeners())) { 1172 instrumentation->MethodExitEvent(self, this_object_ref.get(), 1173 shadow_frame.GetMethod(), inst->GetDexPc(insns), 1174 result); 1175 } 1176 return result; 1177 } 1178 case Instruction::RETURN_VOID_BARRIER: { 1179 PREAMBLE(); 1180 ANDROID_MEMBAR_STORE(); 1181 JValue result; 1182 if (UNLIKELY(instrumentation->HasMethodExitListeners())) { 1183 instrumentation->MethodExitEvent(self, this_object_ref.get(), 1184 shadow_frame.GetMethod(), inst->GetDexPc(insns), 1185 result); 1186 } 1187 return result; 1188 } 1189 case Instruction::RETURN: { 1190 PREAMBLE(); 1191 JValue result; 1192 result.SetJ(0); 1193 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x())); 1194 if (UNLIKELY(instrumentation->HasMethodExitListeners())) { 1195 instrumentation->MethodExitEvent(self, this_object_ref.get(), 1196 shadow_frame.GetMethod(), inst->GetDexPc(insns), 1197 result); 1198 } 1199 return result; 1200 } 1201 case Instruction::RETURN_WIDE: { 1202 PREAMBLE(); 1203 JValue result; 1204 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x())); 1205 if (UNLIKELY(instrumentation->HasMethodExitListeners())) { 1206 instrumentation->MethodExitEvent(self, this_object_ref.get(), 1207 shadow_frame.GetMethod(), inst->GetDexPc(insns), 1208 result); 1209 } 1210 return result; 1211 } 1212 case Instruction::RETURN_OBJECT: { 1213 PREAMBLE(); 1214 JValue result; 1215 result.SetJ(0); 1216 result.SetL(shadow_frame.GetVRegReference(inst->VRegA_11x())); 1217 if (UNLIKELY(instrumentation->HasMethodExitListeners())) { 1218 instrumentation->MethodExitEvent(self, this_object_ref.get(), 1219 shadow_frame.GetMethod(), inst->GetDexPc(insns), 1220 result); 1221 } 1222 return result; 1223 } 1224 case Instruction::CONST_4: { 1225 PREAMBLE(); 1226 uint4_t dst = inst->VRegA_11n(); 1227 int4_t val = inst->VRegB_11n(); 1228 shadow_frame.SetVReg(dst, val); 1229 if (val == 0) { 1230 shadow_frame.SetVRegReference(dst, NULL); 1231 } 1232 inst = inst->Next_1xx(); 1233 break; 1234 } 1235 case Instruction::CONST_16: { 1236 PREAMBLE(); 1237 uint8_t dst = inst->VRegA_21s(); 1238 int16_t val = inst->VRegB_21s(); 1239 shadow_frame.SetVReg(dst, val); 1240 if (val == 0) { 1241 shadow_frame.SetVRegReference(dst, NULL); 1242 } 1243 inst = inst->Next_2xx(); 1244 break; 1245 } 1246 case Instruction::CONST: { 1247 PREAMBLE(); 1248 uint8_t dst = inst->VRegA_31i(); 1249 int32_t val = inst->VRegB_31i(); 1250 shadow_frame.SetVReg(dst, val); 1251 if (val == 0) { 1252 shadow_frame.SetVRegReference(dst, NULL); 1253 } 1254 inst = inst->Next_3xx(); 1255 break; 1256 } 1257 case Instruction::CONST_HIGH16: { 1258 PREAMBLE(); 1259 uint8_t dst = inst->VRegA_21h(); 1260 int32_t val = static_cast<int32_t>(inst->VRegB_21h() << 16); 1261 shadow_frame.SetVReg(dst, val); 1262 if (val == 0) { 1263 shadow_frame.SetVRegReference(dst, NULL); 1264 } 1265 inst = inst->Next_2xx(); 1266 break; 1267 } 1268 case Instruction::CONST_WIDE_16: 1269 PREAMBLE(); 1270 shadow_frame.SetVRegLong(inst->VRegA_21s(), inst->VRegB_21s()); 1271 inst = inst->Next_2xx(); 1272 break; 1273 case Instruction::CONST_WIDE_32: 1274 PREAMBLE(); 1275 shadow_frame.SetVRegLong(inst->VRegA_31i(), inst->VRegB_31i()); 1276 inst = inst->Next_3xx(); 1277 break; 1278 case Instruction::CONST_WIDE: 1279 PREAMBLE(); 1280 shadow_frame.SetVRegLong(inst->VRegA_51l(), inst->VRegB_51l()); 1281 inst = inst->Next_51l(); 1282 break; 1283 case Instruction::CONST_WIDE_HIGH16: 1284 shadow_frame.SetVRegLong(inst->VRegA_21h(), 1285 static_cast<uint64_t>(inst->VRegB_21h()) << 48); 1286 inst = inst->Next_2xx(); 1287 break; 1288 case Instruction::CONST_STRING: { 1289 PREAMBLE(); 1290 String* s = ResolveString(self, mh, inst->VRegB_21c()); 1291 if (UNLIKELY(s == NULL)) { 1292 HANDLE_PENDING_EXCEPTION(); 1293 } else { 1294 shadow_frame.SetVRegReference(inst->VRegA_21c(), s); 1295 inst = inst->Next_2xx(); 1296 } 1297 break; 1298 } 1299 case Instruction::CONST_STRING_JUMBO: { 1300 PREAMBLE(); 1301 String* s = ResolveString(self, mh, inst->VRegB_31c()); 1302 if (UNLIKELY(s == NULL)) { 1303 HANDLE_PENDING_EXCEPTION(); 1304 } else { 1305 shadow_frame.SetVRegReference(inst->VRegA_31c(), s); 1306 inst = inst->Next_3xx(); 1307 } 1308 break; 1309 } 1310 case Instruction::CONST_CLASS: { 1311 PREAMBLE(); 1312 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(), 1313 self, false, do_access_check); 1314 if (UNLIKELY(c == NULL)) { 1315 HANDLE_PENDING_EXCEPTION(); 1316 } else { 1317 shadow_frame.SetVRegReference(inst->VRegA_21c(), c); 1318 inst = inst->Next_2xx(); 1319 } 1320 break; 1321 } 1322 case Instruction::MONITOR_ENTER: { 1323 PREAMBLE(); 1324 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x()); 1325 if (UNLIKELY(obj == NULL)) { 1326 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1327 HANDLE_PENDING_EXCEPTION(); 1328 } else { 1329 DoMonitorEnter(self, obj); 1330 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx); 1331 } 1332 break; 1333 } 1334 case Instruction::MONITOR_EXIT: { 1335 PREAMBLE(); 1336 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x()); 1337 if (UNLIKELY(obj == NULL)) { 1338 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1339 HANDLE_PENDING_EXCEPTION(); 1340 } else { 1341 DoMonitorExit(self, obj); 1342 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx); 1343 } 1344 break; 1345 } 1346 case Instruction::CHECK_CAST: { 1347 PREAMBLE(); 1348 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(), 1349 self, false, do_access_check); 1350 if (UNLIKELY(c == NULL)) { 1351 HANDLE_PENDING_EXCEPTION(); 1352 } else { 1353 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c()); 1354 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) { 1355 ThrowClassCastException(c, obj->GetClass()); 1356 HANDLE_PENDING_EXCEPTION(); 1357 } else { 1358 inst = inst->Next_2xx(); 1359 } 1360 } 1361 break; 1362 } 1363 case Instruction::INSTANCE_OF: { 1364 PREAMBLE(); 1365 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(), 1366 self, false, do_access_check); 1367 if (UNLIKELY(c == NULL)) { 1368 HANDLE_PENDING_EXCEPTION(); 1369 } else { 1370 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c()); 1371 shadow_frame.SetVReg(inst->VRegA_22c(), (obj != NULL && obj->InstanceOf(c)) ? 1 : 0); 1372 inst = inst->Next_2xx(); 1373 } 1374 break; 1375 } 1376 case Instruction::ARRAY_LENGTH: { 1377 PREAMBLE(); 1378 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x()); 1379 if (UNLIKELY(array == NULL)) { 1380 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1381 HANDLE_PENDING_EXCEPTION(); 1382 } else { 1383 shadow_frame.SetVReg(inst->VRegA_12x(), array->AsArray()->GetLength()); 1384 inst = inst->Next_1xx(); 1385 } 1386 break; 1387 } 1388 case Instruction::NEW_INSTANCE: { 1389 PREAMBLE(); 1390 Object* obj = AllocObjectFromCode(inst->VRegB_21c(), shadow_frame.GetMethod(), 1391 self, do_access_check); 1392 if (UNLIKELY(obj == NULL)) { 1393 HANDLE_PENDING_EXCEPTION(); 1394 } else { 1395 shadow_frame.SetVRegReference(inst->VRegA_21c(), obj); 1396 inst = inst->Next_2xx(); 1397 } 1398 break; 1399 } 1400 case Instruction::NEW_ARRAY: { 1401 PREAMBLE(); 1402 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c()); 1403 Object* obj = AllocArrayFromCode(inst->VRegC_22c(), shadow_frame.GetMethod(), 1404 length, self, do_access_check); 1405 if (UNLIKELY(obj == NULL)) { 1406 HANDLE_PENDING_EXCEPTION(); 1407 } else { 1408 shadow_frame.SetVRegReference(inst->VRegA_22c(), obj); 1409 inst = inst->Next_2xx(); 1410 } 1411 break; 1412 } 1413 case Instruction::FILLED_NEW_ARRAY: { 1414 PREAMBLE(); 1415 bool success = DoFilledNewArray<false, do_access_check>(inst, shadow_frame, 1416 self, &result_register); 1417 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); 1418 break; 1419 } 1420 case Instruction::FILLED_NEW_ARRAY_RANGE: { 1421 PREAMBLE(); 1422 bool success = DoFilledNewArray<true, do_access_check>(inst, shadow_frame, 1423 self, &result_register); 1424 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); 1425 break; 1426 } 1427 case Instruction::FILL_ARRAY_DATA: { 1428 PREAMBLE(); 1429 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t()); 1430 if (UNLIKELY(obj == NULL)) { 1431 ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA"); 1432 HANDLE_PENDING_EXCEPTION(); 1433 break; 1434 } 1435 Array* array = obj->AsArray(); 1436 DCHECK(array->IsArrayInstance() && !array->IsObjectArray()); 1437 const uint16_t* payload_addr = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t(); 1438 const Instruction::ArrayDataPayload* payload = 1439 reinterpret_cast<const Instruction::ArrayDataPayload*>(payload_addr); 1440 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) { 1441 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(), 1442 "Ljava/lang/ArrayIndexOutOfBoundsException;", 1443 "failed FILL_ARRAY_DATA; length=%d, index=%d", 1444 array->GetLength(), payload->element_count); 1445 HANDLE_PENDING_EXCEPTION(); 1446 break; 1447 } 1448 uint32_t size_in_bytes = payload->element_count * payload->element_width; 1449 memcpy(array->GetRawData(payload->element_width), payload->data, size_in_bytes); 1450 inst = inst->Next_3xx(); 1451 break; 1452 } 1453 case Instruction::THROW: { 1454 PREAMBLE(); 1455 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x()); 1456 if (UNLIKELY(exception == NULL)) { 1457 ThrowNullPointerException(NULL, "throw with null exception"); 1458 } else { 1459 self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable()); 1460 } 1461 HANDLE_PENDING_EXCEPTION(); 1462 break; 1463 } 1464 case Instruction::GOTO: { 1465 PREAMBLE(); 1466 inst = inst->RelativeAt(inst->VRegA_10t()); 1467 break; 1468 } 1469 case Instruction::GOTO_16: { 1470 PREAMBLE(); 1471 inst = inst->RelativeAt(inst->VRegA_20t()); 1472 break; 1473 } 1474 case Instruction::GOTO_32: { 1475 PREAMBLE(); 1476 inst = inst->RelativeAt(inst->VRegA_30t()); 1477 break; 1478 } 1479 case Instruction::PACKED_SWITCH: { 1480 PREAMBLE(); 1481 const uint16_t* switch_data = reinterpret_cast<const uint16_t*>(inst) + inst->VRegB_31t(); 1482 int32_t test_val = shadow_frame.GetVReg(inst->VRegA_31t()); 1483 DCHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kPackedSwitchSignature)); 1484 uint16_t size = switch_data[1]; 1485 DCHECK_GT(size, 0); 1486 const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]); 1487 DCHECK(IsAligned<4>(keys)); 1488 int32_t first_key = keys[0]; 1489 const int32_t* targets = reinterpret_cast<const int32_t*>(&switch_data[4]); 1490 DCHECK(IsAligned<4>(targets)); 1491 int32_t index = test_val - first_key; 1492 if (index >= 0 && index < size) { 1493 inst = inst->RelativeAt(targets[index]); 1494 } else { 1495 inst = inst->Next_3xx(); 1496 } 1497 break; 1498 } 1499 case Instruction::SPARSE_SWITCH: { 1500 PREAMBLE(); 1501 inst = DoSparseSwitch(inst, shadow_frame); 1502 break; 1503 } 1504 case Instruction::CMPL_FLOAT: { 1505 PREAMBLE(); 1506 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x()); 1507 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x()); 1508 int32_t result; 1509 if (val1 > val2) { 1510 result = 1; 1511 } else if (val1 == val2) { 1512 result = 0; 1513 } else { 1514 result = -1; 1515 } 1516 shadow_frame.SetVReg(inst->VRegA_23x(), result); 1517 inst = inst->Next_2xx(); 1518 break; 1519 } 1520 case Instruction::CMPG_FLOAT: { 1521 PREAMBLE(); 1522 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x()); 1523 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x()); 1524 int32_t result; 1525 if (val1 < val2) { 1526 result = -1; 1527 } else if (val1 == val2) { 1528 result = 0; 1529 } else { 1530 result = 1; 1531 } 1532 shadow_frame.SetVReg(inst->VRegA_23x(), result); 1533 inst = inst->Next_2xx(); 1534 break; 1535 } 1536 case Instruction::CMPL_DOUBLE: { 1537 PREAMBLE(); 1538 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x()); 1539 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x()); 1540 int32_t result; 1541 if (val1 > val2) { 1542 result = 1; 1543 } else if (val1 == val2) { 1544 result = 0; 1545 } else { 1546 result = -1; 1547 } 1548 shadow_frame.SetVReg(inst->VRegA_23x(), result); 1549 inst = inst->Next_2xx(); 1550 break; 1551 } 1552 1553 case Instruction::CMPG_DOUBLE: { 1554 PREAMBLE(); 1555 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x()); 1556 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x()); 1557 int32_t result; 1558 if (val1 < val2) { 1559 result = -1; 1560 } else if (val1 == val2) { 1561 result = 0; 1562 } else { 1563 result = 1; 1564 } 1565 shadow_frame.SetVReg(inst->VRegA_23x(), result); 1566 inst = inst->Next_2xx(); 1567 break; 1568 } 1569 case Instruction::CMP_LONG: { 1570 PREAMBLE(); 1571 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x()); 1572 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x()); 1573 int32_t result; 1574 if (val1 > val2) { 1575 result = 1; 1576 } else if (val1 == val2) { 1577 result = 0; 1578 } else { 1579 result = -1; 1580 } 1581 shadow_frame.SetVReg(inst->VRegA_23x(), result); 1582 inst = inst->Next_2xx(); 1583 break; 1584 } 1585 case Instruction::IF_EQ: { 1586 PREAMBLE(); 1587 if (shadow_frame.GetVReg(inst->VRegA_22t()) == shadow_frame.GetVReg(inst->VRegB_22t())) { 1588 inst = inst->RelativeAt(inst->VRegC_22t()); 1589 } else { 1590 inst = inst->Next_2xx(); 1591 } 1592 break; 1593 } 1594 case Instruction::IF_NE: { 1595 PREAMBLE(); 1596 if (shadow_frame.GetVReg(inst->VRegA_22t()) != shadow_frame.GetVReg(inst->VRegB_22t())) { 1597 inst = inst->RelativeAt(inst->VRegC_22t()); 1598 } else { 1599 inst = inst->Next_2xx(); 1600 } 1601 break; 1602 } 1603 case Instruction::IF_LT: { 1604 PREAMBLE(); 1605 if (shadow_frame.GetVReg(inst->VRegA_22t()) < shadow_frame.GetVReg(inst->VRegB_22t())) { 1606 inst = inst->RelativeAt(inst->VRegC_22t()); 1607 } else { 1608 inst = inst->Next_2xx(); 1609 } 1610 break; 1611 } 1612 case Instruction::IF_GE: { 1613 PREAMBLE(); 1614 if (shadow_frame.GetVReg(inst->VRegA_22t()) >= shadow_frame.GetVReg(inst->VRegB_22t())) { 1615 inst = inst->RelativeAt(inst->VRegC_22t()); 1616 } else { 1617 inst = inst->Next_2xx(); 1618 } 1619 break; 1620 } 1621 case Instruction::IF_GT: { 1622 PREAMBLE(); 1623 if (shadow_frame.GetVReg(inst->VRegA_22t()) > shadow_frame.GetVReg(inst->VRegB_22t())) { 1624 inst = inst->RelativeAt(inst->VRegC_22t()); 1625 } else { 1626 inst = inst->Next_2xx(); 1627 } 1628 break; 1629 } 1630 case Instruction::IF_LE: { 1631 PREAMBLE(); 1632 if (shadow_frame.GetVReg(inst->VRegA_22t()) <= shadow_frame.GetVReg(inst->VRegB_22t())) { 1633 inst = inst->RelativeAt(inst->VRegC_22t()); 1634 } else { 1635 inst = inst->Next_2xx(); 1636 } 1637 break; 1638 } 1639 case Instruction::IF_EQZ: { 1640 PREAMBLE(); 1641 if (shadow_frame.GetVReg(inst->VRegA_21t()) == 0) { 1642 inst = inst->RelativeAt(inst->VRegB_21t()); 1643 } else { 1644 inst = inst->Next_2xx(); 1645 } 1646 break; 1647 } 1648 case Instruction::IF_NEZ: { 1649 PREAMBLE(); 1650 if (shadow_frame.GetVReg(inst->VRegA_21t()) != 0) { 1651 inst = inst->RelativeAt(inst->VRegB_21t()); 1652 } else { 1653 inst = inst->Next_2xx(); 1654 } 1655 break; 1656 } 1657 case Instruction::IF_LTZ: { 1658 PREAMBLE(); 1659 if (shadow_frame.GetVReg(inst->VRegA_21t()) < 0) { 1660 inst = inst->RelativeAt(inst->VRegB_21t()); 1661 } else { 1662 inst = inst->Next_2xx(); 1663 } 1664 break; 1665 } 1666 case Instruction::IF_GEZ: { 1667 PREAMBLE(); 1668 if (shadow_frame.GetVReg(inst->VRegA_21t()) >= 0) { 1669 inst = inst->RelativeAt(inst->VRegB_21t()); 1670 } else { 1671 inst = inst->Next_2xx(); 1672 } 1673 break; 1674 } 1675 case Instruction::IF_GTZ: { 1676 PREAMBLE(); 1677 if (shadow_frame.GetVReg(inst->VRegA_21t()) > 0) { 1678 inst = inst->RelativeAt(inst->VRegB_21t()); 1679 } else { 1680 inst = inst->Next_2xx(); 1681 } 1682 break; 1683 } 1684 case Instruction::IF_LEZ: { 1685 PREAMBLE(); 1686 if (shadow_frame.GetVReg(inst->VRegA_21t()) <= 0) { 1687 inst = inst->RelativeAt(inst->VRegB_21t()); 1688 } else { 1689 inst = inst->Next_2xx(); 1690 } 1691 break; 1692 } 1693 case Instruction::AGET_BOOLEAN: { 1694 PREAMBLE(); 1695 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1696 if (UNLIKELY(a == NULL)) { 1697 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1698 HANDLE_PENDING_EXCEPTION(); 1699 break; 1700 } 1701 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1702 BooleanArray* array = a->AsBooleanArray(); 1703 if (LIKELY(array->IsValidIndex(index))) { 1704 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]); 1705 inst = inst->Next_2xx(); 1706 } else { 1707 HANDLE_PENDING_EXCEPTION(); 1708 } 1709 break; 1710 } 1711 case Instruction::AGET_BYTE: { 1712 PREAMBLE(); 1713 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1714 if (UNLIKELY(a == NULL)) { 1715 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1716 HANDLE_PENDING_EXCEPTION(); 1717 break; 1718 } 1719 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1720 ByteArray* array = a->AsByteArray(); 1721 if (LIKELY(array->IsValidIndex(index))) { 1722 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]); 1723 inst = inst->Next_2xx(); 1724 } else { 1725 HANDLE_PENDING_EXCEPTION(); 1726 } 1727 break; 1728 } 1729 case Instruction::AGET_CHAR: { 1730 PREAMBLE(); 1731 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1732 if (UNLIKELY(a == NULL)) { 1733 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1734 HANDLE_PENDING_EXCEPTION(); 1735 break; 1736 } 1737 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1738 CharArray* array = a->AsCharArray(); 1739 if (LIKELY(array->IsValidIndex(index))) { 1740 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]); 1741 inst = inst->Next_2xx(); 1742 } else { 1743 HANDLE_PENDING_EXCEPTION(); 1744 } 1745 break; 1746 } 1747 case Instruction::AGET_SHORT: { 1748 PREAMBLE(); 1749 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1750 if (UNLIKELY(a == NULL)) { 1751 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1752 HANDLE_PENDING_EXCEPTION(); 1753 break; 1754 } 1755 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1756 ShortArray* array = a->AsShortArray(); 1757 if (LIKELY(array->IsValidIndex(index))) { 1758 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]); 1759 inst = inst->Next_2xx(); 1760 } else { 1761 HANDLE_PENDING_EXCEPTION(); 1762 } 1763 break; 1764 } 1765 case Instruction::AGET: { 1766 PREAMBLE(); 1767 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1768 if (UNLIKELY(a == NULL)) { 1769 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1770 HANDLE_PENDING_EXCEPTION(); 1771 break; 1772 } 1773 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1774 IntArray* array = a->AsIntArray(); 1775 if (LIKELY(array->IsValidIndex(index))) { 1776 shadow_frame.SetVReg(inst->VRegA_23x(), array->GetData()[index]); 1777 inst = inst->Next_2xx(); 1778 } else { 1779 HANDLE_PENDING_EXCEPTION(); 1780 } 1781 break; 1782 } 1783 case Instruction::AGET_WIDE: { 1784 PREAMBLE(); 1785 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1786 if (UNLIKELY(a == NULL)) { 1787 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1788 HANDLE_PENDING_EXCEPTION(); 1789 break; 1790 } 1791 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1792 LongArray* array = a->AsLongArray(); 1793 if (LIKELY(array->IsValidIndex(index))) { 1794 shadow_frame.SetVRegLong(inst->VRegA_23x(), array->GetData()[index]); 1795 inst = inst->Next_2xx(); 1796 } else { 1797 HANDLE_PENDING_EXCEPTION(); 1798 } 1799 break; 1800 } 1801 case Instruction::AGET_OBJECT: { 1802 PREAMBLE(); 1803 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1804 if (UNLIKELY(a == NULL)) { 1805 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1806 HANDLE_PENDING_EXCEPTION(); 1807 break; 1808 } 1809 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1810 ObjectArray<Object>* array = a->AsObjectArray<Object>(); 1811 if (LIKELY(array->IsValidIndex(index))) { 1812 shadow_frame.SetVRegReference(inst->VRegA_23x(), array->GetWithoutChecks(index)); 1813 inst = inst->Next_2xx(); 1814 } else { 1815 HANDLE_PENDING_EXCEPTION(); 1816 } 1817 break; 1818 } 1819 case Instruction::APUT_BOOLEAN: { 1820 PREAMBLE(); 1821 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1822 if (UNLIKELY(a == NULL)) { 1823 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1824 HANDLE_PENDING_EXCEPTION(); 1825 break; 1826 } 1827 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x()); 1828 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1829 BooleanArray* array = a->AsBooleanArray(); 1830 if (LIKELY(array->IsValidIndex(index))) { 1831 array->GetData()[index] = val; 1832 inst = inst->Next_2xx(); 1833 } else { 1834 HANDLE_PENDING_EXCEPTION(); 1835 } 1836 break; 1837 } 1838 case Instruction::APUT_BYTE: { 1839 PREAMBLE(); 1840 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1841 if (UNLIKELY(a == NULL)) { 1842 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1843 HANDLE_PENDING_EXCEPTION(); 1844 break; 1845 } 1846 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x()); 1847 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1848 ByteArray* array = a->AsByteArray(); 1849 if (LIKELY(array->IsValidIndex(index))) { 1850 array->GetData()[index] = val; 1851 inst = inst->Next_2xx(); 1852 } else { 1853 HANDLE_PENDING_EXCEPTION(); 1854 } 1855 break; 1856 } 1857 case Instruction::APUT_CHAR: { 1858 PREAMBLE(); 1859 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1860 if (UNLIKELY(a == NULL)) { 1861 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1862 HANDLE_PENDING_EXCEPTION(); 1863 break; 1864 } 1865 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x()); 1866 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1867 CharArray* array = a->AsCharArray(); 1868 if (LIKELY(array->IsValidIndex(index))) { 1869 array->GetData()[index] = val; 1870 inst = inst->Next_2xx(); 1871 } else { 1872 HANDLE_PENDING_EXCEPTION(); 1873 } 1874 break; 1875 } 1876 case Instruction::APUT_SHORT: { 1877 PREAMBLE(); 1878 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1879 if (UNLIKELY(a == NULL)) { 1880 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1881 HANDLE_PENDING_EXCEPTION(); 1882 break; 1883 } 1884 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x()); 1885 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1886 ShortArray* array = a->AsShortArray(); 1887 if (LIKELY(array->IsValidIndex(index))) { 1888 array->GetData()[index] = val; 1889 inst = inst->Next_2xx(); 1890 } else { 1891 HANDLE_PENDING_EXCEPTION(); 1892 } 1893 break; 1894 } 1895 case Instruction::APUT: { 1896 PREAMBLE(); 1897 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1898 if (UNLIKELY(a == NULL)) { 1899 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1900 HANDLE_PENDING_EXCEPTION(); 1901 break; 1902 } 1903 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x()); 1904 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1905 IntArray* array = a->AsIntArray(); 1906 if (LIKELY(array->IsValidIndex(index))) { 1907 array->GetData()[index] = val; 1908 inst = inst->Next_2xx(); 1909 } else { 1910 HANDLE_PENDING_EXCEPTION(); 1911 } 1912 break; 1913 } 1914 case Instruction::APUT_WIDE: { 1915 PREAMBLE(); 1916 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1917 if (UNLIKELY(a == NULL)) { 1918 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1919 HANDLE_PENDING_EXCEPTION(); 1920 break; 1921 } 1922 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x()); 1923 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1924 LongArray* array = a->AsLongArray(); 1925 if (LIKELY(array->IsValidIndex(index))) { 1926 array->GetData()[index] = val; 1927 inst = inst->Next_2xx(); 1928 } else { 1929 HANDLE_PENDING_EXCEPTION(); 1930 } 1931 break; 1932 } 1933 case Instruction::APUT_OBJECT: { 1934 PREAMBLE(); 1935 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1936 if (UNLIKELY(a == NULL)) { 1937 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1938 HANDLE_PENDING_EXCEPTION(); 1939 break; 1940 } 1941 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1942 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x()); 1943 ObjectArray<Object>* array = a->AsObjectArray<Object>(); 1944 if (LIKELY(array->IsValidIndex(index) && array->CheckAssignable(val))) { 1945 array->SetWithoutChecks(index, val); 1946 inst = inst->Next_2xx(); 1947 } else { 1948 HANDLE_PENDING_EXCEPTION(); 1949 } 1950 break; 1951 } 1952 case Instruction::IGET_BOOLEAN: { 1953 PREAMBLE(); 1954 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst); 1955 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 1956 break; 1957 } 1958 case Instruction::IGET_BYTE: { 1959 PREAMBLE(); 1960 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst); 1961 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 1962 break; 1963 } 1964 case Instruction::IGET_CHAR: { 1965 PREAMBLE(); 1966 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst); 1967 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 1968 break; 1969 } 1970 case Instruction::IGET_SHORT: { 1971 PREAMBLE(); 1972 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst); 1973 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 1974 break; 1975 } 1976 case Instruction::IGET: { 1977 PREAMBLE(); 1978 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst); 1979 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 1980 break; 1981 } 1982 case Instruction::IGET_WIDE: { 1983 PREAMBLE(); 1984 bool success = DoFieldGet<InstancePrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst); 1985 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 1986 break; 1987 } 1988 case Instruction::IGET_OBJECT: { 1989 PREAMBLE(); 1990 bool success = DoFieldGet<InstanceObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst); 1991 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 1992 break; 1993 } 1994 case Instruction::IGET_QUICK: { 1995 PREAMBLE(); 1996 bool success = DoIGetQuick<Primitive::kPrimInt>(self, shadow_frame, inst); 1997 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 1998 break; 1999 } 2000 case Instruction::IGET_WIDE_QUICK: { 2001 PREAMBLE(); 2002 bool success = DoIGetQuick<Primitive::kPrimLong>(self, shadow_frame, inst); 2003 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2004 break; 2005 } 2006 case Instruction::IGET_OBJECT_QUICK: { 2007 PREAMBLE(); 2008 bool success = DoIGetQuick<Primitive::kPrimNot>(self, shadow_frame, inst); 2009 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2010 break; 2011 } 2012 case Instruction::SGET_BOOLEAN: { 2013 PREAMBLE(); 2014 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst); 2015 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2016 break; 2017 } 2018 case Instruction::SGET_BYTE: { 2019 PREAMBLE(); 2020 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst); 2021 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2022 break; 2023 } 2024 case Instruction::SGET_CHAR: { 2025 PREAMBLE(); 2026 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst); 2027 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2028 break; 2029 } 2030 case Instruction::SGET_SHORT: { 2031 PREAMBLE(); 2032 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst); 2033 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2034 break; 2035 } 2036 case Instruction::SGET: { 2037 PREAMBLE(); 2038 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst); 2039 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2040 break; 2041 } 2042 case Instruction::SGET_WIDE: { 2043 PREAMBLE(); 2044 bool success = DoFieldGet<StaticPrimitiveRead, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst); 2045 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2046 break; 2047 } 2048 case Instruction::SGET_OBJECT: { 2049 PREAMBLE(); 2050 bool success = DoFieldGet<StaticObjectRead, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst); 2051 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2052 break; 2053 } 2054 case Instruction::IPUT_BOOLEAN: { 2055 PREAMBLE(); 2056 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst); 2057 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2058 break; 2059 } 2060 case Instruction::IPUT_BYTE: { 2061 PREAMBLE(); 2062 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst); 2063 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2064 break; 2065 } 2066 case Instruction::IPUT_CHAR: { 2067 PREAMBLE(); 2068 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst); 2069 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2070 break; 2071 } 2072 case Instruction::IPUT_SHORT: { 2073 PREAMBLE(); 2074 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst); 2075 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2076 break; 2077 } 2078 case Instruction::IPUT: { 2079 PREAMBLE(); 2080 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst); 2081 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2082 break; 2083 } 2084 case Instruction::IPUT_WIDE: { 2085 PREAMBLE(); 2086 bool success = DoFieldPut<InstancePrimitiveWrite, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst); 2087 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2088 break; 2089 } 2090 case Instruction::IPUT_OBJECT: { 2091 PREAMBLE(); 2092 bool success = DoFieldPut<InstanceObjectWrite, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst); 2093 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2094 break; 2095 } 2096 case Instruction::IPUT_QUICK: { 2097 PREAMBLE(); 2098 bool success = DoIPutQuick<Primitive::kPrimInt>(self, shadow_frame, inst); 2099 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2100 break; 2101 } 2102 case Instruction::IPUT_WIDE_QUICK: { 2103 PREAMBLE(); 2104 bool success = DoIPutQuick<Primitive::kPrimLong>(self, shadow_frame, inst); 2105 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2106 break; 2107 } 2108 case Instruction::IPUT_OBJECT_QUICK: { 2109 PREAMBLE(); 2110 bool success = DoIPutQuick<Primitive::kPrimNot>(self, shadow_frame, inst); 2111 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2112 break; 2113 } 2114 case Instruction::SPUT_BOOLEAN: { 2115 PREAMBLE(); 2116 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimBoolean, do_access_check>(self, shadow_frame, inst); 2117 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2118 break; 2119 } 2120 case Instruction::SPUT_BYTE: { 2121 PREAMBLE(); 2122 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimByte, do_access_check>(self, shadow_frame, inst); 2123 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2124 break; 2125 } 2126 case Instruction::SPUT_CHAR: { 2127 PREAMBLE(); 2128 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimChar, do_access_check>(self, shadow_frame, inst); 2129 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2130 break; 2131 } 2132 case Instruction::SPUT_SHORT: { 2133 PREAMBLE(); 2134 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimShort, do_access_check>(self, shadow_frame, inst); 2135 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2136 break; 2137 } 2138 case Instruction::SPUT: { 2139 PREAMBLE(); 2140 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimInt, do_access_check>(self, shadow_frame, inst); 2141 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2142 break; 2143 } 2144 case Instruction::SPUT_WIDE: { 2145 PREAMBLE(); 2146 bool success = DoFieldPut<StaticPrimitiveWrite, Primitive::kPrimLong, do_access_check>(self, shadow_frame, inst); 2147 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2148 break; 2149 } 2150 case Instruction::SPUT_OBJECT: { 2151 PREAMBLE(); 2152 bool success = DoFieldPut<StaticObjectWrite, Primitive::kPrimNot, do_access_check>(self, shadow_frame, inst); 2153 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2154 break; 2155 } 2156 case Instruction::INVOKE_VIRTUAL: { 2157 PREAMBLE(); 2158 bool success = DoInvoke<kVirtual, false, do_access_check>(self, shadow_frame, inst, &result_register); 2159 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); 2160 break; 2161 } 2162 case Instruction::INVOKE_VIRTUAL_RANGE: { 2163 PREAMBLE(); 2164 bool success = DoInvoke<kVirtual, true, do_access_check>(self, shadow_frame, inst, &result_register); 2165 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); 2166 break; 2167 } 2168 case Instruction::INVOKE_SUPER: { 2169 PREAMBLE(); 2170 bool success = DoInvoke<kSuper, false, do_access_check>(self, shadow_frame, inst, &result_register); 2171 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); 2172 break; 2173 } 2174 case Instruction::INVOKE_SUPER_RANGE: { 2175 PREAMBLE(); 2176 bool success = DoInvoke<kSuper, true, do_access_check>(self, shadow_frame, inst, &result_register); 2177 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); 2178 break; 2179 } 2180 case Instruction::INVOKE_DIRECT: { 2181 PREAMBLE(); 2182 bool success = DoInvoke<kDirect, false, do_access_check>(self, shadow_frame, inst, &result_register); 2183 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); 2184 break; 2185 } 2186 case Instruction::INVOKE_DIRECT_RANGE: { 2187 PREAMBLE(); 2188 bool success = DoInvoke<kDirect, true, do_access_check>(self, shadow_frame, inst, &result_register); 2189 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); 2190 break; 2191 } 2192 case Instruction::INVOKE_INTERFACE: { 2193 PREAMBLE(); 2194 bool success = DoInvoke<kInterface, false, do_access_check>(self, shadow_frame, inst, &result_register); 2195 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); 2196 break; 2197 } 2198 case Instruction::INVOKE_INTERFACE_RANGE: { 2199 PREAMBLE(); 2200 bool success = DoInvoke<kInterface, true, do_access_check>(self, shadow_frame, inst, &result_register); 2201 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); 2202 break; 2203 } 2204 case Instruction::INVOKE_STATIC: { 2205 PREAMBLE(); 2206 bool success = DoInvoke<kStatic, false, do_access_check>(self, shadow_frame, inst, &result_register); 2207 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); 2208 break; 2209 } 2210 case Instruction::INVOKE_STATIC_RANGE: { 2211 PREAMBLE(); 2212 bool success = DoInvoke<kStatic, true, do_access_check>(self, shadow_frame, inst, &result_register); 2213 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); 2214 break; 2215 } 2216 case Instruction::INVOKE_VIRTUAL_QUICK: { 2217 PREAMBLE(); 2218 bool success = DoInvokeVirtualQuick<false>(self, shadow_frame, inst, &result_register); 2219 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); 2220 break; 2221 } 2222 case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: { 2223 PREAMBLE(); 2224 bool success = DoInvokeVirtualQuick<true>(self, shadow_frame, inst, &result_register); 2225 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_3xx); 2226 break; 2227 } 2228 case Instruction::NEG_INT: 2229 PREAMBLE(); 2230 shadow_frame.SetVReg(inst->VRegA_12x(), -shadow_frame.GetVReg(inst->VRegB_12x())); 2231 inst = inst->Next_1xx(); 2232 break; 2233 case Instruction::NOT_INT: 2234 PREAMBLE(); 2235 shadow_frame.SetVReg(inst->VRegA_12x(), ~shadow_frame.GetVReg(inst->VRegB_12x())); 2236 inst = inst->Next_1xx(); 2237 break; 2238 case Instruction::NEG_LONG: 2239 PREAMBLE(); 2240 shadow_frame.SetVRegLong(inst->VRegA_12x(), -shadow_frame.GetVRegLong(inst->VRegB_12x())); 2241 inst = inst->Next_1xx(); 2242 break; 2243 case Instruction::NOT_LONG: 2244 PREAMBLE(); 2245 shadow_frame.SetVRegLong(inst->VRegA_12x(), ~shadow_frame.GetVRegLong(inst->VRegB_12x())); 2246 inst = inst->Next_1xx(); 2247 break; 2248 case Instruction::NEG_FLOAT: 2249 PREAMBLE(); 2250 shadow_frame.SetVRegFloat(inst->VRegA_12x(), -shadow_frame.GetVRegFloat(inst->VRegB_12x())); 2251 inst = inst->Next_1xx(); 2252 break; 2253 case Instruction::NEG_DOUBLE: 2254 PREAMBLE(); 2255 shadow_frame.SetVRegDouble(inst->VRegA_12x(), -shadow_frame.GetVRegDouble(inst->VRegB_12x())); 2256 inst = inst->Next_1xx(); 2257 break; 2258 case Instruction::INT_TO_LONG: 2259 PREAMBLE(); 2260 shadow_frame.SetVRegLong(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x())); 2261 inst = inst->Next_1xx(); 2262 break; 2263 case Instruction::INT_TO_FLOAT: 2264 PREAMBLE(); 2265 shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x())); 2266 inst = inst->Next_1xx(); 2267 break; 2268 case Instruction::INT_TO_DOUBLE: 2269 PREAMBLE(); 2270 shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x())); 2271 inst = inst->Next_1xx(); 2272 break; 2273 case Instruction::LONG_TO_INT: 2274 PREAMBLE(); 2275 shadow_frame.SetVReg(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x())); 2276 inst = inst->Next_1xx(); 2277 break; 2278 case Instruction::LONG_TO_FLOAT: 2279 PREAMBLE(); 2280 shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x())); 2281 inst = inst->Next_1xx(); 2282 break; 2283 case Instruction::LONG_TO_DOUBLE: 2284 PREAMBLE(); 2285 shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x())); 2286 inst = inst->Next_1xx(); 2287 break; 2288 case Instruction::FLOAT_TO_INT: { 2289 PREAMBLE(); 2290 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x()); 2291 int32_t result; 2292 if (val != val) { 2293 result = 0; 2294 } else if (val > static_cast<float>(kMaxInt)) { 2295 result = kMaxInt; 2296 } else if (val < static_cast<float>(kMinInt)) { 2297 result = kMinInt; 2298 } else { 2299 result = val; 2300 } 2301 shadow_frame.SetVReg(inst->VRegA_12x(), result); 2302 inst = inst->Next_1xx(); 2303 break; 2304 } 2305 case Instruction::FLOAT_TO_LONG: { 2306 PREAMBLE(); 2307 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x()); 2308 int64_t result; 2309 if (val != val) { 2310 result = 0; 2311 } else if (val > static_cast<float>(kMaxLong)) { 2312 result = kMaxLong; 2313 } else if (val < static_cast<float>(kMinLong)) { 2314 result = kMinLong; 2315 } else { 2316 result = val; 2317 } 2318 shadow_frame.SetVRegLong(inst->VRegA_12x(), result); 2319 inst = inst->Next_1xx(); 2320 break; 2321 } 2322 case Instruction::FLOAT_TO_DOUBLE: 2323 PREAMBLE(); 2324 shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVRegFloat(inst->VRegB_12x())); 2325 inst = inst->Next_1xx(); 2326 break; 2327 case Instruction::DOUBLE_TO_INT: { 2328 PREAMBLE(); 2329 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x()); 2330 int32_t result; 2331 if (val != val) { 2332 result = 0; 2333 } else if (val > static_cast<double>(kMaxInt)) { 2334 result = kMaxInt; 2335 } else if (val < static_cast<double>(kMinInt)) { 2336 result = kMinInt; 2337 } else { 2338 result = val; 2339 } 2340 shadow_frame.SetVReg(inst->VRegA_12x(), result); 2341 inst = inst->Next_1xx(); 2342 break; 2343 } 2344 case Instruction::DOUBLE_TO_LONG: { 2345 PREAMBLE(); 2346 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x()); 2347 int64_t result; 2348 if (val != val) { 2349 result = 0; 2350 } else if (val > static_cast<double>(kMaxLong)) { 2351 result = kMaxLong; 2352 } else if (val < static_cast<double>(kMinLong)) { 2353 result = kMinLong; 2354 } else { 2355 result = val; 2356 } 2357 shadow_frame.SetVRegLong(inst->VRegA_12x(), result); 2358 inst = inst->Next_1xx(); 2359 break; 2360 } 2361 case Instruction::DOUBLE_TO_FLOAT: 2362 PREAMBLE(); 2363 shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVRegDouble(inst->VRegB_12x())); 2364 inst = inst->Next_1xx(); 2365 break; 2366 case Instruction::INT_TO_BYTE: 2367 PREAMBLE(); 2368 shadow_frame.SetVReg(inst->VRegA_12x(), 2369 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x()))); 2370 inst = inst->Next_1xx(); 2371 break; 2372 case Instruction::INT_TO_CHAR: 2373 PREAMBLE(); 2374 shadow_frame.SetVReg(inst->VRegA_12x(), 2375 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x()))); 2376 inst = inst->Next_1xx(); 2377 break; 2378 case Instruction::INT_TO_SHORT: 2379 PREAMBLE(); 2380 shadow_frame.SetVReg(inst->VRegA_12x(), 2381 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x()))); 2382 inst = inst->Next_1xx(); 2383 break; 2384 case Instruction::ADD_INT: 2385 PREAMBLE(); 2386 shadow_frame.SetVReg(inst->VRegA_23x(), 2387 shadow_frame.GetVReg(inst->VRegB_23x()) + 2388 shadow_frame.GetVReg(inst->VRegC_23x())); 2389 inst = inst->Next_2xx(); 2390 break; 2391 case Instruction::SUB_INT: 2392 PREAMBLE(); 2393 shadow_frame.SetVReg(inst->VRegA_23x(), 2394 shadow_frame.GetVReg(inst->VRegB_23x()) - 2395 shadow_frame.GetVReg(inst->VRegC_23x())); 2396 inst = inst->Next_2xx(); 2397 break; 2398 case Instruction::MUL_INT: 2399 PREAMBLE(); 2400 shadow_frame.SetVReg(inst->VRegA_23x(), 2401 shadow_frame.GetVReg(inst->VRegB_23x()) * 2402 shadow_frame.GetVReg(inst->VRegC_23x())); 2403 inst = inst->Next_2xx(); 2404 break; 2405 case Instruction::DIV_INT: { 2406 PREAMBLE(); 2407 bool success = DoIntDivide(shadow_frame, inst->VRegA_23x(), 2408 shadow_frame.GetVReg(inst->VRegB_23x()), 2409 shadow_frame.GetVReg(inst->VRegC_23x())); 2410 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2411 break; 2412 } 2413 case Instruction::REM_INT: { 2414 PREAMBLE(); 2415 bool success = DoIntRemainder(shadow_frame, inst->VRegA_23x(), 2416 shadow_frame.GetVReg(inst->VRegB_23x()), 2417 shadow_frame.GetVReg(inst->VRegC_23x())); 2418 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2419 break; 2420 } 2421 case Instruction::SHL_INT: 2422 PREAMBLE(); 2423 shadow_frame.SetVReg(inst->VRegA_23x(), 2424 shadow_frame.GetVReg(inst->VRegB_23x()) << 2425 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f)); 2426 inst = inst->Next_2xx(); 2427 break; 2428 case Instruction::SHR_INT: 2429 PREAMBLE(); 2430 shadow_frame.SetVReg(inst->VRegA_23x(), 2431 shadow_frame.GetVReg(inst->VRegB_23x()) >> 2432 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f)); 2433 inst = inst->Next_2xx(); 2434 break; 2435 case Instruction::USHR_INT: 2436 PREAMBLE(); 2437 shadow_frame.SetVReg(inst->VRegA_23x(), 2438 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >> 2439 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f)); 2440 inst = inst->Next_2xx(); 2441 break; 2442 case Instruction::AND_INT: 2443 PREAMBLE(); 2444 shadow_frame.SetVReg(inst->VRegA_23x(), 2445 shadow_frame.GetVReg(inst->VRegB_23x()) & 2446 shadow_frame.GetVReg(inst->VRegC_23x())); 2447 inst = inst->Next_2xx(); 2448 break; 2449 case Instruction::OR_INT: 2450 PREAMBLE(); 2451 shadow_frame.SetVReg(inst->VRegA_23x(), 2452 shadow_frame.GetVReg(inst->VRegB_23x()) | 2453 shadow_frame.GetVReg(inst->VRegC_23x())); 2454 inst = inst->Next_2xx(); 2455 break; 2456 case Instruction::XOR_INT: 2457 PREAMBLE(); 2458 shadow_frame.SetVReg(inst->VRegA_23x(), 2459 shadow_frame.GetVReg(inst->VRegB_23x()) ^ 2460 shadow_frame.GetVReg(inst->VRegC_23x())); 2461 inst = inst->Next_2xx(); 2462 break; 2463 case Instruction::ADD_LONG: 2464 PREAMBLE(); 2465 shadow_frame.SetVRegLong(inst->VRegA_23x(), 2466 shadow_frame.GetVRegLong(inst->VRegB_23x()) + 2467 shadow_frame.GetVRegLong(inst->VRegC_23x())); 2468 inst = inst->Next_2xx(); 2469 break; 2470 case Instruction::SUB_LONG: 2471 PREAMBLE(); 2472 shadow_frame.SetVRegLong(inst->VRegA_23x(), 2473 shadow_frame.GetVRegLong(inst->VRegB_23x()) - 2474 shadow_frame.GetVRegLong(inst->VRegC_23x())); 2475 inst = inst->Next_2xx(); 2476 break; 2477 case Instruction::MUL_LONG: 2478 PREAMBLE(); 2479 shadow_frame.SetVRegLong(inst->VRegA_23x(), 2480 shadow_frame.GetVRegLong(inst->VRegB_23x()) * 2481 shadow_frame.GetVRegLong(inst->VRegC_23x())); 2482 inst = inst->Next_2xx(); 2483 break; 2484 case Instruction::DIV_LONG: 2485 PREAMBLE(); 2486 DoLongDivide(shadow_frame, inst->VRegA_23x(), 2487 shadow_frame.GetVRegLong(inst->VRegB_23x()), 2488 shadow_frame.GetVRegLong(inst->VRegC_23x())); 2489 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx); 2490 break; 2491 case Instruction::REM_LONG: 2492 PREAMBLE(); 2493 DoLongRemainder(shadow_frame, inst->VRegA_23x(), 2494 shadow_frame.GetVRegLong(inst->VRegB_23x()), 2495 shadow_frame.GetVRegLong(inst->VRegC_23x())); 2496 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_2xx); 2497 break; 2498 case Instruction::AND_LONG: 2499 PREAMBLE(); 2500 shadow_frame.SetVRegLong(inst->VRegA_23x(), 2501 shadow_frame.GetVRegLong(inst->VRegB_23x()) & 2502 shadow_frame.GetVRegLong(inst->VRegC_23x())); 2503 inst = inst->Next_2xx(); 2504 break; 2505 case Instruction::OR_LONG: 2506 PREAMBLE(); 2507 shadow_frame.SetVRegLong(inst->VRegA_23x(), 2508 shadow_frame.GetVRegLong(inst->VRegB_23x()) | 2509 shadow_frame.GetVRegLong(inst->VRegC_23x())); 2510 inst = inst->Next_2xx(); 2511 break; 2512 case Instruction::XOR_LONG: 2513 PREAMBLE(); 2514 shadow_frame.SetVRegLong(inst->VRegA_23x(), 2515 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^ 2516 shadow_frame.GetVRegLong(inst->VRegC_23x())); 2517 inst = inst->Next_2xx(); 2518 break; 2519 case Instruction::SHL_LONG: 2520 PREAMBLE(); 2521 shadow_frame.SetVRegLong(inst->VRegA_23x(), 2522 shadow_frame.GetVRegLong(inst->VRegB_23x()) << 2523 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f)); 2524 inst = inst->Next_2xx(); 2525 break; 2526 case Instruction::SHR_LONG: 2527 PREAMBLE(); 2528 shadow_frame.SetVRegLong(inst->VRegA_23x(), 2529 shadow_frame.GetVRegLong(inst->VRegB_23x()) >> 2530 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f)); 2531 inst = inst->Next_2xx(); 2532 break; 2533 case Instruction::USHR_LONG: 2534 PREAMBLE(); 2535 shadow_frame.SetVRegLong(inst->VRegA_23x(), 2536 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >> 2537 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f)); 2538 inst = inst->Next_2xx(); 2539 break; 2540 case Instruction::ADD_FLOAT: 2541 PREAMBLE(); 2542 shadow_frame.SetVRegFloat(inst->VRegA_23x(), 2543 shadow_frame.GetVRegFloat(inst->VRegB_23x()) + 2544 shadow_frame.GetVRegFloat(inst->VRegC_23x())); 2545 inst = inst->Next_2xx(); 2546 break; 2547 case Instruction::SUB_FLOAT: 2548 PREAMBLE(); 2549 shadow_frame.SetVRegFloat(inst->VRegA_23x(), 2550 shadow_frame.GetVRegFloat(inst->VRegB_23x()) - 2551 shadow_frame.GetVRegFloat(inst->VRegC_23x())); 2552 inst = inst->Next_2xx(); 2553 break; 2554 case Instruction::MUL_FLOAT: 2555 PREAMBLE(); 2556 shadow_frame.SetVRegFloat(inst->VRegA_23x(), 2557 shadow_frame.GetVRegFloat(inst->VRegB_23x()) * 2558 shadow_frame.GetVRegFloat(inst->VRegC_23x())); 2559 inst = inst->Next_2xx(); 2560 break; 2561 case Instruction::DIV_FLOAT: 2562 PREAMBLE(); 2563 shadow_frame.SetVRegFloat(inst->VRegA_23x(), 2564 shadow_frame.GetVRegFloat(inst->VRegB_23x()) / 2565 shadow_frame.GetVRegFloat(inst->VRegC_23x())); 2566 inst = inst->Next_2xx(); 2567 break; 2568 case Instruction::REM_FLOAT: 2569 PREAMBLE(); 2570 shadow_frame.SetVRegFloat(inst->VRegA_23x(), 2571 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()), 2572 shadow_frame.GetVRegFloat(inst->VRegC_23x()))); 2573 inst = inst->Next_2xx(); 2574 break; 2575 case Instruction::ADD_DOUBLE: 2576 PREAMBLE(); 2577 shadow_frame.SetVRegDouble(inst->VRegA_23x(), 2578 shadow_frame.GetVRegDouble(inst->VRegB_23x()) + 2579 shadow_frame.GetVRegDouble(inst->VRegC_23x())); 2580 inst = inst->Next_2xx(); 2581 break; 2582 case Instruction::SUB_DOUBLE: 2583 PREAMBLE(); 2584 shadow_frame.SetVRegDouble(inst->VRegA_23x(), 2585 shadow_frame.GetVRegDouble(inst->VRegB_23x()) - 2586 shadow_frame.GetVRegDouble(inst->VRegC_23x())); 2587 inst = inst->Next_2xx(); 2588 break; 2589 case Instruction::MUL_DOUBLE: 2590 PREAMBLE(); 2591 shadow_frame.SetVRegDouble(inst->VRegA_23x(), 2592 shadow_frame.GetVRegDouble(inst->VRegB_23x()) * 2593 shadow_frame.GetVRegDouble(inst->VRegC_23x())); 2594 inst = inst->Next_2xx(); 2595 break; 2596 case Instruction::DIV_DOUBLE: 2597 PREAMBLE(); 2598 shadow_frame.SetVRegDouble(inst->VRegA_23x(), 2599 shadow_frame.GetVRegDouble(inst->VRegB_23x()) / 2600 shadow_frame.GetVRegDouble(inst->VRegC_23x())); 2601 inst = inst->Next_2xx(); 2602 break; 2603 case Instruction::REM_DOUBLE: 2604 PREAMBLE(); 2605 shadow_frame.SetVRegDouble(inst->VRegA_23x(), 2606 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()), 2607 shadow_frame.GetVRegDouble(inst->VRegC_23x()))); 2608 inst = inst->Next_2xx(); 2609 break; 2610 case Instruction::ADD_INT_2ADDR: { 2611 PREAMBLE(); 2612 uint4_t vregA = inst->VRegA_12x(); 2613 shadow_frame.SetVReg(vregA, 2614 shadow_frame.GetVReg(vregA) + 2615 shadow_frame.GetVReg(inst->VRegB_12x())); 2616 inst = inst->Next_1xx(); 2617 break; 2618 } 2619 case Instruction::SUB_INT_2ADDR: { 2620 PREAMBLE(); 2621 uint4_t vregA = inst->VRegA_12x(); 2622 shadow_frame.SetVReg(vregA, 2623 shadow_frame.GetVReg(vregA) - 2624 shadow_frame.GetVReg(inst->VRegB_12x())); 2625 inst = inst->Next_1xx(); 2626 break; 2627 } 2628 case Instruction::MUL_INT_2ADDR: { 2629 PREAMBLE(); 2630 uint4_t vregA = inst->VRegA_12x(); 2631 shadow_frame.SetVReg(vregA, 2632 shadow_frame.GetVReg(vregA) * 2633 shadow_frame.GetVReg(inst->VRegB_12x())); 2634 inst = inst->Next_1xx(); 2635 break; 2636 } 2637 case Instruction::DIV_INT_2ADDR: { 2638 PREAMBLE(); 2639 uint4_t vregA = inst->VRegA_12x(); 2640 bool success = DoIntDivide(shadow_frame, vregA, shadow_frame.GetVReg(vregA), 2641 shadow_frame.GetVReg(inst->VRegB_12x())); 2642 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx); 2643 break; 2644 } 2645 case Instruction::REM_INT_2ADDR: { 2646 PREAMBLE(); 2647 uint4_t vregA = inst->VRegA_12x(); 2648 bool success = DoIntRemainder(shadow_frame, vregA, shadow_frame.GetVReg(vregA), 2649 shadow_frame.GetVReg(inst->VRegB_12x())); 2650 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_1xx); 2651 break; 2652 } 2653 case Instruction::SHL_INT_2ADDR: { 2654 PREAMBLE(); 2655 uint4_t vregA = inst->VRegA_12x(); 2656 shadow_frame.SetVReg(vregA, 2657 shadow_frame.GetVReg(vregA) << 2658 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f)); 2659 inst = inst->Next_1xx(); 2660 break; 2661 } 2662 case Instruction::SHR_INT_2ADDR: { 2663 PREAMBLE(); 2664 uint4_t vregA = inst->VRegA_12x(); 2665 shadow_frame.SetVReg(vregA, 2666 shadow_frame.GetVReg(vregA) >> 2667 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f)); 2668 inst = inst->Next_1xx(); 2669 break; 2670 } 2671 case Instruction::USHR_INT_2ADDR: { 2672 PREAMBLE(); 2673 uint4_t vregA = inst->VRegA_12x(); 2674 shadow_frame.SetVReg(vregA, 2675 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >> 2676 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f)); 2677 inst = inst->Next_1xx(); 2678 break; 2679 } 2680 case Instruction::AND_INT_2ADDR: { 2681 PREAMBLE(); 2682 uint4_t vregA = inst->VRegA_12x(); 2683 shadow_frame.SetVReg(vregA, 2684 shadow_frame.GetVReg(vregA) & 2685 shadow_frame.GetVReg(inst->VRegB_12x())); 2686 inst = inst->Next_1xx(); 2687 break; 2688 } 2689 case Instruction::OR_INT_2ADDR: { 2690 PREAMBLE(); 2691 uint4_t vregA = inst->VRegA_12x(); 2692 shadow_frame.SetVReg(vregA, 2693 shadow_frame.GetVReg(vregA) | 2694 shadow_frame.GetVReg(inst->VRegB_12x())); 2695 inst = inst->Next_1xx(); 2696 break; 2697 } 2698 case Instruction::XOR_INT_2ADDR: { 2699 PREAMBLE(); 2700 uint4_t vregA = inst->VRegA_12x(); 2701 shadow_frame.SetVReg(vregA, 2702 shadow_frame.GetVReg(vregA) ^ 2703 shadow_frame.GetVReg(inst->VRegB_12x())); 2704 inst = inst->Next_1xx(); 2705 break; 2706 } 2707 case Instruction::ADD_LONG_2ADDR: { 2708 PREAMBLE(); 2709 uint4_t vregA = inst->VRegA_12x(); 2710 shadow_frame.SetVRegLong(vregA, 2711 shadow_frame.GetVRegLong(vregA) + 2712 shadow_frame.GetVRegLong(inst->VRegB_12x())); 2713 inst = inst->Next_1xx(); 2714 break; 2715 } 2716 case Instruction::SUB_LONG_2ADDR: { 2717 PREAMBLE(); 2718 uint4_t vregA = inst->VRegA_12x(); 2719 shadow_frame.SetVRegLong(vregA, 2720 shadow_frame.GetVRegLong(vregA) - 2721 shadow_frame.GetVRegLong(inst->VRegB_12x())); 2722 inst = inst->Next_1xx(); 2723 break; 2724 } 2725 case Instruction::MUL_LONG_2ADDR: { 2726 PREAMBLE(); 2727 uint4_t vregA = inst->VRegA_12x(); 2728 shadow_frame.SetVRegLong(vregA, 2729 shadow_frame.GetVRegLong(vregA) * 2730 shadow_frame.GetVRegLong(inst->VRegB_12x())); 2731 inst = inst->Next_1xx(); 2732 break; 2733 } 2734 case Instruction::DIV_LONG_2ADDR: { 2735 PREAMBLE(); 2736 uint4_t vregA = inst->VRegA_12x(); 2737 DoLongDivide(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA), 2738 shadow_frame.GetVRegLong(inst->VRegB_12x())); 2739 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx); 2740 break; 2741 } 2742 case Instruction::REM_LONG_2ADDR: { 2743 PREAMBLE(); 2744 uint4_t vregA = inst->VRegA_12x(); 2745 DoLongRemainder(shadow_frame, vregA, shadow_frame.GetVRegLong(vregA), 2746 shadow_frame.GetVRegLong(inst->VRegB_12x())); 2747 POSSIBLY_HANDLE_PENDING_EXCEPTION(self->IsExceptionPending(), Next_1xx); 2748 break; 2749 } 2750 case Instruction::AND_LONG_2ADDR: { 2751 PREAMBLE(); 2752 uint4_t vregA = inst->VRegA_12x(); 2753 shadow_frame.SetVRegLong(vregA, 2754 shadow_frame.GetVRegLong(vregA) & 2755 shadow_frame.GetVRegLong(inst->VRegB_12x())); 2756 inst = inst->Next_1xx(); 2757 break; 2758 } 2759 case Instruction::OR_LONG_2ADDR: { 2760 PREAMBLE(); 2761 uint4_t vregA = inst->VRegA_12x(); 2762 shadow_frame.SetVRegLong(vregA, 2763 shadow_frame.GetVRegLong(vregA) | 2764 shadow_frame.GetVRegLong(inst->VRegB_12x())); 2765 inst = inst->Next_1xx(); 2766 break; 2767 } 2768 case Instruction::XOR_LONG_2ADDR: { 2769 PREAMBLE(); 2770 uint4_t vregA = inst->VRegA_12x(); 2771 shadow_frame.SetVRegLong(vregA, 2772 shadow_frame.GetVRegLong(vregA) ^ 2773 shadow_frame.GetVRegLong(inst->VRegB_12x())); 2774 inst = inst->Next_1xx(); 2775 break; 2776 } 2777 case Instruction::SHL_LONG_2ADDR: { 2778 PREAMBLE(); 2779 uint4_t vregA = inst->VRegA_12x(); 2780 shadow_frame.SetVRegLong(vregA, 2781 shadow_frame.GetVRegLong(vregA) << 2782 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f)); 2783 inst = inst->Next_1xx(); 2784 break; 2785 } 2786 case Instruction::SHR_LONG_2ADDR: { 2787 PREAMBLE(); 2788 uint4_t vregA = inst->VRegA_12x(); 2789 shadow_frame.SetVRegLong(vregA, 2790 shadow_frame.GetVRegLong(vregA) >> 2791 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f)); 2792 inst = inst->Next_1xx(); 2793 break; 2794 } 2795 case Instruction::USHR_LONG_2ADDR: { 2796 PREAMBLE(); 2797 uint4_t vregA = inst->VRegA_12x(); 2798 shadow_frame.SetVRegLong(vregA, 2799 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >> 2800 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f)); 2801 inst = inst->Next_1xx(); 2802 break; 2803 } 2804 case Instruction::ADD_FLOAT_2ADDR: { 2805 PREAMBLE(); 2806 uint4_t vregA = inst->VRegA_12x(); 2807 shadow_frame.SetVRegFloat(vregA, 2808 shadow_frame.GetVRegFloat(vregA) + 2809 shadow_frame.GetVRegFloat(inst->VRegB_12x())); 2810 inst = inst->Next_1xx(); 2811 break; 2812 } 2813 case Instruction::SUB_FLOAT_2ADDR: { 2814 PREAMBLE(); 2815 uint4_t vregA = inst->VRegA_12x(); 2816 shadow_frame.SetVRegFloat(vregA, 2817 shadow_frame.GetVRegFloat(vregA) - 2818 shadow_frame.GetVRegFloat(inst->VRegB_12x())); 2819 inst = inst->Next_1xx(); 2820 break; 2821 } 2822 case Instruction::MUL_FLOAT_2ADDR: { 2823 PREAMBLE(); 2824 uint4_t vregA = inst->VRegA_12x(); 2825 shadow_frame.SetVRegFloat(vregA, 2826 shadow_frame.GetVRegFloat(vregA) * 2827 shadow_frame.GetVRegFloat(inst->VRegB_12x())); 2828 inst = inst->Next_1xx(); 2829 break; 2830 } 2831 case Instruction::DIV_FLOAT_2ADDR: { 2832 PREAMBLE(); 2833 uint4_t vregA = inst->VRegA_12x(); 2834 shadow_frame.SetVRegFloat(vregA, 2835 shadow_frame.GetVRegFloat(vregA) / 2836 shadow_frame.GetVRegFloat(inst->VRegB_12x())); 2837 inst = inst->Next_1xx(); 2838 break; 2839 } 2840 case Instruction::REM_FLOAT_2ADDR: { 2841 PREAMBLE(); 2842 uint4_t vregA = inst->VRegA_12x(); 2843 shadow_frame.SetVRegFloat(vregA, 2844 fmodf(shadow_frame.GetVRegFloat(vregA), 2845 shadow_frame.GetVRegFloat(inst->VRegB_12x()))); 2846 inst = inst->Next_1xx(); 2847 break; 2848 } 2849 case Instruction::ADD_DOUBLE_2ADDR: { 2850 PREAMBLE(); 2851 uint4_t vregA = inst->VRegA_12x(); 2852 shadow_frame.SetVRegDouble(vregA, 2853 shadow_frame.GetVRegDouble(vregA) + 2854 shadow_frame.GetVRegDouble(inst->VRegB_12x())); 2855 inst = inst->Next_1xx(); 2856 break; 2857 } 2858 case Instruction::SUB_DOUBLE_2ADDR: { 2859 PREAMBLE(); 2860 uint4_t vregA = inst->VRegA_12x(); 2861 shadow_frame.SetVRegDouble(vregA, 2862 shadow_frame.GetVRegDouble(vregA) - 2863 shadow_frame.GetVRegDouble(inst->VRegB_12x())); 2864 inst = inst->Next_1xx(); 2865 break; 2866 } 2867 case Instruction::MUL_DOUBLE_2ADDR: { 2868 PREAMBLE(); 2869 uint4_t vregA = inst->VRegA_12x(); 2870 shadow_frame.SetVRegDouble(vregA, 2871 shadow_frame.GetVRegDouble(vregA) * 2872 shadow_frame.GetVRegDouble(inst->VRegB_12x())); 2873 inst = inst->Next_1xx(); 2874 break; 2875 } 2876 case Instruction::DIV_DOUBLE_2ADDR: { 2877 PREAMBLE(); 2878 uint4_t vregA = inst->VRegA_12x(); 2879 shadow_frame.SetVRegDouble(vregA, 2880 shadow_frame.GetVRegDouble(vregA) / 2881 shadow_frame.GetVRegDouble(inst->VRegB_12x())); 2882 inst = inst->Next_1xx(); 2883 break; 2884 } 2885 case Instruction::REM_DOUBLE_2ADDR: { 2886 PREAMBLE(); 2887 uint4_t vregA = inst->VRegA_12x(); 2888 shadow_frame.SetVRegDouble(vregA, 2889 fmod(shadow_frame.GetVRegDouble(vregA), 2890 shadow_frame.GetVRegDouble(inst->VRegB_12x()))); 2891 inst = inst->Next_1xx(); 2892 break; 2893 } 2894 case Instruction::ADD_INT_LIT16: 2895 PREAMBLE(); 2896 shadow_frame.SetVReg(inst->VRegA_22s(), 2897 shadow_frame.GetVReg(inst->VRegB_22s()) + 2898 inst->VRegC_22s()); 2899 inst = inst->Next_2xx(); 2900 break; 2901 case Instruction::RSUB_INT: 2902 PREAMBLE(); 2903 shadow_frame.SetVReg(inst->VRegA_22s(), 2904 inst->VRegC_22s() - 2905 shadow_frame.GetVReg(inst->VRegB_22s())); 2906 inst = inst->Next_2xx(); 2907 break; 2908 case Instruction::MUL_INT_LIT16: 2909 PREAMBLE(); 2910 shadow_frame.SetVReg(inst->VRegA_22s(), 2911 shadow_frame.GetVReg(inst->VRegB_22s()) * 2912 inst->VRegC_22s()); 2913 inst = inst->Next_2xx(); 2914 break; 2915 case Instruction::DIV_INT_LIT16: { 2916 PREAMBLE(); 2917 bool success = DoIntDivide(shadow_frame, inst->VRegA_22s(), 2918 shadow_frame.GetVReg(inst->VRegB_22s()), inst->VRegC_22s()); 2919 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2920 break; 2921 } 2922 case Instruction::REM_INT_LIT16: { 2923 PREAMBLE(); 2924 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22s(), 2925 shadow_frame.GetVReg(inst->VRegB_22s()), inst->VRegC_22s()); 2926 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2927 break; 2928 } 2929 case Instruction::AND_INT_LIT16: 2930 PREAMBLE(); 2931 shadow_frame.SetVReg(inst->VRegA_22s(), 2932 shadow_frame.GetVReg(inst->VRegB_22s()) & 2933 inst->VRegC_22s()); 2934 inst = inst->Next_2xx(); 2935 break; 2936 case Instruction::OR_INT_LIT16: 2937 PREAMBLE(); 2938 shadow_frame.SetVReg(inst->VRegA_22s(), 2939 shadow_frame.GetVReg(inst->VRegB_22s()) | 2940 inst->VRegC_22s()); 2941 inst = inst->Next_2xx(); 2942 break; 2943 case Instruction::XOR_INT_LIT16: 2944 PREAMBLE(); 2945 shadow_frame.SetVReg(inst->VRegA_22s(), 2946 shadow_frame.GetVReg(inst->VRegB_22s()) ^ 2947 inst->VRegC_22s()); 2948 inst = inst->Next_2xx(); 2949 break; 2950 case Instruction::ADD_INT_LIT8: 2951 PREAMBLE(); 2952 shadow_frame.SetVReg(inst->VRegA_22b(), 2953 shadow_frame.GetVReg(inst->VRegB_22b()) + 2954 inst->VRegC_22b()); 2955 inst = inst->Next_2xx(); 2956 break; 2957 case Instruction::RSUB_INT_LIT8: 2958 PREAMBLE(); 2959 shadow_frame.SetVReg(inst->VRegA_22b(), 2960 inst->VRegC_22b() - 2961 shadow_frame.GetVReg(inst->VRegB_22b())); 2962 inst = inst->Next_2xx(); 2963 break; 2964 case Instruction::MUL_INT_LIT8: 2965 PREAMBLE(); 2966 shadow_frame.SetVReg(inst->VRegA_22b(), 2967 shadow_frame.GetVReg(inst->VRegB_22b()) * 2968 inst->VRegC_22b()); 2969 inst = inst->Next_2xx(); 2970 break; 2971 case Instruction::DIV_INT_LIT8: { 2972 PREAMBLE(); 2973 bool success = DoIntDivide(shadow_frame, inst->VRegA_22b(), 2974 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()); 2975 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2976 break; 2977 } 2978 case Instruction::REM_INT_LIT8: { 2979 PREAMBLE(); 2980 bool success = DoIntRemainder(shadow_frame, inst->VRegA_22b(), 2981 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()); 2982 POSSIBLY_HANDLE_PENDING_EXCEPTION(!success, Next_2xx); 2983 break; 2984 } 2985 case Instruction::AND_INT_LIT8: 2986 PREAMBLE(); 2987 shadow_frame.SetVReg(inst->VRegA_22b(), 2988 shadow_frame.GetVReg(inst->VRegB_22b()) & 2989 inst->VRegC_22b()); 2990 inst = inst->Next_2xx(); 2991 break; 2992 case Instruction::OR_INT_LIT8: 2993 PREAMBLE(); 2994 shadow_frame.SetVReg(inst->VRegA_22b(), 2995 shadow_frame.GetVReg(inst->VRegB_22b()) | 2996 inst->VRegC_22b()); 2997 inst = inst->Next_2xx(); 2998 break; 2999 case Instruction::XOR_INT_LIT8: 3000 PREAMBLE(); 3001 shadow_frame.SetVReg(inst->VRegA_22b(), 3002 shadow_frame.GetVReg(inst->VRegB_22b()) ^ 3003 inst->VRegC_22b()); 3004 inst = inst->Next_2xx(); 3005 break; 3006 case Instruction::SHL_INT_LIT8: 3007 PREAMBLE(); 3008 shadow_frame.SetVReg(inst->VRegA_22b(), 3009 shadow_frame.GetVReg(inst->VRegB_22b()) << 3010 (inst->VRegC_22b() & 0x1f)); 3011 inst = inst->Next_2xx(); 3012 break; 3013 case Instruction::SHR_INT_LIT8: 3014 PREAMBLE(); 3015 shadow_frame.SetVReg(inst->VRegA_22b(), 3016 shadow_frame.GetVReg(inst->VRegB_22b()) >> 3017 (inst->VRegC_22b() & 0x1f)); 3018 inst = inst->Next_2xx(); 3019 break; 3020 case Instruction::USHR_INT_LIT8: 3021 PREAMBLE(); 3022 shadow_frame.SetVReg(inst->VRegA_22b(), 3023 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >> 3024 (inst->VRegC_22b() & 0x1f)); 3025 inst = inst->Next_2xx(); 3026 break; 3027 case Instruction::UNUSED_3E ... Instruction::UNUSED_43: 3028 case Instruction::UNUSED_EB ... Instruction::UNUSED_FF: 3029 case Instruction::UNUSED_79: 3030 case Instruction::UNUSED_7A: 3031 UnexpectedOpcode(inst, mh); 3032 } 3033 } 3034} // NOLINT(readability/fn_size) 3035 3036static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 3037 ShadowFrame& shadow_frame, JValue result_register) 3038 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 3039 3040static inline JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 3041 ShadowFrame& shadow_frame, JValue result_register) { 3042 DCHECK(shadow_frame.GetMethod() == mh.GetMethod() || 3043 shadow_frame.GetMethod()->GetDeclaringClass()->IsProxyClass()); 3044 DCHECK(!shadow_frame.GetMethod()->IsAbstract()); 3045 DCHECK(!shadow_frame.GetMethod()->IsNative()); 3046 if (shadow_frame.GetMethod()->IsPreverified()) { 3047 // Enter the "without access check" interpreter. 3048 return ExecuteImpl<false>(self, mh, code_item, shadow_frame, result_register); 3049 } else { 3050 // Enter the "with access check" interpreter. 3051 return ExecuteImpl<true>(self, mh, code_item, shadow_frame, result_register); 3052 } 3053} 3054 3055void EnterInterpreterFromInvoke(Thread* self, AbstractMethod* method, Object* receiver, 3056 uint32_t* args, JValue* result) { 3057 DCHECK_EQ(self, Thread::Current()); 3058 if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) { 3059 ThrowStackOverflowError(self); 3060 return; 3061 } 3062 3063 MethodHelper mh(method); 3064 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 3065 uint16_t num_regs; 3066 uint16_t num_ins; 3067 if (code_item != NULL) { 3068 num_regs = code_item->registers_size_; 3069 num_ins = code_item->ins_size_; 3070 } else if (method->IsAbstract()) { 3071 ThrowAbstractMethodError(method); 3072 return; 3073 } else { 3074 DCHECK(method->IsNative()); 3075 num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty()); 3076 if (!method->IsStatic()) { 3077 num_regs++; 3078 num_ins++; 3079 } 3080 } 3081 // Set up shadow frame with matching number of reference slots to vregs. 3082 ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame(); 3083 void* memory = alloca(ShadowFrame::ComputeSize(num_regs)); 3084 ShadowFrame* shadow_frame(ShadowFrame::Create(num_regs, last_shadow_frame, method, 0, memory)); 3085 self->PushShadowFrame(shadow_frame); 3086 size_t cur_reg = num_regs - num_ins; 3087 if (!method->IsStatic()) { 3088 CHECK(receiver != NULL); 3089 shadow_frame->SetVRegReference(cur_reg, receiver); 3090 ++cur_reg; 3091 } else if (UNLIKELY(!method->GetDeclaringClass()->IsInitializing())) { 3092 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 3093 if (UNLIKELY(!class_linker->EnsureInitialized(method->GetDeclaringClass(), 3094 true, true))) { 3095 CHECK(self->IsExceptionPending()); 3096 self->PopShadowFrame(); 3097 return; 3098 } 3099 CHECK(method->GetDeclaringClass()->IsInitializing()); 3100 } 3101 const char* shorty = mh.GetShorty(); 3102 for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) { 3103 DCHECK_LT(shorty_pos + 1, mh.GetShortyLength()); 3104 switch (shorty[shorty_pos + 1]) { 3105 case 'L': { 3106 Object* o = reinterpret_cast<Object*>(args[arg_pos]); 3107 shadow_frame->SetVRegReference(cur_reg, o); 3108 break; 3109 } 3110 case 'J': case 'D': { 3111 uint64_t wide_value = (static_cast<uint64_t>(args[arg_pos + 1]) << 32) | args[arg_pos]; 3112 shadow_frame->SetVRegLong(cur_reg, wide_value); 3113 cur_reg++; 3114 arg_pos++; 3115 break; 3116 } 3117 default: 3118 shadow_frame->SetVReg(cur_reg, args[arg_pos]); 3119 break; 3120 } 3121 } 3122 if (LIKELY(!method->IsNative())) { 3123 JValue r = Execute(self, mh, code_item, *shadow_frame, JValue()); 3124 if (result != NULL) { 3125 *result = r; 3126 } 3127 } else { 3128 // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 3129 // generated stub) except during testing and image writing. 3130 if (!Runtime::Current()->IsStarted()) { 3131 UnstartedRuntimeJni(self, method, receiver, args, result); 3132 } else { 3133 InterpreterJni(self, method, shorty, receiver, args, result); 3134 } 3135 } 3136 self->PopShadowFrame(); 3137} 3138 3139void EnterInterpreterFromDeoptimize(Thread* self, ShadowFrame* shadow_frame, JValue* ret_val) 3140 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 3141 JValue value; 3142 value.SetJ(ret_val->GetJ()); // Set value to last known result in case the shadow frame chain is empty. 3143 MethodHelper mh; 3144 while (shadow_frame != NULL) { 3145 self->SetTopOfShadowStack(shadow_frame); 3146 mh.ChangeMethod(shadow_frame->GetMethod()); 3147 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 3148 value = Execute(self, mh, code_item, *shadow_frame, value); 3149 ShadowFrame* old_frame = shadow_frame; 3150 shadow_frame = shadow_frame->GetLink(); 3151 delete old_frame; 3152 } 3153 ret_val->SetJ(value.GetJ()); 3154} 3155 3156JValue EnterInterpreterFromStub(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 3157 ShadowFrame& shadow_frame) { 3158 DCHECK_EQ(self, Thread::Current()); 3159 if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) { 3160 ThrowStackOverflowError(self); 3161 return JValue(); 3162 } 3163 3164 return Execute(self, mh, code_item, shadow_frame, JValue()); 3165} 3166 3167extern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper& mh, 3168 const DexFile::CodeItem* code_item, 3169 ShadowFrame* shadow_frame, JValue* result) { 3170 if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) { 3171 ThrowStackOverflowError(self); 3172 return; 3173 } 3174 3175 AbstractMethod* method = shadow_frame->GetMethod(); 3176 if (method->IsStatic() && !method->GetDeclaringClass()->IsInitializing()) { 3177 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(), 3178 true, true)) { 3179 DCHECK(Thread::Current()->IsExceptionPending()); 3180 return; 3181 } 3182 CHECK(method->GetDeclaringClass()->IsInitializing()); 3183 } 3184 3185 self->PushShadowFrame(shadow_frame); 3186 3187 if (LIKELY(!method->IsNative())) { 3188 result->SetJ(Execute(self, mh, code_item, *shadow_frame, JValue()).GetJ()); 3189 } else { 3190 // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 3191 // generated stub) except during testing and image writing. 3192 CHECK(!Runtime::Current()->IsStarted()); 3193 Object* receiver = method->IsStatic() ? NULL : shadow_frame->GetVRegReference(0); 3194 uint32_t* args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1); 3195 UnstartedRuntimeJni(self, method, receiver, args, result); 3196 } 3197 3198 self->PopShadowFrame(); 3199 return; 3200} 3201 3202} // namespace interpreter 3203} // namespace art 3204