interpreter.cc revision 167436311a08a65dea28dda079a137893821c9c7
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.h" 26#include "gc/card_table-inl.h" 27#include "invoke_arg_array_builder.h" 28#include "nth_caller_visitor.h" 29#include "mirror/class.h" 30#include "mirror/class-inl.h" 31#include "mirror/field-inl.h" 32#include "mirror/abstract_method.h" 33#include "mirror/abstract_method-inl.h" 34#include "mirror/object-inl.h" 35#include "mirror/object_array-inl.h" 36#include "object_utils.h" 37#include "runtime_support.h" 38#include "ScopedLocalRef.h" 39#include "scoped_thread_state_change.h" 40#include "thread.h" 41 42using namespace art::mirror; 43 44namespace art { 45 46namespace interpreter { 47 48static const int32_t kMaxInt = std::numeric_limits<int32_t>::max(); 49static const int32_t kMinInt = std::numeric_limits<int32_t>::min(); 50static const int64_t kMaxLong = std::numeric_limits<int64_t>::max(); 51static const int64_t kMinLong = std::numeric_limits<int64_t>::min(); 52 53static void UnstartedRuntimeInvoke(Thread* self, AbstractMethod* target_method, 54 ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) 55 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 56 // In a runtime that's not started we intercept certain methods to avoid complicated dependency 57 // problems in core libraries. 58 std::string name(PrettyMethod(target_method)); 59 if (name == "java.lang.Class java.lang.Class.forName(java.lang.String)") { 60 std::string descriptor(DotToDescriptor(shadow_frame->GetVRegReference(arg_offset)->AsString()->ToModifiedUtf8().c_str())); 61 ClassLoader* class_loader = NULL; // shadow_frame.GetMethod()->GetDeclaringClass()->GetClassLoader(); 62 Class* found = Runtime::Current()->GetClassLinker()->FindClass(descriptor.c_str(), 63 class_loader); 64 CHECK(found != NULL) << "Class.forName failed in un-started runtime for class: " 65 << PrettyDescriptor(descriptor); 66 result->SetL(found); 67 } else if (name == "java.lang.Object java.lang.Class.newInstance()") { 68 Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass(); 69 AbstractMethod* c = klass->FindDeclaredDirectMethod("<init>", "()V"); 70 CHECK(c != NULL); 71 Object* obj = klass->AllocObject(self); 72 CHECK(obj != NULL); 73 EnterInterpreterFromInvoke(self, c, obj, NULL, NULL); 74 result->SetL(obj); 75 } else if (name == "java.lang.reflect.Field java.lang.Class.getDeclaredField(java.lang.String)") { 76 // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail 77 // going the reflective Dex way. 78 Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass(); 79 String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString(); 80 Field* found = NULL; 81 FieldHelper fh; 82 ObjectArray<Field>* fields = klass->GetIFields(); 83 for (int32_t i = 0; i < fields->GetLength() && found == NULL; ++i) { 84 Field* f = fields->Get(i); 85 fh.ChangeField(f); 86 if (name->Equals(fh.GetName())) { 87 found = f; 88 } 89 } 90 if (found == NULL) { 91 fields = klass->GetSFields(); 92 for (int32_t i = 0; i < fields->GetLength() && found == NULL; ++i) { 93 Field* f = fields->Get(i); 94 fh.ChangeField(f); 95 if (name->Equals(fh.GetName())) { 96 found = f; 97 } 98 } 99 } 100 CHECK(found != NULL) 101 << "Failed to find field in Class.getDeclaredField in un-started runtime. name=" 102 << name->ToModifiedUtf8() << " class=" << PrettyDescriptor(klass); 103 // TODO: getDeclaredField calls GetType once the field is found to ensure a 104 // NoClassDefFoundError is thrown if the field's type cannot be resolved. 105 result->SetL(found); 106 } else if (name == "void java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int)") { 107 // Special case array copying without initializing System. 108 Class* ctype = shadow_frame->GetVRegReference(arg_offset)->GetClass()->GetComponentType(); 109 jint srcPos = shadow_frame->GetVReg(arg_offset + 1); 110 jint dstPos = shadow_frame->GetVReg(arg_offset + 3); 111 jint length = shadow_frame->GetVReg(arg_offset + 4); 112 if (!ctype->IsPrimitive()) { 113 ObjectArray<Object>* src = shadow_frame->GetVRegReference(arg_offset)->AsObjectArray<Object>(); 114 ObjectArray<Object>* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<Object>(); 115 for (jint i = 0; i < length; ++i) { 116 dst->Set(dstPos + i, src->Get(srcPos + i)); 117 } 118 } else if (ctype->IsPrimitiveChar()) { 119 CharArray* src = shadow_frame->GetVRegReference(arg_offset)->AsCharArray(); 120 CharArray* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray(); 121 for (jint i = 0; i < length; ++i) { 122 dst->Set(dstPos + i, src->Get(srcPos + i)); 123 } 124 } else if (ctype->IsPrimitiveInt()) { 125 IntArray* src = shadow_frame->GetVRegReference(arg_offset)->AsIntArray(); 126 IntArray* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsIntArray(); 127 for (jint i = 0; i < length; ++i) { 128 dst->Set(dstPos + i, src->Get(srcPos + i)); 129 } 130 } else { 131 UNIMPLEMENTED(FATAL) << "System.arraycopy of unexpected type: " << PrettyDescriptor(ctype); 132 } 133 } else { 134 // Not special, continue with regular interpreter execution. 135 result->SetJ(EnterInterpreterFromInterpreter(self, shadow_frame).GetJ()); 136 } 137} 138 139// Hand select a number of methods to be run in a not yet started runtime without using JNI. 140static void UnstartedRuntimeJni(Thread* self, AbstractMethod* method, 141 Object* receiver, uint32_t* args, JValue* result) 142 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 143 std::string name(PrettyMethod(method)); 144 if (name == "java.lang.ClassLoader dalvik.system.VMStack.getCallingClassLoader()") { 145 result->SetL(NULL); 146 } else if (name == "java.lang.Class dalvik.system.VMStack.getStackClass2()") { 147 NthCallerVisitor visitor(self, 3); 148 visitor.WalkStack(); 149 result->SetL(visitor.caller->GetDeclaringClass()); 150 } else if (name == "double java.lang.Math.log(double)") { 151 JValue value; 152 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]); 153 result->SetD(log(value.GetD())); 154 } else if (name == "java.lang.String java.lang.Class.getNameNative()") { 155 result->SetL(receiver->AsClass()->ComputeName()); 156 } else if (name == "int java.lang.Float.floatToRawIntBits(float)") { 157 result->SetI(args[0]); 158 } else if (name == "float java.lang.Float.intBitsToFloat(int)") { 159 result->SetI(args[0]); 160 } else if (name == "double java.lang.Math.exp(double)") { 161 JValue value; 162 value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]); 163 result->SetD(exp(value.GetD())); 164 } else if (name == "java.lang.Object java.lang.Object.internalClone()") { 165 result->SetL(receiver->Clone(self)); 166 } else if (name == "void java.lang.Object.notifyAll()") { 167 receiver->NotifyAll(self); 168 } else if (name == "int java.lang.String.compareTo(java.lang.String)") { 169 String* rhs = reinterpret_cast<Object*>(args[0])->AsString(); 170 CHECK(rhs != NULL); 171 result->SetI(receiver->AsString()->CompareTo(rhs)); 172 } else if (name == "java.lang.String java.lang.String.intern()") { 173 result->SetL(receiver->AsString()->Intern()); 174 } else if (name == "int java.lang.String.fastIndexOf(int, int)") { 175 result->SetI(receiver->AsString()->FastIndexOf(args[0], args[1])); 176 } else if (name == "java.lang.Object java.lang.reflect.Array.createMultiArray(java.lang.Class, int[])") { 177 result->SetL(Array::CreateMultiArray(self, reinterpret_cast<Object*>(args[0])->AsClass(), reinterpret_cast<Object*>(args[1])->AsIntArray())); 178 } else if (name == "java.lang.Object java.lang.Throwable.nativeFillInStackTrace()") { 179 ScopedObjectAccessUnchecked soa(self); 180 result->SetL(soa.Decode<Object*>(self->CreateInternalStackTrace(soa))); 181 } else if (name == "boolean java.nio.ByteOrder.isLittleEndian()") { 182 result->SetJ(JNI_TRUE); 183 } else if (name == "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)") { 184 Object* obj = reinterpret_cast<Object*>(args[0]); 185 jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1]; 186 jint expectedValue = args[3]; 187 jint newValue = args[4]; 188 byte* raw_addr = reinterpret_cast<byte*>(obj) + offset; 189 volatile int32_t* address = reinterpret_cast<volatile int32_t*>(raw_addr); 190 // Note: android_atomic_release_cas() returns 0 on success, not failure. 191 int r = android_atomic_release_cas(expectedValue, newValue, address); 192 result->SetZ(r == 0); 193 } else if (name == "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)") { 194 Object* obj = reinterpret_cast<Object*>(args[0]); 195 Object* newValue = reinterpret_cast<Object*>(args[3]); 196 obj->SetFieldObject(MemberOffset((static_cast<uint64_t>(args[2]) << 32) | args[1]), newValue, false); 197 } else { 198 LOG(FATAL) << "Attempt to invoke native method in non-started runtime: " << name; 199 } 200} 201 202static void InterpreterJni(Thread* self, AbstractMethod* method, StringPiece shorty, 203 Object* receiver, uint32_t* args, JValue* result) 204 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 205 // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler, 206 // it should be removed and JNI compiled stubs used instead. 207 ScopedObjectAccessUnchecked soa(self); 208 if (method->IsStatic()) { 209 if (shorty == "L") { 210 typedef jobject (fnptr)(JNIEnv*, jclass); 211 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 212 ScopedLocalRef<jclass> klass(soa.Env(), 213 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 214 jobject jresult; 215 { 216 ScopedThreadStateChange tsc(self, kNative); 217 jresult = fn(soa.Env(), klass.get()); 218 } 219 result->SetL(soa.Decode<Object*>(jresult)); 220 } else if (shorty == "V") { 221 typedef void (fnptr)(JNIEnv*, jclass); 222 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 223 ScopedLocalRef<jclass> klass(soa.Env(), 224 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 225 ScopedThreadStateChange tsc(self, kNative); 226 fn(soa.Env(), klass.get()); 227 } else if (shorty == "Z") { 228 typedef jboolean (fnptr)(JNIEnv*, jclass); 229 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 230 ScopedLocalRef<jclass> klass(soa.Env(), 231 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 232 ScopedThreadStateChange tsc(self, kNative); 233 result->SetZ(fn(soa.Env(), klass.get())); 234 } else if (shorty == "BI") { 235 typedef jbyte (fnptr)(JNIEnv*, jclass, jint); 236 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 237 ScopedLocalRef<jclass> klass(soa.Env(), 238 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 239 ScopedThreadStateChange tsc(self, kNative); 240 result->SetB(fn(soa.Env(), klass.get(), args[0])); 241 } else if (shorty == "II") { 242 typedef jint (fnptr)(JNIEnv*, jclass, jint); 243 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 244 ScopedLocalRef<jclass> klass(soa.Env(), 245 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 246 ScopedThreadStateChange tsc(self, kNative); 247 result->SetI(fn(soa.Env(), klass.get(), args[0])); 248 } else if (shorty == "LL") { 249 typedef jobject (fnptr)(JNIEnv*, jclass, jobject); 250 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 251 ScopedLocalRef<jclass> klass(soa.Env(), 252 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 253 ScopedLocalRef<jobject> arg0(soa.Env(), 254 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 255 jobject jresult; 256 { 257 ScopedThreadStateChange tsc(self, kNative); 258 jresult = fn(soa.Env(), klass.get(), arg0.get()); 259 } 260 result->SetL(soa.Decode<Object*>(jresult)); 261 } else if (shorty == "IIZ") { 262 typedef jint (fnptr)(JNIEnv*, jclass, jint, jboolean); 263 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 264 ScopedLocalRef<jclass> klass(soa.Env(), 265 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 266 ScopedThreadStateChange tsc(self, kNative); 267 result->SetI(fn(soa.Env(), klass.get(), args[0], args[1])); 268 } else if (shorty == "ILI") { 269 typedef jint (fnptr)(JNIEnv*, jclass, jobject, jint); 270 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 271 ScopedLocalRef<jclass> klass(soa.Env(), 272 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 273 ScopedLocalRef<jobject> arg0(soa.Env(), 274 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 275 ScopedThreadStateChange tsc(self, kNative); 276 result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1])); 277 } else if (shorty == "SIZ") { 278 typedef jshort (fnptr)(JNIEnv*, jclass, jint, jboolean); 279 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 280 ScopedLocalRef<jclass> klass(soa.Env(), 281 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 282 ScopedThreadStateChange tsc(self, kNative); 283 result->SetS(fn(soa.Env(), klass.get(), args[0], args[1])); 284 } else if (shorty == "VIZ") { 285 typedef void (fnptr)(JNIEnv*, jclass, jint, jboolean); 286 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 287 ScopedLocalRef<jclass> klass(soa.Env(), 288 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 289 ScopedThreadStateChange tsc(self, kNative); 290 fn(soa.Env(), klass.get(), args[0], args[1]); 291 } else if (shorty == "ZLL") { 292 typedef jboolean (fnptr)(JNIEnv*, jclass, jobject, jobject); 293 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 294 ScopedLocalRef<jclass> klass(soa.Env(), 295 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 296 ScopedLocalRef<jobject> arg0(soa.Env(), 297 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 298 ScopedLocalRef<jobject> arg1(soa.Env(), 299 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 300 ScopedThreadStateChange tsc(self, kNative); 301 result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get())); 302 } else if (shorty == "ZILL") { 303 typedef jboolean (fnptr)(JNIEnv*, jclass, jint, jobject, jobject); 304 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 305 ScopedLocalRef<jclass> klass(soa.Env(), 306 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 307 ScopedLocalRef<jobject> arg1(soa.Env(), 308 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 309 ScopedLocalRef<jobject> arg2(soa.Env(), 310 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[2]))); 311 ScopedThreadStateChange tsc(self, kNative); 312 result->SetZ(fn(soa.Env(), klass.get(), args[0], arg1.get(), arg2.get())); 313 } else if (shorty == "VILII") { 314 typedef void (fnptr)(JNIEnv*, jclass, jint, jobject, jint, jint); 315 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 316 ScopedLocalRef<jclass> klass(soa.Env(), 317 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 318 ScopedLocalRef<jobject> arg1(soa.Env(), 319 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 320 ScopedThreadStateChange tsc(self, kNative); 321 fn(soa.Env(), klass.get(), args[0], arg1.get(), args[2], args[3]); 322 } else if (shorty == "VLILII") { 323 typedef void (fnptr)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint); 324 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 325 ScopedLocalRef<jclass> klass(soa.Env(), 326 soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 327 ScopedLocalRef<jobject> arg0(soa.Env(), 328 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 329 ScopedLocalRef<jobject> arg2(soa.Env(), 330 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[2]))); 331 ScopedThreadStateChange tsc(self, kNative); 332 fn(soa.Env(), klass.get(), arg0.get(), args[1], arg2.get(), args[3], args[4]); 333 } else { 334 LOG(FATAL) << "Do something with static native method: " << PrettyMethod(method) 335 << " shorty: " << shorty; 336 } 337 } else { 338 if (shorty == "L") { 339 typedef jobject (fnptr)(JNIEnv*, jobject); 340 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 341 ScopedLocalRef<jobject> rcvr(soa.Env(), 342 soa.AddLocalReference<jobject>(receiver)); 343 jobject jresult; 344 { 345 ScopedThreadStateChange tsc(self, kNative); 346 jresult = fn(soa.Env(), rcvr.get()); 347 } 348 result->SetL(soa.Decode<Object*>(jresult)); 349 } else if (shorty == "LL") { 350 typedef jobject (fnptr)(JNIEnv*, jobject, jobject); 351 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 352 ScopedLocalRef<jobject> rcvr(soa.Env(), 353 soa.AddLocalReference<jobject>(receiver)); 354 ScopedLocalRef<jobject> arg0(soa.Env(), 355 soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 356 jobject jresult; 357 { 358 ScopedThreadStateChange tsc(self, kNative); 359 jresult = fn(soa.Env(), rcvr.get(), arg0.get()); 360 361 } 362 result->SetL(soa.Decode<Object*>(jresult)); 363 ScopedThreadStateChange tsc(self, kNative); 364 } else if (shorty == "III") { 365 typedef jint (fnptr)(JNIEnv*, jobject, jint, jint); 366 fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod()); 367 ScopedLocalRef<jobject> rcvr(soa.Env(), 368 soa.AddLocalReference<jobject>(receiver)); 369 ScopedThreadStateChange tsc(self, kNative); 370 result->SetI(fn(soa.Env(), rcvr.get(), args[0], args[1])); 371 } else { 372 LOG(FATAL) << "Do something with native method: " << PrettyMethod(method) 373 << " shorty: " << shorty; 374 } 375 } 376} 377 378static void DoMonitorEnter(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS { 379 ref->MonitorEnter(self); 380} 381 382static void DoMonitorExit(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS { 383 ref->MonitorExit(self); 384} 385 386static void DoInvoke(Thread* self, MethodHelper& mh, ShadowFrame& shadow_frame, 387 const DecodedInstruction& dec_insn, InvokeType type, bool is_range, 388 JValue* result) 389 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 390 Object* receiver; 391 if (type == kStatic) { 392 receiver = NULL; 393 } else { 394 receiver = shadow_frame.GetVRegReference(dec_insn.vC); 395 } 396 uint32_t method_idx = dec_insn.vB; 397 AbstractMethod* target_method = FindMethodFromCode(method_idx, receiver, 398 shadow_frame.GetMethod(), self, true, 399 type); 400 if (UNLIKELY(target_method == NULL)) { 401 CHECK(self->IsExceptionPending()); 402 result->SetJ(0); 403 return; 404 } 405 mh.ChangeMethod(target_method); 406 407 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 408 uint16_t num_regs; 409 uint16_t num_ins; 410 if (code_item != NULL) { 411 num_regs = code_item->registers_size_; 412 num_ins = code_item->ins_size_; 413 } else if (target_method->IsAbstract()) { 414 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 415 self->ThrowNewExceptionF(throw_location, "Ljava/lang/AbstractMethodError;", 416 "abstract method \"%s\"", PrettyMethod(target_method).c_str()); 417 return; 418 } else { 419 DCHECK(target_method->IsNative() || target_method->IsProxyMethod()); 420 num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty()); 421 if (!target_method->IsStatic()) { 422 num_regs++; 423 num_ins++; 424 } 425 } 426 427 Runtime* runtime = Runtime::Current(); 428 UniquePtr<ShadowFrame> new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame, 429 target_method, 0)); 430 size_t cur_reg = num_regs - num_ins; 431 if (receiver != NULL) { 432 new_shadow_frame->SetVRegReference(cur_reg, receiver); 433 ++cur_reg; 434 } 435 436 size_t arg_offset = (receiver == NULL) ? 0 : 1; 437 const char* shorty = mh.GetShorty(); 438 for (size_t shorty_pos = 0; cur_reg < num_regs; ++shorty_pos, cur_reg++, arg_offset++) { 439 DCHECK_LT(shorty_pos + 1, mh.GetShortyLength()); 440 size_t arg_pos = is_range ? dec_insn.vC + arg_offset : dec_insn.arg[arg_offset]; 441 switch (shorty[shorty_pos + 1]) { 442 case 'L': { 443 Object* o = shadow_frame.GetVRegReference(arg_pos); 444 new_shadow_frame->SetVRegReference(cur_reg, o); 445 break; 446 } 447 case 'J': case 'D': { 448 uint64_t wide_value = (static_cast<uint64_t>(shadow_frame.GetVReg(arg_pos + 1)) << 32) | 449 static_cast<uint32_t>(shadow_frame.GetVReg(arg_pos)); 450 new_shadow_frame->SetVRegLong(cur_reg, wide_value); 451 cur_reg++; 452 arg_offset++; 453 break; 454 } 455 default: 456 new_shadow_frame->SetVReg(cur_reg, shadow_frame.GetVReg(arg_pos)); 457 break; 458 } 459 } 460 461 if (LIKELY(runtime->IsStarted())) { 462 result->SetJ((target_method->GetEntryPointFromInterpreter())(self, new_shadow_frame.get()).GetJ()); 463 } else { 464 UnstartedRuntimeInvoke(self, target_method, new_shadow_frame.get(), result, num_regs - num_ins); 465 } 466 mh.ChangeMethod(shadow_frame.GetMethod()); 467} 468 469static void DoFieldGet(Thread* self, ShadowFrame& shadow_frame, 470 const DecodedInstruction& dec_insn, FindFieldType find_type, 471 Primitive::Type field_type) 472 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 473 bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead); 474 uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC; 475 Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self, 476 find_type, Primitive::FieldSize(field_type)); 477 if (LIKELY(f != NULL)) { 478 Object* obj; 479 if (is_static) { 480 obj = f->GetDeclaringClass(); 481 } else { 482 obj = shadow_frame.GetVRegReference(dec_insn.vB); 483 if (UNLIKELY(obj == NULL)) { 484 ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(), f, true); 485 return; 486 } 487 } 488 switch (field_type) { 489 case Primitive::kPrimBoolean: 490 shadow_frame.SetVReg(dec_insn.vA, f->GetBoolean(obj)); 491 break; 492 case Primitive::kPrimByte: 493 shadow_frame.SetVReg(dec_insn.vA, f->GetByte(obj)); 494 break; 495 case Primitive::kPrimChar: 496 shadow_frame.SetVReg(dec_insn.vA, f->GetChar(obj)); 497 break; 498 case Primitive::kPrimShort: 499 shadow_frame.SetVReg(dec_insn.vA, f->GetShort(obj)); 500 break; 501 case Primitive::kPrimInt: 502 shadow_frame.SetVReg(dec_insn.vA, f->GetInt(obj)); 503 break; 504 case Primitive::kPrimLong: 505 shadow_frame.SetVRegLong(dec_insn.vA, f->GetLong(obj)); 506 break; 507 case Primitive::kPrimNot: 508 shadow_frame.SetVRegReference(dec_insn.vA, f->GetObject(obj)); 509 break; 510 default: 511 LOG(FATAL) << "Unreachable: " << field_type; 512 } 513 } 514} 515 516static void DoFieldPut(Thread* self, ShadowFrame& shadow_frame, 517 const DecodedInstruction& dec_insn, FindFieldType find_type, 518 Primitive::Type field_type) 519 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 520 bool is_static = (find_type == StaticObjectWrite) || (find_type == StaticPrimitiveWrite); 521 uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC; 522 Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self, 523 find_type, Primitive::FieldSize(field_type)); 524 if (LIKELY(f != NULL)) { 525 Object* obj; 526 if (is_static) { 527 obj = f->GetDeclaringClass(); 528 } else { 529 obj = shadow_frame.GetVRegReference(dec_insn.vB); 530 if (UNLIKELY(obj == NULL)) { 531 ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(), 532 f, false); 533 return; 534 } 535 } 536 switch (field_type) { 537 case Primitive::kPrimBoolean: 538 f->SetBoolean(obj, shadow_frame.GetVReg(dec_insn.vA)); 539 break; 540 case Primitive::kPrimByte: 541 f->SetByte(obj, shadow_frame.GetVReg(dec_insn.vA)); 542 break; 543 case Primitive::kPrimChar: 544 f->SetChar(obj, shadow_frame.GetVReg(dec_insn.vA)); 545 break; 546 case Primitive::kPrimShort: 547 f->SetShort(obj, shadow_frame.GetVReg(dec_insn.vA)); 548 break; 549 case Primitive::kPrimInt: 550 f->SetInt(obj, shadow_frame.GetVReg(dec_insn.vA)); 551 break; 552 case Primitive::kPrimLong: 553 f->SetLong(obj, shadow_frame.GetVRegLong(dec_insn.vA)); 554 break; 555 case Primitive::kPrimNot: 556 f->SetObj(obj, shadow_frame.GetVRegReference(dec_insn.vA)); 557 break; 558 default: 559 LOG(FATAL) << "Unreachable: " << field_type; 560 } 561 } 562} 563 564static void DoIntDivide(Thread* self, ShadowFrame& shadow_frame, size_t result_reg, 565 int32_t dividend, int32_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 566 if (UNLIKELY(divisor == 0)) { 567 ThrowArithmeticExceptionDivideByZero(self); 568 } else if (UNLIKELY(dividend == kMinInt && divisor == -1)) { 569 shadow_frame.SetVReg(result_reg, kMinInt); 570 } else { 571 shadow_frame.SetVReg(result_reg, dividend / divisor); 572 } 573} 574 575static void DoIntRemainder(Thread* self, ShadowFrame& shadow_frame, size_t result_reg, 576 int32_t dividend, int32_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 577 if (UNLIKELY(divisor == 0)) { 578 ThrowArithmeticExceptionDivideByZero(self); 579 } else if (UNLIKELY(dividend == kMinInt && divisor == -1)) { 580 shadow_frame.SetVReg(result_reg, 0); 581 } else { 582 shadow_frame.SetVReg(result_reg, dividend % divisor); 583 } 584} 585 586static void DoLongDivide(Thread* self, ShadowFrame& shadow_frame, size_t result_reg, 587 int64_t dividend, int64_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 588 if (UNLIKELY(divisor == 0)) { 589 ThrowArithmeticExceptionDivideByZero(self); 590 } else if (UNLIKELY(dividend == kMinLong && divisor == -1)) { 591 shadow_frame.SetVRegLong(result_reg, kMinLong); 592 } else { 593 shadow_frame.SetVRegLong(result_reg, dividend / divisor); 594 } 595} 596 597static void DoLongRemainder(Thread* self, ShadowFrame& shadow_frame, size_t result_reg, 598 int64_t dividend, int64_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 599 if (UNLIKELY(divisor == 0)) { 600 ThrowArithmeticExceptionDivideByZero(self); 601 } else if (UNLIKELY(dividend == kMinLong && divisor == -1)) { 602 shadow_frame.SetVRegLong(result_reg, 0); 603 } else { 604 shadow_frame.SetVRegLong(result_reg, dividend % divisor); 605 } 606} 607 608static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 609 ShadowFrame& shadow_frame, JValue result_register) 610 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 611 if (UNLIKELY(!shadow_frame.HasReferenceArray())) { 612 LOG(FATAL) << "Invalid shadow frame for interpreter use"; 613 return JValue(); 614 } 615 self->VerifyStack(); 616 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 617 const uint16_t* insns = code_item->insns_; 618 const Instruction* inst = Instruction::At(insns + shadow_frame.GetDexPC()); 619 if (inst->GetDexPc(insns) == 0) { // We are entering the method as opposed to deoptimizing.. 620 instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(), shadow_frame.GetMethod(), 621 0); 622 } 623 while (true) { 624 CheckSuspend(self); 625 uint32_t dex_pc = inst->GetDexPc(insns); 626 shadow_frame.SetDexPC(dex_pc); 627 instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(), shadow_frame.GetMethod(), 628 dex_pc); 629 DecodedInstruction dec_insn(inst); 630 const bool kTracing = false; 631 if (kTracing) { 632#define TRACE_LOG std::cerr 633 TRACE_LOG << PrettyMethod(shadow_frame.GetMethod()) 634 << StringPrintf("\n0x%x: ", inst->GetDexPc(insns)) 635 << inst->DumpString(&mh.GetDexFile()) << "\n"; 636 for (size_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) { 637 uint32_t raw_value = shadow_frame.GetVReg(i); 638 Object* ref_value = shadow_frame.GetVRegReference(i); 639 TRACE_LOG << StringPrintf(" vreg%d=0x%08X", i, raw_value); 640 if (ref_value != NULL) { 641 if (ref_value->GetClass()->IsStringClass() && 642 ref_value->AsString()->GetCharArray() != NULL) { 643 TRACE_LOG << "/java.lang.String \"" << ref_value->AsString()->ToModifiedUtf8() << "\""; 644 } else { 645 TRACE_LOG << "/" << PrettyTypeOf(ref_value); 646 } 647 } 648 } 649 TRACE_LOG << "\n"; 650#undef TRACE_LOG 651 } 652 const Instruction* next_inst = inst->Next(); 653 switch (dec_insn.opcode) { 654 case Instruction::NOP: 655 break; 656 case Instruction::MOVE: 657 case Instruction::MOVE_FROM16: 658 case Instruction::MOVE_16: 659 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB)); 660 break; 661 case Instruction::MOVE_WIDE: 662 case Instruction::MOVE_WIDE_FROM16: 663 case Instruction::MOVE_WIDE_16: 664 shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB)); 665 break; 666 case Instruction::MOVE_OBJECT: 667 case Instruction::MOVE_OBJECT_FROM16: 668 case Instruction::MOVE_OBJECT_16: 669 shadow_frame.SetVRegReference(dec_insn.vA, shadow_frame.GetVRegReference(dec_insn.vB)); 670 break; 671 case Instruction::MOVE_RESULT: 672 shadow_frame.SetVReg(dec_insn.vA, result_register.GetI()); 673 break; 674 case Instruction::MOVE_RESULT_WIDE: 675 shadow_frame.SetVRegLong(dec_insn.vA, result_register.GetJ()); 676 break; 677 case Instruction::MOVE_RESULT_OBJECT: 678 shadow_frame.SetVRegReference(dec_insn.vA, result_register.GetL()); 679 break; 680 case Instruction::MOVE_EXCEPTION: { 681 Throwable* exception = self->GetException(NULL); 682 self->ClearException(); 683 shadow_frame.SetVRegReference(dec_insn.vA, exception); 684 break; 685 } 686 case Instruction::RETURN_VOID: { 687 JValue result; 688 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(), 689 shadow_frame.GetMethod(), shadow_frame.GetDexPC(), 690 result); 691 return result; 692 } 693 case Instruction::RETURN: { 694 JValue result; 695 result.SetJ(0); 696 result.SetI(shadow_frame.GetVReg(dec_insn.vA)); 697 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(), 698 shadow_frame.GetMethod(), shadow_frame.GetDexPC(), 699 result); 700 return result; 701 } 702 case Instruction::RETURN_WIDE: { 703 JValue result; 704 result.SetJ(shadow_frame.GetVRegLong(dec_insn.vA)); 705 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(), 706 shadow_frame.GetMethod(), shadow_frame.GetDexPC(), 707 result); 708 return result; 709 } 710 case Instruction::RETURN_OBJECT: { 711 JValue result; 712 result.SetJ(0); 713 result.SetL(shadow_frame.GetVRegReference(dec_insn.vA)); 714 instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(), 715 shadow_frame.GetMethod(), shadow_frame.GetDexPC(), 716 result); 717 return result; 718 } 719 case Instruction::CONST_4: { 720 int32_t val = static_cast<int32_t>(dec_insn.vB << 28) >> 28; 721 shadow_frame.SetVReg(dec_insn.vA, val); 722 if (val == 0) { 723 shadow_frame.SetVRegReference(dec_insn.vA, NULL); 724 } 725 break; 726 } 727 case Instruction::CONST_16: { 728 int32_t val = static_cast<int16_t>(dec_insn.vB); 729 shadow_frame.SetVReg(dec_insn.vA, val); 730 if (val == 0) { 731 shadow_frame.SetVRegReference(dec_insn.vA, NULL); 732 } 733 break; 734 } 735 case Instruction::CONST: { 736 int32_t val = dec_insn.vB; 737 shadow_frame.SetVReg(dec_insn.vA, val); 738 if (val == 0) { 739 shadow_frame.SetVRegReference(dec_insn.vA, NULL); 740 } 741 break; 742 } 743 case Instruction::CONST_HIGH16: { 744 int32_t val = dec_insn.vB << 16; 745 shadow_frame.SetVReg(dec_insn.vA, val); 746 if (val == 0) { 747 shadow_frame.SetVRegReference(dec_insn.vA, NULL); 748 } 749 break; 750 } 751 case Instruction::CONST_WIDE_16: 752 shadow_frame.SetVRegLong(dec_insn.vA, static_cast<int16_t>(dec_insn.vB)); 753 break; 754 case Instruction::CONST_WIDE_32: 755 shadow_frame.SetVRegLong(dec_insn.vA, static_cast<int32_t>(dec_insn.vB)); 756 break; 757 case Instruction::CONST_WIDE: 758 shadow_frame.SetVRegLong(dec_insn.vA, dec_insn.vB_wide); 759 break; 760 case Instruction::CONST_WIDE_HIGH16: 761 shadow_frame.SetVRegLong(dec_insn.vA, static_cast<uint64_t>(dec_insn.vB) << 48); 762 break; 763 case Instruction::CONST_STRING: 764 case Instruction::CONST_STRING_JUMBO: { 765 if (UNLIKELY(!String::GetJavaLangString()->IsInitialized())) { 766 Runtime::Current()->GetClassLinker()->EnsureInitialized(String::GetJavaLangString(), 767 true, true); 768 } 769 String* s = mh.ResolveString(dec_insn.vB); 770 shadow_frame.SetVRegReference(dec_insn.vA, s); 771 break; 772 } 773 case Instruction::CONST_CLASS: { 774 Class* c = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true); 775 shadow_frame.SetVRegReference(dec_insn.vA, c); 776 break; 777 } 778 case Instruction::MONITOR_ENTER: { 779 Object* obj = shadow_frame.GetVRegReference(dec_insn.vA); 780 if (UNLIKELY(obj == NULL)) { 781 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 782 } else { 783 DoMonitorEnter(self, obj); 784 } 785 break; 786 } 787 case Instruction::MONITOR_EXIT: { 788 Object* obj = shadow_frame.GetVRegReference(dec_insn.vA); 789 if (UNLIKELY(obj == NULL)) { 790 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 791 } else { 792 DoMonitorExit(self, obj); 793 } 794 break; 795 } 796 case Instruction::CHECK_CAST: { 797 Class* c = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true); 798 if (UNLIKELY(c == NULL)) { 799 CHECK(self->IsExceptionPending()); 800 } else { 801 Object* obj = shadow_frame.GetVRegReference(dec_insn.vA); 802 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) { 803 ThrowClassCastException(c, obj->GetClass()); 804 } 805 } 806 break; 807 } 808 case Instruction::INSTANCE_OF: { 809 Class* c = ResolveVerifyAndClinit(dec_insn.vC, shadow_frame.GetMethod(), self, false, true); 810 if (UNLIKELY(c == NULL)) { 811 CHECK(self->IsExceptionPending()); 812 } else { 813 Object* obj = shadow_frame.GetVRegReference(dec_insn.vB); 814 shadow_frame.SetVReg(dec_insn.vA, (obj != NULL && obj->InstanceOf(c)) ? 1 : 0); 815 } 816 break; 817 } 818 case Instruction::ARRAY_LENGTH: { 819 Object* array = shadow_frame.GetVRegReference(dec_insn.vB); 820 if (UNLIKELY(array == NULL)) { 821 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 822 break; 823 } 824 shadow_frame.SetVReg(dec_insn.vA, array->AsArray()->GetLength()); 825 break; 826 } 827 case Instruction::NEW_INSTANCE: { 828 Object* obj = AllocObjectFromCode(dec_insn.vB, shadow_frame.GetMethod(), self, true); 829 shadow_frame.SetVRegReference(dec_insn.vA, obj); 830 break; 831 } 832 case Instruction::NEW_ARRAY: { 833 int32_t length = shadow_frame.GetVReg(dec_insn.vB); 834 Object* obj = AllocArrayFromCode(dec_insn.vC, shadow_frame.GetMethod(), length, self, true); 835 shadow_frame.SetVRegReference(dec_insn.vA, obj); 836 break; 837 } 838 case Instruction::FILLED_NEW_ARRAY: 839 case Instruction::FILLED_NEW_ARRAY_RANGE: { 840 bool is_range = (dec_insn.opcode == Instruction::FILLED_NEW_ARRAY_RANGE); 841 int32_t length = dec_insn.vA; 842 CHECK(is_range || length <= 5); 843 if (UNLIKELY(length < 0)) { 844 ThrowNegativeArraySizeException(length); 845 break; 846 } 847 Class* arrayClass = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true); 848 if (UNLIKELY(arrayClass == NULL)) { 849 CHECK(self->IsExceptionPending()); 850 break; 851 } 852 CHECK(arrayClass->IsArrayClass()); 853 Class* componentClass = arrayClass->GetComponentType(); 854 if (UNLIKELY(componentClass->IsPrimitive() && !componentClass->IsPrimitiveInt())) { 855 if (componentClass->IsPrimitiveLong() || componentClass->IsPrimitiveDouble()) { 856 ThrowRuntimeException("Bad filled array request for type %s", 857 PrettyDescriptor(componentClass).c_str()); 858 } else { 859 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(), 860 "Ljava/lang/InternalError;", 861 "Found type %s; filled-new-array not implemented for anything but \'int\'", 862 PrettyDescriptor(componentClass).c_str()); 863 } 864 break; 865 } 866 Object* newArray = Array::Alloc(self, arrayClass, length); 867 if (newArray != NULL) { 868 for (int32_t i = 0; i < length; ++i) { 869 if (is_range) { 870 if (componentClass->IsPrimitiveInt()) { 871 newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(dec_insn.vC + i)); 872 } else { 873 newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(dec_insn.vC + i)); 874 } 875 } else { 876 if (componentClass->IsPrimitiveInt()) { 877 newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(dec_insn.arg[i])); 878 } else { 879 newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(dec_insn.arg[i])); 880 } 881 } 882 } 883 } 884 result_register.SetL(newArray); 885 break; 886 } 887 case Instruction::CMPL_FLOAT: { 888 float val1 = shadow_frame.GetVRegFloat(dec_insn.vB); 889 float val2 = shadow_frame.GetVRegFloat(dec_insn.vC); 890 int32_t result; 891 if (val1 == val2) { 892 result = 0; 893 } else if (val1 > val2) { 894 result = 1; 895 } else { 896 result = -1; 897 } 898 shadow_frame.SetVReg(dec_insn.vA, result); 899 break; 900 } 901 case Instruction::CMPG_FLOAT: { 902 float val1 = shadow_frame.GetVRegFloat(dec_insn.vB); 903 float val2 = shadow_frame.GetVRegFloat(dec_insn.vC); 904 int32_t result; 905 if (val1 == val2) { 906 result = 0; 907 } else if (val1 < val2) { 908 result = -1; 909 } else { 910 result = 1; 911 } 912 shadow_frame.SetVReg(dec_insn.vA, result); 913 break; 914 } 915 case Instruction::CMPL_DOUBLE: { 916 double val1 = shadow_frame.GetVRegDouble(dec_insn.vB); 917 double val2 = shadow_frame.GetVRegDouble(dec_insn.vC); 918 int32_t result; 919 if (val1 == val2) { 920 result = 0; 921 } else if (val1 > val2) { 922 result = 1; 923 } else { 924 result = -1; 925 } 926 shadow_frame.SetVReg(dec_insn.vA, result); 927 break; 928 } 929 930 case Instruction::CMPG_DOUBLE: { 931 double val1 = shadow_frame.GetVRegDouble(dec_insn.vB); 932 double val2 = shadow_frame.GetVRegDouble(dec_insn.vC); 933 int32_t result; 934 if (val1 == val2) { 935 result = 0; 936 } else if (val1 < val2) { 937 result = -1; 938 } else { 939 result = 1; 940 } 941 shadow_frame.SetVReg(dec_insn.vA, result); 942 break; 943 } 944 case Instruction::CMP_LONG: { 945 int64_t val1 = shadow_frame.GetVRegLong(dec_insn.vB); 946 int64_t val2 = shadow_frame.GetVRegLong(dec_insn.vC); 947 int32_t result; 948 if (val1 > val2) { 949 result = 1; 950 } else if (val1 == val2) { 951 result = 0; 952 } else { 953 result = -1; 954 } 955 shadow_frame.SetVReg(dec_insn.vA, result); 956 break; 957 } 958 case Instruction::THROW: { 959 Object* exception = shadow_frame.GetVRegReference(dec_insn.vA); 960 if (exception == NULL) { 961 ThrowNullPointerException(NULL, "throw with null exception"); 962 } else { 963 self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable()); 964 } 965 break; 966 } 967 case Instruction::GOTO: 968 case Instruction::GOTO_16: 969 case Instruction::GOTO_32: { 970 uint32_t dex_pc = inst->GetDexPc(insns); 971 next_inst = Instruction::At(insns + dex_pc + dec_insn.vA); 972 break; 973 } 974 case Instruction::PACKED_SWITCH: { 975 uint32_t dex_pc = inst->GetDexPc(insns); 976 const uint16_t* switch_data = insns + dex_pc + dec_insn.vB; 977 int32_t test_val = shadow_frame.GetVReg(dec_insn.vA); 978 CHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kPackedSwitchSignature)); 979 uint16_t size = switch_data[1]; 980 CHECK_GT(size, 0); 981 const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]); 982 CHECK(IsAligned<4>(keys)); 983 int32_t first_key = keys[0]; 984 const int32_t* targets = reinterpret_cast<const int32_t*>(&switch_data[4]); 985 CHECK(IsAligned<4>(targets)); 986 int32_t index = test_val - first_key; 987 if (index >= 0 && index < size) { 988 next_inst = Instruction::At(insns + dex_pc + targets[index]); 989 } 990 break; 991 } 992 case Instruction::SPARSE_SWITCH: { 993 uint32_t dex_pc = inst->GetDexPc(insns); 994 const uint16_t* switch_data = insns + dex_pc + dec_insn.vB; 995 int32_t test_val = shadow_frame.GetVReg(dec_insn.vA); 996 CHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature)); 997 uint16_t size = switch_data[1]; 998 CHECK_GT(size, 0); 999 const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]); 1000 CHECK(IsAligned<4>(keys)); 1001 const int32_t* entries = keys + size; 1002 CHECK(IsAligned<4>(entries)); 1003 int lo = 0; 1004 int hi = size - 1; 1005 while (lo <= hi) { 1006 int mid = (lo + hi) / 2; 1007 int32_t foundVal = keys[mid]; 1008 if (test_val < foundVal) { 1009 hi = mid - 1; 1010 } else if (test_val > foundVal) { 1011 lo = mid + 1; 1012 } else { 1013 next_inst = Instruction::At(insns + dex_pc + entries[mid]); 1014 break; 1015 } 1016 } 1017 break; 1018 } 1019 case Instruction::FILL_ARRAY_DATA: { 1020 Object* obj = shadow_frame.GetVRegReference(dec_insn.vA); 1021 if (UNLIKELY(obj == NULL)) { 1022 ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA"); 1023 break; 1024 } 1025 Array* array = obj->AsArray(); 1026 DCHECK(array->IsArrayInstance() && !array->IsObjectArray()); 1027 uint32_t dex_pc = inst->GetDexPc(insns); 1028 const Instruction::ArrayDataPayload* payload = 1029 reinterpret_cast<const Instruction::ArrayDataPayload*>(insns + dex_pc + dec_insn.vB); 1030 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) { 1031 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(), 1032 "Ljava/lang/ArrayIndexOutOfBoundsException;", 1033 "failed FILL_ARRAY_DATA; length=%d, index=%d", 1034 array->GetLength(), payload->element_count); 1035 break; 1036 } 1037 uint32_t size_in_bytes = payload->element_count * payload->element_width; 1038 memcpy(array->GetRawData(payload->element_width), payload->data, size_in_bytes); 1039 break; 1040 } 1041 case Instruction::IF_EQ: { 1042 if (shadow_frame.GetVReg(dec_insn.vA) == shadow_frame.GetVReg(dec_insn.vB)) { 1043 uint32_t dex_pc = inst->GetDexPc(insns); 1044 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC); 1045 } 1046 break; 1047 } 1048 case Instruction::IF_NE: { 1049 if (shadow_frame.GetVReg(dec_insn.vA) != shadow_frame.GetVReg(dec_insn.vB)) { 1050 uint32_t dex_pc = inst->GetDexPc(insns); 1051 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC); 1052 } 1053 break; 1054 } 1055 case Instruction::IF_LT: { 1056 if (shadow_frame.GetVReg(dec_insn.vA) < shadow_frame.GetVReg(dec_insn.vB)) { 1057 uint32_t dex_pc = inst->GetDexPc(insns); 1058 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC); 1059 } 1060 break; 1061 } 1062 case Instruction::IF_GE: { 1063 if (shadow_frame.GetVReg(dec_insn.vA) >= shadow_frame.GetVReg(dec_insn.vB)) { 1064 uint32_t dex_pc = inst->GetDexPc(insns); 1065 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC); 1066 } 1067 break; 1068 } 1069 case Instruction::IF_GT: { 1070 if (shadow_frame.GetVReg(dec_insn.vA) > shadow_frame.GetVReg(dec_insn.vB)) { 1071 uint32_t dex_pc = inst->GetDexPc(insns); 1072 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC); 1073 } 1074 break; 1075 } 1076 case Instruction::IF_LE: { 1077 if (shadow_frame.GetVReg(dec_insn.vA) <= shadow_frame.GetVReg(dec_insn.vB)) { 1078 uint32_t dex_pc = inst->GetDexPc(insns); 1079 next_inst = Instruction::At(insns + dex_pc + dec_insn.vC); 1080 } 1081 break; 1082 } 1083 case Instruction::IF_EQZ: { 1084 if (shadow_frame.GetVReg(dec_insn.vA) == 0) { 1085 uint32_t dex_pc = inst->GetDexPc(insns); 1086 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB); 1087 } 1088 break; 1089 } 1090 case Instruction::IF_NEZ: { 1091 if (shadow_frame.GetVReg(dec_insn.vA) != 0) { 1092 uint32_t dex_pc = inst->GetDexPc(insns); 1093 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB); 1094 } 1095 break; 1096 } 1097 case Instruction::IF_LTZ: { 1098 if (shadow_frame.GetVReg(dec_insn.vA) < 0) { 1099 uint32_t dex_pc = inst->GetDexPc(insns); 1100 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB); 1101 } 1102 break; 1103 } 1104 case Instruction::IF_GEZ: { 1105 if (shadow_frame.GetVReg(dec_insn.vA) >= 0) { 1106 uint32_t dex_pc = inst->GetDexPc(insns); 1107 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB); 1108 } 1109 break; 1110 } 1111 case Instruction::IF_GTZ: { 1112 if (shadow_frame.GetVReg(dec_insn.vA) > 0) { 1113 uint32_t dex_pc = inst->GetDexPc(insns); 1114 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB); 1115 } 1116 break; 1117 } 1118 case Instruction::IF_LEZ: { 1119 if (shadow_frame.GetVReg(dec_insn.vA) <= 0) { 1120 uint32_t dex_pc = inst->GetDexPc(insns); 1121 next_inst = Instruction::At(insns + dex_pc + dec_insn.vB); 1122 } 1123 break; 1124 } 1125 case Instruction::AGET_BOOLEAN: { 1126 Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1127 if (UNLIKELY(a == NULL)) { 1128 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1129 break; 1130 } 1131 int32_t index = shadow_frame.GetVReg(dec_insn.vC); 1132 shadow_frame.SetVReg(dec_insn.vA, a->AsBooleanArray()->Get(index)); 1133 break; 1134 } 1135 case Instruction::AGET_BYTE: { 1136 Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1137 if (UNLIKELY(a == NULL)) { 1138 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1139 break; 1140 } 1141 int32_t index = shadow_frame.GetVReg(dec_insn.vC); 1142 shadow_frame.SetVReg(dec_insn.vA, a->AsByteArray()->Get(index)); 1143 break; 1144 } 1145 case Instruction::AGET_CHAR: { 1146 Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1147 if (UNLIKELY(a == NULL)) { 1148 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1149 break; 1150 } 1151 int32_t index = shadow_frame.GetVReg(dec_insn.vC); 1152 shadow_frame.SetVReg(dec_insn.vA, a->AsCharArray()->Get(index)); 1153 break; 1154 } 1155 case Instruction::AGET_SHORT: { 1156 Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1157 if (UNLIKELY(a == NULL)) { 1158 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1159 break; 1160 } 1161 int32_t index = shadow_frame.GetVReg(dec_insn.vC); 1162 shadow_frame.SetVReg(dec_insn.vA, a->AsShortArray()->Get(index)); 1163 break; 1164 } 1165 case Instruction::AGET: { 1166 Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1167 if (UNLIKELY(a == NULL)) { 1168 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1169 break; 1170 } 1171 int32_t index = shadow_frame.GetVReg(dec_insn.vC); 1172 shadow_frame.SetVReg(dec_insn.vA, a->AsIntArray()->Get(index)); 1173 break; 1174 } 1175 case Instruction::AGET_WIDE: { 1176 Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1177 if (UNLIKELY(a == NULL)) { 1178 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1179 break; 1180 } 1181 int32_t index = shadow_frame.GetVReg(dec_insn.vC); 1182 shadow_frame.SetVRegLong(dec_insn.vA, a->AsLongArray()->Get(index)); 1183 break; 1184 } 1185 case Instruction::AGET_OBJECT: { 1186 Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1187 if (UNLIKELY(a == NULL)) { 1188 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1189 break; 1190 } 1191 int32_t index = shadow_frame.GetVReg(dec_insn.vC); 1192 shadow_frame.SetVRegReference(dec_insn.vA, a->AsObjectArray<Object>()->Get(index)); 1193 break; 1194 } 1195 case Instruction::APUT_BOOLEAN: { 1196 uint8_t val = shadow_frame.GetVReg(dec_insn.vA); 1197 Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1198 if (UNLIKELY(a == NULL)) { 1199 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1200 break; 1201 } 1202 int32_t index = shadow_frame.GetVReg(dec_insn.vC); 1203 a->AsBooleanArray()->Set(index, val); 1204 break; 1205 } 1206 case Instruction::APUT_BYTE: { 1207 int8_t val = shadow_frame.GetVReg(dec_insn.vA); 1208 Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1209 if (UNLIKELY(a == NULL)) { 1210 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1211 break; 1212 } 1213 int32_t index = shadow_frame.GetVReg(dec_insn.vC); 1214 a->AsByteArray()->Set(index, val); 1215 break; 1216 } 1217 case Instruction::APUT_CHAR: { 1218 uint16_t val = shadow_frame.GetVReg(dec_insn.vA); 1219 Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1220 if (UNLIKELY(a == NULL)) { 1221 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1222 break; 1223 } 1224 int32_t index = shadow_frame.GetVReg(dec_insn.vC); 1225 a->AsCharArray()->Set(index, val); 1226 break; 1227 } 1228 case Instruction::APUT_SHORT: { 1229 int16_t val = shadow_frame.GetVReg(dec_insn.vA); 1230 Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1231 if (UNLIKELY(a == NULL)) { 1232 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1233 break; 1234 } 1235 int32_t index = shadow_frame.GetVReg(dec_insn.vC); 1236 a->AsShortArray()->Set(index, val); 1237 break; 1238 } 1239 case Instruction::APUT: { 1240 int32_t val = shadow_frame.GetVReg(dec_insn.vA); 1241 Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1242 if (UNLIKELY(a == NULL)) { 1243 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1244 break; 1245 } 1246 int32_t index = shadow_frame.GetVReg(dec_insn.vC); 1247 a->AsIntArray()->Set(index, val); 1248 break; 1249 } 1250 case Instruction::APUT_WIDE: { 1251 int64_t val = shadow_frame.GetVRegLong(dec_insn.vA); 1252 Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1253 if (UNLIKELY(a == NULL)) { 1254 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1255 break; 1256 } 1257 int32_t index = shadow_frame.GetVReg(dec_insn.vC); 1258 a->AsLongArray()->Set(index, val); 1259 break; 1260 } 1261 case Instruction::APUT_OBJECT: { 1262 Object* val = shadow_frame.GetVRegReference(dec_insn.vA); 1263 Object* a = shadow_frame.GetVRegReference(dec_insn.vB); 1264 if (UNLIKELY(a == NULL)) { 1265 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1266 break; 1267 } 1268 int32_t index = shadow_frame.GetVReg(dec_insn.vC); 1269 a->AsObjectArray<Object>()->Set(index, val); 1270 break; 1271 } 1272 case Instruction::IGET_BOOLEAN: 1273 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimBoolean); 1274 break; 1275 case Instruction::IGET_BYTE: 1276 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimByte); 1277 break; 1278 case Instruction::IGET_CHAR: 1279 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimChar); 1280 break; 1281 case Instruction::IGET_SHORT: 1282 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimShort); 1283 break; 1284 case Instruction::IGET: 1285 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimInt); 1286 break; 1287 case Instruction::IGET_WIDE: 1288 DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimLong); 1289 break; 1290 case Instruction::IGET_OBJECT: 1291 DoFieldGet(self, shadow_frame, dec_insn, InstanceObjectRead, Primitive::kPrimNot); 1292 break; 1293 case Instruction::SGET_BOOLEAN: 1294 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimBoolean); 1295 break; 1296 case Instruction::SGET_BYTE: 1297 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimByte); 1298 break; 1299 case Instruction::SGET_CHAR: 1300 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimChar); 1301 break; 1302 case Instruction::SGET_SHORT: 1303 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimShort); 1304 break; 1305 case Instruction::SGET: 1306 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimInt); 1307 break; 1308 case Instruction::SGET_WIDE: 1309 DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimLong); 1310 break; 1311 case Instruction::SGET_OBJECT: 1312 DoFieldGet(self, shadow_frame, dec_insn, StaticObjectRead, Primitive::kPrimNot); 1313 break; 1314 case Instruction::IPUT_BOOLEAN: 1315 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimBoolean); 1316 break; 1317 case Instruction::IPUT_BYTE: 1318 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimByte); 1319 break; 1320 case Instruction::IPUT_CHAR: 1321 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimChar); 1322 break; 1323 case Instruction::IPUT_SHORT: 1324 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimShort); 1325 break; 1326 case Instruction::IPUT: 1327 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimInt); 1328 break; 1329 case Instruction::IPUT_WIDE: 1330 DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimLong); 1331 break; 1332 case Instruction::IPUT_OBJECT: 1333 DoFieldPut(self, shadow_frame, dec_insn, InstanceObjectWrite, Primitive::kPrimNot); 1334 break; 1335 case Instruction::SPUT_BOOLEAN: 1336 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimBoolean); 1337 break; 1338 case Instruction::SPUT_BYTE: 1339 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimByte); 1340 break; 1341 case Instruction::SPUT_CHAR: 1342 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimChar); 1343 break; 1344 case Instruction::SPUT_SHORT: 1345 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimShort); 1346 break; 1347 case Instruction::SPUT: 1348 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimInt); 1349 break; 1350 case Instruction::SPUT_WIDE: 1351 DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimLong); 1352 break; 1353 case Instruction::SPUT_OBJECT: 1354 DoFieldPut(self, shadow_frame, dec_insn, StaticObjectWrite, Primitive::kPrimNot); 1355 break; 1356 case Instruction::INVOKE_VIRTUAL: 1357 DoInvoke(self, mh, shadow_frame, dec_insn, kVirtual, false, &result_register); 1358 break; 1359 case Instruction::INVOKE_VIRTUAL_RANGE: 1360 DoInvoke(self, mh, shadow_frame, dec_insn, kVirtual, true, &result_register); 1361 break; 1362 case Instruction::INVOKE_SUPER: 1363 DoInvoke(self, mh, shadow_frame, dec_insn, kSuper, false, &result_register); 1364 break; 1365 case Instruction::INVOKE_SUPER_RANGE: 1366 DoInvoke(self, mh, shadow_frame, dec_insn, kSuper, true, &result_register); 1367 break; 1368 case Instruction::INVOKE_DIRECT: 1369 DoInvoke(self, mh, shadow_frame, dec_insn, kDirect, false, &result_register); 1370 break; 1371 case Instruction::INVOKE_DIRECT_RANGE: 1372 DoInvoke(self, mh, shadow_frame, dec_insn, kDirect, true, &result_register); 1373 break; 1374 case Instruction::INVOKE_INTERFACE: 1375 DoInvoke(self, mh, shadow_frame, dec_insn, kInterface, false, &result_register); 1376 break; 1377 case Instruction::INVOKE_INTERFACE_RANGE: 1378 DoInvoke(self, mh, shadow_frame, dec_insn, kInterface, true, &result_register); 1379 break; 1380 case Instruction::INVOKE_STATIC: 1381 DoInvoke(self, mh, shadow_frame, dec_insn, kStatic, false, &result_register); 1382 break; 1383 case Instruction::INVOKE_STATIC_RANGE: 1384 DoInvoke(self, mh, shadow_frame, dec_insn, kStatic, true, &result_register); 1385 break; 1386 case Instruction::NEG_INT: 1387 shadow_frame.SetVReg(dec_insn.vA, -shadow_frame.GetVReg(dec_insn.vB)); 1388 break; 1389 case Instruction::NOT_INT: 1390 shadow_frame.SetVReg(dec_insn.vA, ~shadow_frame.GetVReg(dec_insn.vB)); 1391 break; 1392 case Instruction::NEG_LONG: 1393 shadow_frame.SetVRegLong(dec_insn.vA, -shadow_frame.GetVRegLong(dec_insn.vB)); 1394 break; 1395 case Instruction::NOT_LONG: 1396 shadow_frame.SetVRegLong(dec_insn.vA, ~shadow_frame.GetVRegLong(dec_insn.vB)); 1397 break; 1398 case Instruction::NEG_FLOAT: 1399 shadow_frame.SetVRegFloat(dec_insn.vA, -shadow_frame.GetVRegFloat(dec_insn.vB)); 1400 break; 1401 case Instruction::NEG_DOUBLE: 1402 shadow_frame.SetVRegDouble(dec_insn.vA, -shadow_frame.GetVRegDouble(dec_insn.vB)); 1403 break; 1404 case Instruction::INT_TO_LONG: 1405 shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB)); 1406 break; 1407 case Instruction::INT_TO_FLOAT: 1408 shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB)); 1409 break; 1410 case Instruction::INT_TO_DOUBLE: 1411 shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB)); 1412 break; 1413 case Instruction::LONG_TO_INT: 1414 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB)); 1415 break; 1416 case Instruction::LONG_TO_FLOAT: 1417 shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB)); 1418 break; 1419 case Instruction::LONG_TO_DOUBLE: 1420 shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB)); 1421 break; 1422 case Instruction::FLOAT_TO_INT: { 1423 float val = shadow_frame.GetVRegFloat(dec_insn.vB); 1424 if (val != val) { 1425 shadow_frame.SetVReg(dec_insn.vA, 0); 1426 } else if (val > static_cast<float>(kMaxInt)) { 1427 shadow_frame.SetVReg(dec_insn.vA, kMaxInt); 1428 } else if (val < static_cast<float>(kMinInt)) { 1429 shadow_frame.SetVReg(dec_insn.vA, kMinInt); 1430 } else { 1431 shadow_frame.SetVReg(dec_insn.vA, val); 1432 } 1433 break; 1434 } 1435 case Instruction::FLOAT_TO_LONG: { 1436 float val = shadow_frame.GetVRegFloat(dec_insn.vB); 1437 if (val != val) { 1438 shadow_frame.SetVRegLong(dec_insn.vA, 0); 1439 } else if (val > static_cast<float>(kMaxLong)) { 1440 shadow_frame.SetVRegLong(dec_insn.vA, kMaxLong); 1441 } else if (val < static_cast<float>(kMinLong)) { 1442 shadow_frame.SetVRegLong(dec_insn.vA, kMinLong); 1443 } else { 1444 shadow_frame.SetVRegLong(dec_insn.vA, val); 1445 } 1446 break; 1447 } 1448 case Instruction::FLOAT_TO_DOUBLE: 1449 shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVRegFloat(dec_insn.vB)); 1450 break; 1451 case Instruction::DOUBLE_TO_INT: { 1452 double val = shadow_frame.GetVRegDouble(dec_insn.vB); 1453 if (val != val) { 1454 shadow_frame.SetVReg(dec_insn.vA, 0); 1455 } else if (val > static_cast<double>(kMaxInt)) { 1456 shadow_frame.SetVReg(dec_insn.vA, kMaxInt); 1457 } else if (val < static_cast<double>(kMinInt)) { 1458 shadow_frame.SetVReg(dec_insn.vA, kMinInt); 1459 } else { 1460 shadow_frame.SetVReg(dec_insn.vA, val); 1461 } 1462 break; 1463 } 1464 case Instruction::DOUBLE_TO_LONG: { 1465 double val = shadow_frame.GetVRegDouble(dec_insn.vB); 1466 if (val != val) { 1467 shadow_frame.SetVRegLong(dec_insn.vA, 0); 1468 } else if (val > static_cast<double>(kMaxLong)) { 1469 shadow_frame.SetVRegLong(dec_insn.vA, kMaxLong); 1470 } else if (val < static_cast<double>(kMinLong)) { 1471 shadow_frame.SetVRegLong(dec_insn.vA, kMinLong); 1472 } else { 1473 shadow_frame.SetVRegLong(dec_insn.vA, val); 1474 } 1475 break; 1476 } 1477 case Instruction::DOUBLE_TO_FLOAT: 1478 shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVRegDouble(dec_insn.vB)); 1479 break; 1480 case Instruction::INT_TO_BYTE: 1481 shadow_frame.SetVReg(dec_insn.vA, static_cast<int8_t>(shadow_frame.GetVReg(dec_insn.vB))); 1482 break; 1483 case Instruction::INT_TO_CHAR: 1484 shadow_frame.SetVReg(dec_insn.vA, static_cast<uint16_t>(shadow_frame.GetVReg(dec_insn.vB))); 1485 break; 1486 case Instruction::INT_TO_SHORT: 1487 shadow_frame.SetVReg(dec_insn.vA, static_cast<int16_t>(shadow_frame.GetVReg(dec_insn.vB))); 1488 break; 1489 case Instruction::ADD_INT: 1490 shadow_frame.SetVReg(dec_insn.vA, 1491 shadow_frame.GetVReg(dec_insn.vB) + shadow_frame.GetVReg(dec_insn.vC)); 1492 break; 1493 case Instruction::SUB_INT: 1494 shadow_frame.SetVReg(dec_insn.vA, 1495 shadow_frame.GetVReg(dec_insn.vB) - shadow_frame.GetVReg(dec_insn.vC)); 1496 break; 1497 case Instruction::MUL_INT: 1498 shadow_frame.SetVReg(dec_insn.vA, 1499 shadow_frame.GetVReg(dec_insn.vB) * shadow_frame.GetVReg(dec_insn.vC)); 1500 break; 1501 case Instruction::REM_INT: 1502 DoIntRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB), 1503 shadow_frame.GetVReg(dec_insn.vC)); 1504 break; 1505 case Instruction::DIV_INT: 1506 DoIntDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB), 1507 shadow_frame.GetVReg(dec_insn.vC)); 1508 break; 1509 case Instruction::SHL_INT: 1510 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) << 1511 (shadow_frame.GetVReg(dec_insn.vC) & 0x1f)); 1512 break; 1513 case Instruction::SHR_INT: 1514 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) >> 1515 (shadow_frame.GetVReg(dec_insn.vC) & 0x1f)); 1516 break; 1517 case Instruction::USHR_INT: 1518 shadow_frame.SetVReg(dec_insn.vA, 1519 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vB)) >> 1520 (shadow_frame.GetVReg(dec_insn.vC) & 0x1f)); 1521 break; 1522 case Instruction::AND_INT: 1523 shadow_frame.SetVReg(dec_insn.vA, 1524 shadow_frame.GetVReg(dec_insn.vB) & shadow_frame.GetVReg(dec_insn.vC)); 1525 break; 1526 case Instruction::OR_INT: 1527 shadow_frame.SetVReg(dec_insn.vA, 1528 shadow_frame.GetVReg(dec_insn.vB) | shadow_frame.GetVReg(dec_insn.vC)); 1529 break; 1530 case Instruction::XOR_INT: 1531 shadow_frame.SetVReg(dec_insn.vA, 1532 shadow_frame.GetVReg(dec_insn.vB) ^ shadow_frame.GetVReg(dec_insn.vC)); 1533 break; 1534 case Instruction::ADD_LONG: 1535 shadow_frame.SetVRegLong(dec_insn.vA, 1536 shadow_frame.GetVRegLong(dec_insn.vB) + 1537 shadow_frame.GetVRegLong(dec_insn.vC)); 1538 break; 1539 case Instruction::SUB_LONG: 1540 shadow_frame.SetVRegLong(dec_insn.vA, 1541 shadow_frame.GetVRegLong(dec_insn.vB) - 1542 shadow_frame.GetVRegLong(dec_insn.vC)); 1543 break; 1544 case Instruction::MUL_LONG: 1545 shadow_frame.SetVRegLong(dec_insn.vA, 1546 shadow_frame.GetVRegLong(dec_insn.vB) * 1547 shadow_frame.GetVRegLong(dec_insn.vC)); 1548 break; 1549 case Instruction::DIV_LONG: 1550 DoLongDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB), 1551 shadow_frame.GetVRegLong(dec_insn.vC)); 1552 break; 1553 case Instruction::REM_LONG: 1554 DoLongRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB), 1555 shadow_frame.GetVRegLong(dec_insn.vC)); 1556 break; 1557 case Instruction::AND_LONG: 1558 shadow_frame.SetVRegLong(dec_insn.vA, 1559 shadow_frame.GetVRegLong(dec_insn.vB) & 1560 shadow_frame.GetVRegLong(dec_insn.vC)); 1561 break; 1562 case Instruction::OR_LONG: 1563 shadow_frame.SetVRegLong(dec_insn.vA, 1564 shadow_frame.GetVRegLong(dec_insn.vB) | 1565 shadow_frame.GetVRegLong(dec_insn.vC)); 1566 break; 1567 case Instruction::XOR_LONG: 1568 shadow_frame.SetVRegLong(dec_insn.vA, 1569 shadow_frame.GetVRegLong(dec_insn.vB) ^ 1570 shadow_frame.GetVRegLong(dec_insn.vC)); 1571 break; 1572 case Instruction::SHL_LONG: 1573 shadow_frame.SetVRegLong(dec_insn.vA, 1574 shadow_frame.GetVRegLong(dec_insn.vB) << 1575 (shadow_frame.GetVReg(dec_insn.vC) & 0x3f)); 1576 break; 1577 case Instruction::SHR_LONG: 1578 shadow_frame.SetVRegLong(dec_insn.vA, 1579 shadow_frame.GetVRegLong(dec_insn.vB) >> 1580 (shadow_frame.GetVReg(dec_insn.vC) & 0x3f)); 1581 break; 1582 case Instruction::USHR_LONG: 1583 shadow_frame.SetVRegLong(dec_insn.vA, 1584 static_cast<uint64_t>(shadow_frame.GetVRegLong(dec_insn.vB)) >> 1585 (shadow_frame.GetVReg(dec_insn.vC) & 0x3f)); 1586 break; 1587 case Instruction::ADD_FLOAT: 1588 shadow_frame.SetVRegFloat(dec_insn.vA, 1589 shadow_frame.GetVRegFloat(dec_insn.vB) + 1590 shadow_frame.GetVRegFloat(dec_insn.vC)); 1591 break; 1592 case Instruction::SUB_FLOAT: 1593 shadow_frame.SetVRegFloat(dec_insn.vA, 1594 shadow_frame.GetVRegFloat(dec_insn.vB) - 1595 shadow_frame.GetVRegFloat(dec_insn.vC)); 1596 break; 1597 case Instruction::MUL_FLOAT: 1598 shadow_frame.SetVRegFloat(dec_insn.vA, 1599 shadow_frame.GetVRegFloat(dec_insn.vB) * 1600 shadow_frame.GetVRegFloat(dec_insn.vC)); 1601 break; 1602 case Instruction::DIV_FLOAT: 1603 shadow_frame.SetVRegFloat(dec_insn.vA, 1604 shadow_frame.GetVRegFloat(dec_insn.vB) / 1605 shadow_frame.GetVRegFloat(dec_insn.vC)); 1606 break; 1607 case Instruction::REM_FLOAT: 1608 shadow_frame.SetVRegFloat(dec_insn.vA, 1609 fmodf(shadow_frame.GetVRegFloat(dec_insn.vB), 1610 shadow_frame.GetVRegFloat(dec_insn.vC))); 1611 break; 1612 case Instruction::ADD_DOUBLE: 1613 shadow_frame.SetVRegDouble(dec_insn.vA, 1614 shadow_frame.GetVRegDouble(dec_insn.vB) + 1615 shadow_frame.GetVRegDouble(dec_insn.vC)); 1616 break; 1617 case Instruction::SUB_DOUBLE: 1618 shadow_frame.SetVRegDouble(dec_insn.vA, 1619 shadow_frame.GetVRegDouble(dec_insn.vB) - 1620 shadow_frame.GetVRegDouble(dec_insn.vC)); 1621 break; 1622 case Instruction::MUL_DOUBLE: 1623 shadow_frame.SetVRegDouble(dec_insn.vA, 1624 shadow_frame.GetVRegDouble(dec_insn.vB) * 1625 shadow_frame.GetVRegDouble(dec_insn.vC)); 1626 break; 1627 case Instruction::DIV_DOUBLE: 1628 shadow_frame.SetVRegDouble(dec_insn.vA, 1629 shadow_frame.GetVRegDouble(dec_insn.vB) / 1630 shadow_frame.GetVRegDouble(dec_insn.vC)); 1631 break; 1632 case Instruction::REM_DOUBLE: 1633 shadow_frame.SetVRegDouble(dec_insn.vA, 1634 fmod(shadow_frame.GetVRegDouble(dec_insn.vB), 1635 shadow_frame.GetVRegDouble(dec_insn.vC))); 1636 break; 1637 case Instruction::ADD_INT_2ADDR: 1638 shadow_frame.SetVReg(dec_insn.vA, 1639 shadow_frame.GetVReg(dec_insn.vA) + shadow_frame.GetVReg(dec_insn.vB)); 1640 break; 1641 case Instruction::SUB_INT_2ADDR: 1642 shadow_frame.SetVReg(dec_insn.vA, 1643 shadow_frame.GetVReg(dec_insn.vA) - shadow_frame.GetVReg(dec_insn.vB)); 1644 break; 1645 case Instruction::MUL_INT_2ADDR: 1646 shadow_frame.SetVReg(dec_insn.vA, 1647 shadow_frame.GetVReg(dec_insn.vA) * shadow_frame.GetVReg(dec_insn.vB)); 1648 break; 1649 case Instruction::REM_INT_2ADDR: 1650 DoIntRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA), 1651 shadow_frame.GetVReg(dec_insn.vB)); 1652 break; 1653 case Instruction::SHL_INT_2ADDR: 1654 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA) << 1655 (shadow_frame.GetVReg(dec_insn.vB) & 0x1f)); 1656 break; 1657 case Instruction::SHR_INT_2ADDR: 1658 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA) >> 1659 (shadow_frame.GetVReg(dec_insn.vB) & 0x1f)); 1660 break; 1661 case Instruction::USHR_INT_2ADDR: 1662 shadow_frame.SetVReg(dec_insn.vA, 1663 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vA)) >> 1664 (shadow_frame.GetVReg(dec_insn.vB) & 0x1f)); 1665 break; 1666 case Instruction::AND_INT_2ADDR: 1667 shadow_frame.SetVReg(dec_insn.vA, 1668 shadow_frame.GetVReg(dec_insn.vA) & shadow_frame.GetVReg(dec_insn.vB)); 1669 break; 1670 case Instruction::OR_INT_2ADDR: 1671 shadow_frame.SetVReg(dec_insn.vA, 1672 shadow_frame.GetVReg(dec_insn.vA) | shadow_frame.GetVReg(dec_insn.vB)); 1673 break; 1674 case Instruction::XOR_INT_2ADDR: 1675 shadow_frame.SetVReg(dec_insn.vA, 1676 shadow_frame.GetVReg(dec_insn.vA) ^ shadow_frame.GetVReg(dec_insn.vB)); 1677 break; 1678 case Instruction::DIV_INT_2ADDR: 1679 DoIntDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA), 1680 shadow_frame.GetVReg(dec_insn.vB)); 1681 break; 1682 case Instruction::ADD_LONG_2ADDR: 1683 shadow_frame.SetVRegLong(dec_insn.vA, 1684 shadow_frame.GetVRegLong(dec_insn.vA) + 1685 shadow_frame.GetVRegLong(dec_insn.vB)); 1686 break; 1687 case Instruction::SUB_LONG_2ADDR: 1688 shadow_frame.SetVRegLong(dec_insn.vA, 1689 shadow_frame.GetVRegLong(dec_insn.vA) - 1690 shadow_frame.GetVRegLong(dec_insn.vB)); 1691 break; 1692 case Instruction::MUL_LONG_2ADDR: 1693 shadow_frame.SetVRegLong(dec_insn.vA, 1694 shadow_frame.GetVRegLong(dec_insn.vA) * 1695 shadow_frame.GetVRegLong(dec_insn.vB)); 1696 break; 1697 case Instruction::DIV_LONG_2ADDR: 1698 DoLongDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vA), 1699 shadow_frame.GetVRegLong(dec_insn.vB)); 1700 break; 1701 case Instruction::REM_LONG_2ADDR: 1702 DoLongRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vA), 1703 shadow_frame.GetVRegLong(dec_insn.vB)); 1704 break; 1705 case Instruction::AND_LONG_2ADDR: 1706 shadow_frame.SetVRegLong(dec_insn.vA, 1707 shadow_frame.GetVRegLong(dec_insn.vA) & 1708 shadow_frame.GetVRegLong(dec_insn.vB)); 1709 break; 1710 case Instruction::OR_LONG_2ADDR: 1711 shadow_frame.SetVRegLong(dec_insn.vA, 1712 shadow_frame.GetVRegLong(dec_insn.vA) | 1713 shadow_frame.GetVRegLong(dec_insn.vB)); 1714 break; 1715 case Instruction::XOR_LONG_2ADDR: 1716 shadow_frame.SetVRegLong(dec_insn.vA, 1717 shadow_frame.GetVRegLong(dec_insn.vA) ^ 1718 shadow_frame.GetVRegLong(dec_insn.vB)); 1719 break; 1720 case Instruction::SHL_LONG_2ADDR: 1721 shadow_frame.SetVRegLong(dec_insn.vA, 1722 shadow_frame.GetVRegLong(dec_insn.vA) << 1723 (shadow_frame.GetVReg(dec_insn.vB) & 0x3f)); 1724 break; 1725 case Instruction::SHR_LONG_2ADDR: 1726 shadow_frame.SetVRegLong(dec_insn.vA, 1727 shadow_frame.GetVRegLong(dec_insn.vA) >> 1728 (shadow_frame.GetVReg(dec_insn.vB) & 0x3f)); 1729 break; 1730 case Instruction::USHR_LONG_2ADDR: 1731 shadow_frame.SetVRegLong(dec_insn.vA, 1732 static_cast<uint64_t>(shadow_frame.GetVRegLong(dec_insn.vA)) >> 1733 (shadow_frame.GetVReg(dec_insn.vB) & 0x3f)); 1734 break; 1735 case Instruction::ADD_FLOAT_2ADDR: 1736 shadow_frame.SetVRegFloat(dec_insn.vA, 1737 shadow_frame.GetVRegFloat(dec_insn.vA) + 1738 shadow_frame.GetVRegFloat(dec_insn.vB)); 1739 break; 1740 case Instruction::SUB_FLOAT_2ADDR: 1741 shadow_frame.SetVRegFloat(dec_insn.vA, 1742 shadow_frame.GetVRegFloat(dec_insn.vA) - 1743 shadow_frame.GetVRegFloat(dec_insn.vB)); 1744 break; 1745 case Instruction::MUL_FLOAT_2ADDR: 1746 shadow_frame.SetVRegFloat(dec_insn.vA, 1747 shadow_frame.GetVRegFloat(dec_insn.vA) * 1748 shadow_frame.GetVRegFloat(dec_insn.vB)); 1749 break; 1750 case Instruction::DIV_FLOAT_2ADDR: 1751 shadow_frame.SetVRegFloat(dec_insn.vA, 1752 shadow_frame.GetVRegFloat(dec_insn.vA) / 1753 shadow_frame.GetVRegFloat(dec_insn.vB)); 1754 break; 1755 case Instruction::REM_FLOAT_2ADDR: 1756 shadow_frame.SetVRegFloat(dec_insn.vA, 1757 fmodf(shadow_frame.GetVRegFloat(dec_insn.vA), 1758 shadow_frame.GetVRegFloat(dec_insn.vB))); 1759 break; 1760 case Instruction::ADD_DOUBLE_2ADDR: 1761 shadow_frame.SetVRegDouble(dec_insn.vA, 1762 shadow_frame.GetVRegDouble(dec_insn.vA) + 1763 shadow_frame.GetVRegDouble(dec_insn.vB)); 1764 break; 1765 case Instruction::SUB_DOUBLE_2ADDR: 1766 shadow_frame.SetVRegDouble(dec_insn.vA, 1767 shadow_frame.GetVRegDouble(dec_insn.vA) - 1768 shadow_frame.GetVRegDouble(dec_insn.vB)); 1769 break; 1770 case Instruction::MUL_DOUBLE_2ADDR: 1771 shadow_frame.SetVRegDouble(dec_insn.vA, 1772 shadow_frame.GetVRegDouble(dec_insn.vA) * 1773 shadow_frame.GetVRegDouble(dec_insn.vB)); 1774 break; 1775 case Instruction::DIV_DOUBLE_2ADDR: 1776 shadow_frame.SetVRegDouble(dec_insn.vA, 1777 shadow_frame.GetVRegDouble(dec_insn.vA) / 1778 shadow_frame.GetVRegDouble(dec_insn.vB)); 1779 break; 1780 case Instruction::REM_DOUBLE_2ADDR: 1781 shadow_frame.SetVRegDouble(dec_insn.vA, 1782 fmod(shadow_frame.GetVRegDouble(dec_insn.vA), 1783 shadow_frame.GetVRegDouble(dec_insn.vB))); 1784 break; 1785 case Instruction::ADD_INT_LIT16: 1786 case Instruction::ADD_INT_LIT8: 1787 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) + dec_insn.vC); 1788 break; 1789 case Instruction::RSUB_INT: 1790 case Instruction::RSUB_INT_LIT8: 1791 shadow_frame.SetVReg(dec_insn.vA, dec_insn.vC - shadow_frame.GetVReg(dec_insn.vB)); 1792 break; 1793 case Instruction::MUL_INT_LIT16: 1794 case Instruction::MUL_INT_LIT8: 1795 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) * dec_insn.vC); 1796 break; 1797 case Instruction::DIV_INT_LIT16: 1798 case Instruction::DIV_INT_LIT8: 1799 DoIntDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB), 1800 dec_insn.vC); 1801 break; 1802 case Instruction::REM_INT_LIT16: 1803 case Instruction::REM_INT_LIT8: 1804 DoIntRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB), 1805 dec_insn.vC); 1806 break; 1807 case Instruction::AND_INT_LIT16: 1808 case Instruction::AND_INT_LIT8: 1809 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) & dec_insn.vC); 1810 break; 1811 case Instruction::OR_INT_LIT16: 1812 case Instruction::OR_INT_LIT8: 1813 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) | dec_insn.vC); 1814 break; 1815 case Instruction::XOR_INT_LIT16: 1816 case Instruction::XOR_INT_LIT8: 1817 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) ^ dec_insn.vC); 1818 break; 1819 case Instruction::SHL_INT_LIT8: 1820 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) << 1821 (dec_insn.vC & 0x1f)); 1822 break; 1823 case Instruction::SHR_INT_LIT8: 1824 shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) >> 1825 (dec_insn.vC & 0x1f)); 1826 break; 1827 case Instruction::USHR_INT_LIT8: 1828 shadow_frame.SetVReg(dec_insn.vA, 1829 static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vB)) >> 1830 (dec_insn.vC & 0x1f)); 1831 break; 1832 default: 1833 LOG(FATAL) << "Unexpected instruction: " << inst->DumpString(&mh.GetDexFile()); 1834 break; 1835 } 1836 if (UNLIKELY(self->IsExceptionPending())) { 1837 self->VerifyStack(); 1838 ThrowLocation throw_location; 1839 mirror::Throwable* exception = self->GetException(&throw_location); 1840 uint32_t found_dex_pc = 1841 shadow_frame.GetMethod()->FindCatchBlock(exception->GetClass(), inst->GetDexPc(insns)); 1842 if (found_dex_pc == DexFile::kDexNoIndex) { 1843 JValue result; 1844 result.SetJ(0); 1845 instrumentation->MethodUnwindEvent(self, shadow_frame.GetThisObject(), 1846 shadow_frame.GetMethod(), shadow_frame.GetDexPC()); 1847 return result; // Handler in caller. 1848 } else { 1849 Runtime::Current()->GetInstrumentation()->ExceptionCaughtEvent(self, throw_location, 1850 shadow_frame.GetMethod(), 1851 found_dex_pc, exception); 1852 next_inst = Instruction::At(insns + found_dex_pc); 1853 } 1854 } 1855 inst = next_inst; 1856 } 1857} 1858 1859void EnterInterpreterFromInvoke(Thread* self, AbstractMethod* method, Object* receiver, 1860 uint32_t* args, JValue* result) { 1861 DCHECK_EQ(self, Thread::Current()); 1862 if (__builtin_frame_address(0) < self->GetStackEnd()) { 1863 ThrowStackOverflowError(self); 1864 return; 1865 } 1866 1867 MethodHelper mh(method); 1868 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 1869 uint16_t num_regs; 1870 uint16_t num_ins; 1871 if (code_item != NULL) { 1872 num_regs = code_item->registers_size_; 1873 num_ins = code_item->ins_size_; 1874 } else if (method->IsAbstract()) { 1875 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 1876 self->ThrowNewExceptionF(throw_location, "Ljava/lang/AbstractMethodError;", 1877 "abstract method \"%s\"", PrettyMethod(method).c_str()); 1878 return; 1879 } else { 1880 DCHECK(method->IsNative()); 1881 num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty()); 1882 if (!method->IsStatic()) { 1883 num_regs++; 1884 num_ins++; 1885 } 1886 } 1887 // Set up shadow frame with matching number of reference slots to vregs. 1888 ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame(); 1889 UniquePtr<ShadowFrame> shadow_frame(ShadowFrame::Create(num_regs, 1890 last_shadow_frame, 1891 method, 0)); 1892 self->PushShadowFrame(shadow_frame.get()); 1893 size_t cur_reg = num_regs - num_ins; 1894 if (!method->IsStatic()) { 1895 CHECK(receiver != NULL); 1896 shadow_frame->SetVRegReference(cur_reg, receiver); 1897 ++cur_reg; 1898 } else if (!method->GetDeclaringClass()->IsInitializing()) { 1899 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(), 1900 true, true)) { 1901 DCHECK(Thread::Current()->IsExceptionPending()); 1902 return; 1903 } 1904 CHECK(method->GetDeclaringClass()->IsInitializing()); 1905 } 1906 const char* shorty = mh.GetShorty(); 1907 for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) { 1908 DCHECK_LT(shorty_pos + 1, mh.GetShortyLength()); 1909 switch (shorty[shorty_pos + 1]) { 1910 case 'L': { 1911 Object* o = reinterpret_cast<Object*>(args[arg_pos]); 1912 shadow_frame->SetVRegReference(cur_reg, o); 1913 break; 1914 } 1915 case 'J': case 'D': { 1916 uint64_t wide_value = (static_cast<uint64_t>(args[arg_pos + 1]) << 32) | args[arg_pos]; 1917 shadow_frame->SetVRegLong(cur_reg, wide_value); 1918 cur_reg++; 1919 arg_pos++; 1920 break; 1921 } 1922 default: 1923 shadow_frame->SetVReg(cur_reg, args[arg_pos]); 1924 break; 1925 } 1926 } 1927 if (LIKELY(!method->IsNative())) { 1928 JValue r = Execute(self, mh, code_item, *shadow_frame.get(), JValue()); 1929 if (result != NULL) { 1930 *result = r; 1931 } 1932 } else { 1933 // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 1934 // generated stub) except during testing and image writing. 1935 if (!Runtime::Current()->IsStarted()) { 1936 UnstartedRuntimeJni(self, method, receiver, args, result); 1937 } else { 1938 InterpreterJni(self, method, shorty, receiver, args, result); 1939 } 1940 } 1941 self->PopShadowFrame(); 1942} 1943 1944void EnterInterpreterFromDeoptimize(Thread* self, ShadowFrame* shadow_frame, JValue* ret_val) 1945 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1946 JValue value; 1947 value.SetJ(ret_val->GetJ()); // Set value to last known result in case the shadow frame chain is empty. 1948 MethodHelper mh; 1949 while (shadow_frame != NULL) { 1950 self->SetTopOfShadowStack(shadow_frame); 1951 mh.ChangeMethod(shadow_frame->GetMethod()); 1952 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 1953 value = Execute(self, mh, code_item, *shadow_frame, value); 1954 ShadowFrame* old_frame = shadow_frame; 1955 shadow_frame = shadow_frame->GetLink(); 1956 delete old_frame; 1957 } 1958 ret_val->SetJ(value.GetJ()); 1959} 1960 1961JValue EnterInterpreterFromStub(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 1962 ShadowFrame& shadow_frame) 1963 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1964 DCHECK_EQ(self, Thread::Current()); 1965 if (__builtin_frame_address(0) < self->GetStackEnd()) { 1966 ThrowStackOverflowError(self); 1967 return JValue(); 1968 } 1969 1970 return Execute(self, mh, code_item, shadow_frame, JValue()); 1971} 1972 1973JValue EnterInterpreterFromInterpreter(Thread* self, ShadowFrame* shadow_frame) 1974 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 1975 if (__builtin_frame_address(0) < self->GetStackEnd()) { 1976 ThrowStackOverflowError(self); 1977 return JValue(); 1978 } 1979 1980 AbstractMethod* method = shadow_frame->GetMethod(); 1981 if (method->IsStatic() && !method->GetDeclaringClass()->IsInitializing()) { 1982 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(), 1983 true, true)) { 1984 DCHECK(Thread::Current()->IsExceptionPending()); 1985 return JValue(); 1986 } 1987 CHECK(method->GetDeclaringClass()->IsInitializing()); 1988 } 1989 1990 self->PushShadowFrame(shadow_frame); 1991 1992 MethodHelper mh(method); 1993 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 1994 JValue result; 1995 if (LIKELY(!method->IsNative())) { 1996 result = Execute(self, mh, code_item, *shadow_frame, JValue()); 1997 } else { 1998 // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 1999 // generated stub) except during testing and image writing. 2000 CHECK(!Runtime::Current()->IsStarted()); 2001 Object* receiver = method->IsStatic() ? NULL : shadow_frame->GetVRegReference(0); 2002 uint32_t* args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1); 2003 UnstartedRuntimeJni(self, method, receiver, args, &result); 2004 } 2005 2006 self->PopShadowFrame(); 2007 return result; 2008} 2009 2010} // namespace interpreter 2011} // namespace art 2012