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