interpreter.cc revision 807a25640d4f4de8143b160b3bb8f552ffbf6f4a
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 "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 Instruction* inst, InvokeType type, bool is_range, 388 JValue* result) 389 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 390 uint32_t vregC = (is_range) ? inst->VRegC_3rc() : inst->VRegC_35c(); 391 Object* receiver; 392 if (type == kStatic) { 393 receiver = NULL; 394 } else { 395 receiver = shadow_frame.GetVRegReference(vregC); 396 } 397 uint32_t method_idx = (is_range) ? inst->VRegB_3rc() : inst->VRegB_35c(); 398 AbstractMethod* target_method = FindMethodFromCode(method_idx, receiver, 399 shadow_frame.GetMethod(), 400 self, true, type); 401 if (UNLIKELY(target_method == NULL)) { 402 CHECK(self->IsExceptionPending()); 403 result->SetJ(0); 404 return; 405 } 406 mh.ChangeMethod(target_method); 407 408 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 409 uint16_t num_regs; 410 uint16_t num_ins; 411 if (code_item != NULL) { 412 num_regs = code_item->registers_size_; 413 num_ins = code_item->ins_size_; 414 } else if (target_method->IsAbstract()) { 415 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 416 self->ThrowNewExceptionF(throw_location, "Ljava/lang/AbstractMethodError;", 417 "abstract method \"%s\"", PrettyMethod(target_method).c_str()); 418 return; 419 } else { 420 DCHECK(target_method->IsNative() || target_method->IsProxyMethod()); 421 num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty()); 422 if (!target_method->IsStatic()) { 423 num_regs++; 424 num_ins++; 425 } 426 } 427 428 Runtime* runtime = Runtime::Current(); 429 UniquePtr<ShadowFrame> new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame, 430 target_method, 0)); 431 size_t cur_reg = num_regs - num_ins; 432 if (receiver != NULL) { 433 new_shadow_frame->SetVRegReference(cur_reg, receiver); 434 ++cur_reg; 435 } 436 437 size_t arg_offset = (receiver == NULL) ? 0 : 1; 438 const char* shorty = mh.GetShorty(); 439 uint32_t arg[5]; 440 if (!is_range) { 441 inst->GetArgs(arg); 442 } 443 for (size_t shorty_pos = 0; cur_reg < num_regs; ++shorty_pos, cur_reg++, arg_offset++) { 444 DCHECK_LT(shorty_pos + 1, mh.GetShortyLength()); 445 size_t arg_pos = is_range ? vregC + arg_offset : arg[arg_offset]; 446 switch (shorty[shorty_pos + 1]) { 447 case 'L': { 448 Object* o = shadow_frame.GetVRegReference(arg_pos); 449 new_shadow_frame->SetVRegReference(cur_reg, o); 450 break; 451 } 452 case 'J': case 'D': { 453 uint64_t wide_value = (static_cast<uint64_t>(shadow_frame.GetVReg(arg_pos + 1)) << 32) | 454 static_cast<uint32_t>(shadow_frame.GetVReg(arg_pos)); 455 new_shadow_frame->SetVRegLong(cur_reg, wide_value); 456 cur_reg++; 457 arg_offset++; 458 break; 459 } 460 default: 461 new_shadow_frame->SetVReg(cur_reg, shadow_frame.GetVReg(arg_pos)); 462 break; 463 } 464 } 465 466 if (LIKELY(runtime->IsStarted())) { 467 result->SetJ((target_method->GetEntryPointFromInterpreter())(self, new_shadow_frame.get()).GetJ()); 468 } else { 469 UnstartedRuntimeInvoke(self, target_method, new_shadow_frame.get(), result, num_regs - num_ins); 470 } 471 mh.ChangeMethod(shadow_frame.GetMethod()); 472} 473 474static void DoFieldGet(Thread* self, ShadowFrame& shadow_frame, 475 const Instruction* inst, FindFieldType find_type, 476 Primitive::Type field_type) 477 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 478 bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead); 479 uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c(); 480 Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self, 481 find_type, Primitive::FieldSize(field_type)); 482 if (UNLIKELY(f == NULL)) { 483 CHECK(self->IsExceptionPending()); 484 return; 485 } 486 Object* obj; 487 if (is_static) { 488 obj = f->GetDeclaringClass(); 489 } else { 490 obj = shadow_frame.GetVRegReference(inst->VRegB_22c()); 491 if (UNLIKELY(obj == NULL)) { 492 ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(), f, true); 493 return; 494 } 495 } 496 uint32_t vregA = is_static ? inst->VRegA_21c() : inst->VRegA_22c(); 497 switch (field_type) { 498 case Primitive::kPrimBoolean: 499 shadow_frame.SetVReg(vregA, f->GetBoolean(obj)); 500 break; 501 case Primitive::kPrimByte: 502 shadow_frame.SetVReg(vregA, f->GetByte(obj)); 503 break; 504 case Primitive::kPrimChar: 505 shadow_frame.SetVReg(vregA, f->GetChar(obj)); 506 break; 507 case Primitive::kPrimShort: 508 shadow_frame.SetVReg(vregA, f->GetShort(obj)); 509 break; 510 case Primitive::kPrimInt: 511 shadow_frame.SetVReg(vregA, f->GetInt(obj)); 512 break; 513 case Primitive::kPrimLong: 514 shadow_frame.SetVRegLong(vregA, f->GetLong(obj)); 515 break; 516 case Primitive::kPrimNot: 517 shadow_frame.SetVRegReference(vregA, f->GetObject(obj)); 518 break; 519 default: 520 LOG(FATAL) << "Unreachable: " << field_type; 521 } 522} 523 524static void DoFieldPut(Thread* self, ShadowFrame& shadow_frame, 525 const Instruction* inst, FindFieldType find_type, 526 Primitive::Type field_type) 527 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 528 bool is_static = (find_type == StaticObjectWrite) || (find_type == StaticPrimitiveWrite); 529 uint32_t field_idx = is_static ? inst->VRegB_21c() : inst->VRegC_22c(); 530 Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self, 531 find_type, Primitive::FieldSize(field_type)); 532 if (UNLIKELY(f == NULL)) { 533 CHECK(self->IsExceptionPending()); 534 return; 535 } 536 Object* obj; 537 if (is_static) { 538 obj = f->GetDeclaringClass(); 539 } else { 540 obj = shadow_frame.GetVRegReference(inst->VRegB_22c()); 541 if (UNLIKELY(obj == NULL)) { 542 ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(), 543 f, false); 544 return; 545 } 546 } 547 uint32_t vregA = is_static ? inst->VRegA_21c() : inst->VRegA_22c(); 548 switch (field_type) { 549 case Primitive::kPrimBoolean: 550 f->SetBoolean(obj, shadow_frame.GetVReg(vregA)); 551 break; 552 case Primitive::kPrimByte: 553 f->SetByte(obj, shadow_frame.GetVReg(vregA)); 554 break; 555 case Primitive::kPrimChar: 556 f->SetChar(obj, shadow_frame.GetVReg(vregA)); 557 break; 558 case Primitive::kPrimShort: 559 f->SetShort(obj, shadow_frame.GetVReg(vregA)); 560 break; 561 case Primitive::kPrimInt: 562 f->SetInt(obj, shadow_frame.GetVReg(vregA)); 563 break; 564 case Primitive::kPrimLong: 565 f->SetLong(obj, shadow_frame.GetVRegLong(vregA)); 566 break; 567 case Primitive::kPrimNot: 568 f->SetObj(obj, shadow_frame.GetVRegReference(vregA)); 569 break; 570 default: 571 LOG(FATAL) << "Unreachable: " << field_type; 572 } 573} 574 575static String* ResolveString(Thread* self, MethodHelper& mh, uint32_t string_idx) { 576 Class* java_lang_string_class = String::GetJavaLangString(); 577 if (UNLIKELY(!java_lang_string_class->IsInitialized())) { 578 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 579 if (UNLIKELY(!class_linker->EnsureInitialized(java_lang_string_class, 580 true, true))) { 581 DCHECK(self->IsExceptionPending()); 582 return NULL; 583 } 584 } 585 return mh.ResolveString(string_idx); 586} 587 588static void DoIntDivide(Thread* self, ShadowFrame& shadow_frame, size_t result_reg, 589 int32_t dividend, int32_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 590 if (UNLIKELY(divisor == 0)) { 591 ThrowArithmeticExceptionDivideByZero(self); 592 } else if (UNLIKELY(dividend == kMinInt && divisor == -1)) { 593 shadow_frame.SetVReg(result_reg, kMinInt); 594 } else { 595 shadow_frame.SetVReg(result_reg, dividend / divisor); 596 } 597} 598 599static void DoIntRemainder(Thread* self, ShadowFrame& shadow_frame, size_t result_reg, 600 int32_t dividend, int32_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 601 if (UNLIKELY(divisor == 0)) { 602 ThrowArithmeticExceptionDivideByZero(self); 603 } else if (UNLIKELY(dividend == kMinInt && divisor == -1)) { 604 shadow_frame.SetVReg(result_reg, 0); 605 } else { 606 shadow_frame.SetVReg(result_reg, dividend % divisor); 607 } 608} 609 610static void DoLongDivide(Thread* self, ShadowFrame& shadow_frame, size_t result_reg, 611 int64_t dividend, int64_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 612 if (UNLIKELY(divisor == 0)) { 613 ThrowArithmeticExceptionDivideByZero(self); 614 } else if (UNLIKELY(dividend == kMinLong && divisor == -1)) { 615 shadow_frame.SetVRegLong(result_reg, kMinLong); 616 } else { 617 shadow_frame.SetVRegLong(result_reg, dividend / divisor); 618 } 619} 620 621static void DoLongRemainder(Thread* self, ShadowFrame& shadow_frame, size_t result_reg, 622 int64_t dividend, int64_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 623 if (UNLIKELY(divisor == 0)) { 624 ThrowArithmeticExceptionDivideByZero(self); 625 } else if (UNLIKELY(dividend == kMinLong && divisor == -1)) { 626 shadow_frame.SetVRegLong(result_reg, 0); 627 } else { 628 shadow_frame.SetVRegLong(result_reg, dividend % divisor); 629 } 630} 631 632static JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 633 ShadowFrame& shadow_frame, JValue result_register) 634 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 635 if (UNLIKELY(!shadow_frame.HasReferenceArray())) { 636 LOG(FATAL) << "Invalid shadow frame for interpreter use"; 637 return JValue(); 638 } 639 self->VerifyStack(); 640 instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 641 const uint16_t* const insns = code_item->insns_; 642 643 // As the 'this' object won't change during the execution of current code, we 644 // want to cache it in local variables. Nevertheless, in order to let the 645 // garbage collector access it, we store it into sirt references. 646 SirtRef<Object> this_object_ref(self, shadow_frame.GetThisObject()); 647 648 const Instruction* inst = Instruction::At(insns + shadow_frame.GetDexPC()); 649 if (inst->GetDexPc(insns) == 0) { // We are entering the method as opposed to deoptimizing.. 650 instrumentation->MethodEnterEvent(self, this_object_ref.get(), 651 shadow_frame.GetMethod(), 0); 652 } 653 while (true) { 654 CheckSuspend(self); 655 const uint32_t dex_pc = inst->GetDexPc(insns); 656 shadow_frame.SetDexPC(dex_pc); 657 instrumentation->DexPcMovedEvent(self, this_object_ref.get(), 658 shadow_frame.GetMethod(), dex_pc); 659 const bool kTracing = false; 660 if (kTracing) { 661#define TRACE_LOG std::cerr 662 TRACE_LOG << PrettyMethod(shadow_frame.GetMethod()) 663 << StringPrintf("\n0x%x: ", dex_pc) 664 << inst->DumpString(&mh.GetDexFile()) << "\n"; 665 for (size_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) { 666 uint32_t raw_value = shadow_frame.GetVReg(i); 667 Object* ref_value = shadow_frame.GetVRegReference(i); 668 TRACE_LOG << StringPrintf(" vreg%d=0x%08X", i, raw_value); 669 if (ref_value != NULL) { 670 if (ref_value->GetClass()->IsStringClass() && 671 ref_value->AsString()->GetCharArray() != NULL) { 672 TRACE_LOG << "/java.lang.String \"" << ref_value->AsString()->ToModifiedUtf8() << "\""; 673 } else { 674 TRACE_LOG << "/" << PrettyTypeOf(ref_value); 675 } 676 } 677 } 678 TRACE_LOG << "\n"; 679#undef TRACE_LOG 680 } 681 const Instruction* next_inst = inst->Next(); 682 switch (inst->Opcode()) { 683 case Instruction::NOP: 684 break; 685 case Instruction::MOVE: 686 shadow_frame.SetVReg(inst->VRegA_12x(), 687 shadow_frame.GetVReg(inst->VRegB_12x())); 688 break; 689 case Instruction::MOVE_FROM16: 690 shadow_frame.SetVReg(inst->VRegA_22x(), 691 shadow_frame.GetVReg(inst->VRegB_22x())); 692 break; 693 case Instruction::MOVE_16: 694 shadow_frame.SetVReg(inst->VRegA_32x(), 695 shadow_frame.GetVReg(inst->VRegB_32x())); 696 break; 697 case Instruction::MOVE_WIDE: 698 shadow_frame.SetVRegLong(inst->VRegA_12x(), 699 shadow_frame.GetVRegLong(inst->VRegB_12x())); 700 break; 701 case Instruction::MOVE_WIDE_FROM16: 702 shadow_frame.SetVRegLong(inst->VRegA_22x(), 703 shadow_frame.GetVRegLong(inst->VRegB_22x())); 704 break; 705 case Instruction::MOVE_WIDE_16: 706 shadow_frame.SetVRegLong(inst->VRegA_32x(), 707 shadow_frame.GetVRegLong(inst->VRegB_32x())); 708 break; 709 case Instruction::MOVE_OBJECT: 710 shadow_frame.SetVRegReference(inst->VRegA_12x(), 711 shadow_frame.GetVRegReference(inst->VRegB_12x())); 712 break; 713 case Instruction::MOVE_OBJECT_FROM16: 714 shadow_frame.SetVRegReference(inst->VRegA_22x(), 715 shadow_frame.GetVRegReference(inst->VRegB_22x())); 716 break; 717 case Instruction::MOVE_OBJECT_16: 718 shadow_frame.SetVRegReference(inst->VRegA_32x(), 719 shadow_frame.GetVRegReference(inst->VRegB_32x())); 720 break; 721 case Instruction::MOVE_RESULT: 722 shadow_frame.SetVReg(inst->VRegA_11x(), result_register.GetI()); 723 break; 724 case Instruction::MOVE_RESULT_WIDE: 725 shadow_frame.SetVRegLong(inst->VRegA_11x(), result_register.GetJ()); 726 break; 727 case Instruction::MOVE_RESULT_OBJECT: 728 shadow_frame.SetVRegReference(inst->VRegA_11x(), result_register.GetL()); 729 break; 730 case Instruction::MOVE_EXCEPTION: { 731 Throwable* exception = self->GetException(NULL); 732 self->ClearException(); 733 shadow_frame.SetVRegReference(inst->VRegA_11x(), exception); 734 break; 735 } 736 case Instruction::RETURN_VOID: { 737 JValue result; 738 instrumentation->MethodExitEvent(self, this_object_ref.get(), 739 shadow_frame.GetMethod(), dex_pc, result); 740 return result; 741 } 742 case Instruction::RETURN: { 743 JValue result; 744 result.SetJ(0); 745 result.SetI(shadow_frame.GetVReg(inst->VRegA_11x())); 746 instrumentation->MethodExitEvent(self, this_object_ref.get(), 747 shadow_frame.GetMethod(), dex_pc, result); 748 return result; 749 } 750 case Instruction::RETURN_WIDE: { 751 JValue result; 752 result.SetJ(shadow_frame.GetVRegLong(inst->VRegA_11x())); 753 instrumentation->MethodExitEvent(self, this_object_ref.get(), 754 shadow_frame.GetMethod(), dex_pc, result); 755 return result; 756 } 757 case Instruction::RETURN_OBJECT: { 758 JValue result; 759 result.SetJ(0); 760 result.SetL(shadow_frame.GetVRegReference(inst->VRegA_11x())); 761 instrumentation->MethodExitEvent(self, this_object_ref.get(), 762 shadow_frame.GetMethod(), dex_pc, result); 763 return result; 764 } 765 case Instruction::CONST_4: { 766 uint32_t dst = inst->VRegA_11n(); 767 int32_t val = static_cast<int32_t>(inst->VRegB_11n() << 28) >> 28; 768 shadow_frame.SetVReg(dst, val); 769 if (val == 0) { 770 shadow_frame.SetVRegReference(dst, NULL); 771 } 772 break; 773 } 774 case Instruction::CONST_16: { 775 uint32_t dst = inst->VRegA_21s(); 776 int32_t val = static_cast<int16_t>(inst->VRegB_21s()); 777 shadow_frame.SetVReg(dst, val); 778 if (val == 0) { 779 shadow_frame.SetVRegReference(dst, NULL); 780 } 781 break; 782 } 783 case Instruction::CONST: { 784 uint32_t dst = inst->VRegA_31i(); 785 int32_t val = inst->VRegB_31i(); 786 shadow_frame.SetVReg(dst, val); 787 if (val == 0) { 788 shadow_frame.SetVRegReference(dst, NULL); 789 } 790 break; 791 } 792 case Instruction::CONST_HIGH16: { 793 uint32_t dst = inst->VRegA_21h(); 794 int32_t val = inst->VRegB_21h() << 16; 795 shadow_frame.SetVReg(dst, val); 796 if (val == 0) { 797 shadow_frame.SetVRegReference(dst, NULL); 798 } 799 break; 800 } 801 case Instruction::CONST_WIDE_16: 802 shadow_frame.SetVRegLong(inst->VRegA_21s(), 803 static_cast<int16_t>(inst->VRegB_21s())); 804 break; 805 case Instruction::CONST_WIDE_32: 806 shadow_frame.SetVRegLong(inst->VRegA_31i(), 807 static_cast<int32_t>(inst->VRegB_31i())); 808 break; 809 case Instruction::CONST_WIDE: 810 shadow_frame.SetVRegLong(inst->VRegA_51l(), inst->VRegB_51l()); 811 break; 812 case Instruction::CONST_WIDE_HIGH16: 813 shadow_frame.SetVRegLong(inst->VRegA_21h(), 814 static_cast<uint64_t>(inst->VRegB_21h()) << 48); 815 break; 816 case Instruction::CONST_STRING: { 817 String* s = ResolveString(self, mh, inst->VRegB_21c()); 818 if (UNLIKELY(s == NULL)) { 819 CHECK(self->IsExceptionPending()); 820 } else { 821 shadow_frame.SetVRegReference( inst->VRegA_21c(), s); 822 } 823 break; 824 } 825 case Instruction::CONST_STRING_JUMBO: { 826 String* s = ResolveString(self, mh, inst->VRegB_31c()); 827 if (UNLIKELY(s == NULL)) { 828 CHECK(self->IsExceptionPending()); 829 } else { 830 shadow_frame.SetVRegReference( inst->VRegA_31c(), s); 831 } 832 break; 833 } 834 case Instruction::CONST_CLASS: { 835 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(), 836 self, false, true); 837 if (UNLIKELY(c == NULL)) { 838 CHECK(self->IsExceptionPending()); 839 } else { 840 shadow_frame.SetVRegReference(inst->VRegA_21c(), c); 841 } 842 break; 843 } 844 case Instruction::MONITOR_ENTER: { 845 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x()); 846 if (UNLIKELY(obj == NULL)) { 847 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 848 } else { 849 DoMonitorEnter(self, obj); 850 } 851 break; 852 } 853 case Instruction::MONITOR_EXIT: { 854 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_11x()); 855 if (UNLIKELY(obj == NULL)) { 856 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 857 } else { 858 DoMonitorExit(self, obj); 859 } 860 break; 861 } 862 case Instruction::CHECK_CAST: { 863 Class* c = ResolveVerifyAndClinit(inst->VRegB_21c(), shadow_frame.GetMethod(), 864 self, false, true); 865 if (UNLIKELY(c == NULL)) { 866 CHECK(self->IsExceptionPending()); 867 } else { 868 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_21c()); 869 if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) { 870 ThrowClassCastException(c, obj->GetClass()); 871 } 872 } 873 break; 874 } 875 case Instruction::INSTANCE_OF: { 876 Class* c = ResolveVerifyAndClinit(inst->VRegC_22c(), shadow_frame.GetMethod(), 877 self, false, true); 878 if (UNLIKELY(c == NULL)) { 879 CHECK(self->IsExceptionPending()); 880 } else { 881 Object* obj = shadow_frame.GetVRegReference(inst->VRegB_22c()); 882 shadow_frame.SetVReg(inst->VRegA_22c(), (obj != NULL && obj->InstanceOf(c)) ? 1 : 0); 883 } 884 break; 885 } 886 case Instruction::ARRAY_LENGTH: { 887 Object* array = shadow_frame.GetVRegReference(inst->VRegB_12x()); 888 if (UNLIKELY(array == NULL)) { 889 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 890 break; 891 } 892 shadow_frame.SetVReg(inst->VRegA_12x(), array->AsArray()->GetLength()); 893 break; 894 } 895 case Instruction::NEW_INSTANCE: { 896 Object* obj = AllocObjectFromCode(inst->VRegB_21c(), shadow_frame.GetMethod(), 897 self, true); 898 if (UNLIKELY(obj == NULL)) { 899 CHECK(self->IsExceptionPending()); 900 } else { 901 shadow_frame.SetVRegReference(inst->VRegA_21c(), obj); 902 } 903 break; 904 } 905 case Instruction::NEW_ARRAY: { 906 int32_t length = shadow_frame.GetVReg(inst->VRegB_22c()); 907 Object* obj = AllocArrayFromCode(inst->VRegC_22c(), shadow_frame.GetMethod(), 908 length, self, true); 909 if (UNLIKELY(obj == NULL)) { 910 CHECK(self->IsExceptionPending()); 911 } else { 912 shadow_frame.SetVRegReference(inst->VRegA_22c(), obj); 913 } 914 break; 915 } 916 case Instruction::FILLED_NEW_ARRAY: { 917 const int32_t length = inst->VRegA_35c(); 918 CHECK(length <= 5); 919 if (UNLIKELY(length < 0)) { 920 ThrowNegativeArraySizeException(length); 921 break; 922 } 923 Class* arrayClass = ResolveVerifyAndClinit(inst->VRegB_35c(), shadow_frame.GetMethod(), 924 self, false, true); 925 if (UNLIKELY(arrayClass == NULL)) { 926 CHECK(self->IsExceptionPending()); 927 break; 928 } 929 CHECK(arrayClass->IsArrayClass()); 930 Class* componentClass = arrayClass->GetComponentType(); 931 if (UNLIKELY(componentClass->IsPrimitive() && !componentClass->IsPrimitiveInt())) { 932 if (componentClass->IsPrimitiveLong() || componentClass->IsPrimitiveDouble()) { 933 ThrowRuntimeException("Bad filled array request for type %s", 934 PrettyDescriptor(componentClass).c_str()); 935 } else { 936 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(), 937 "Ljava/lang/InternalError;", 938 "Found type %s; filled-new-array not implemented for anything but \'int\'", 939 PrettyDescriptor(componentClass).c_str()); 940 } 941 break; 942 } 943 Object* newArray = Array::Alloc(self, arrayClass, length); 944 if (UNLIKELY(newArray == NULL)) { 945 CHECK(self->IsExceptionPending()); 946 } else { 947 uint32_t arg[5]; 948 inst->GetArgs(arg); 949 const bool is_primitive_int_component = componentClass->IsPrimitiveInt(); 950 for (int32_t i = 0; i < length; ++i) { 951 if (is_primitive_int_component) { 952 newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(arg[i])); 953 } else { 954 newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(arg[i])); 955 } 956 } 957 } 958 result_register.SetL(newArray); 959 break; 960 } 961 case Instruction::FILLED_NEW_ARRAY_RANGE: { 962 int32_t length = inst->VRegA_3rc(); 963 if (UNLIKELY(length < 0)) { 964 ThrowNegativeArraySizeException(length); 965 break; 966 } 967 Class* arrayClass = ResolveVerifyAndClinit(inst->VRegB_3rc(), shadow_frame.GetMethod(), 968 self, false, true); 969 if (UNLIKELY(arrayClass == NULL)) { 970 CHECK(self->IsExceptionPending()); 971 break; 972 } 973 CHECK(arrayClass->IsArrayClass()); 974 Class* componentClass = arrayClass->GetComponentType(); 975 if (UNLIKELY(componentClass->IsPrimitive() && !componentClass->IsPrimitiveInt())) { 976 if (componentClass->IsPrimitiveLong() || componentClass->IsPrimitiveDouble()) { 977 ThrowRuntimeException("Bad filled array request for type %s", 978 PrettyDescriptor(componentClass).c_str()); 979 } else { 980 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(), 981 "Ljava/lang/InternalError;", 982 "Found type %s; filled-new-array not implemented for anything but \'int\'", 983 PrettyDescriptor(componentClass).c_str()); 984 } 985 break; 986 } 987 Object* newArray = Array::Alloc(self, arrayClass, length); 988 if (UNLIKELY(newArray == NULL)) { 989 CHECK(self->IsExceptionPending()); 990 } else { 991 uint32_t vregC = inst->VRegC_3rc(); 992 const bool is_primitive_int_component = componentClass->IsPrimitiveInt(); 993 for (int32_t i = 0; i < length; ++i) { 994 if (is_primitive_int_component) { 995 newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(vregC + i)); 996 } else { 997 newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(vregC + i)); 998 } 999 } 1000 } 1001 result_register.SetL(newArray); 1002 break; 1003 } 1004 case Instruction::FILL_ARRAY_DATA: { 1005 Object* obj = shadow_frame.GetVRegReference(inst->VRegA_31t()); 1006 if (UNLIKELY(obj == NULL)) { 1007 ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA"); 1008 break; 1009 } 1010 Array* array = obj->AsArray(); 1011 DCHECK(array->IsArrayInstance() && !array->IsObjectArray()); 1012 const Instruction::ArrayDataPayload* payload = 1013 reinterpret_cast<const Instruction::ArrayDataPayload*>(insns + dex_pc + inst->VRegB_31t()); 1014 if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) { 1015 self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(), 1016 "Ljava/lang/ArrayIndexOutOfBoundsException;", 1017 "failed FILL_ARRAY_DATA; length=%d, index=%d", 1018 array->GetLength(), payload->element_count); 1019 break; 1020 } 1021 uint32_t size_in_bytes = payload->element_count * payload->element_width; 1022 memcpy(array->GetRawData(payload->element_width), payload->data, size_in_bytes); 1023 break; 1024 } 1025 case Instruction::THROW: { 1026 Object* exception = shadow_frame.GetVRegReference(inst->VRegA_11x()); 1027 if (UNLIKELY(exception == NULL)) { 1028 ThrowNullPointerException(NULL, "throw with null exception"); 1029 } else { 1030 self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable()); 1031 } 1032 break; 1033 } 1034 case Instruction::GOTO: { 1035 next_inst = Instruction::At(insns + dex_pc + inst->VRegA_10t()); 1036 break; 1037 } 1038 case Instruction::GOTO_16: { 1039 next_inst = Instruction::At(insns + dex_pc + inst->VRegA_20t()); 1040 break; 1041 } 1042 case Instruction::GOTO_32: { 1043 next_inst = Instruction::At(insns + dex_pc + inst->VRegA_30t()); 1044 break; 1045 } 1046 case Instruction::PACKED_SWITCH: { 1047 const uint16_t* switch_data = insns + dex_pc + inst->VRegB_31t(); 1048 int32_t test_val = shadow_frame.GetVReg(inst->VRegA_31t()); 1049 CHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kPackedSwitchSignature)); 1050 uint16_t size = switch_data[1]; 1051 CHECK_GT(size, 0); 1052 const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]); 1053 CHECK(IsAligned<4>(keys)); 1054 int32_t first_key = keys[0]; 1055 const int32_t* targets = reinterpret_cast<const int32_t*>(&switch_data[4]); 1056 CHECK(IsAligned<4>(targets)); 1057 int32_t index = test_val - first_key; 1058 if (index >= 0 && index < size) { 1059 next_inst = Instruction::At(insns + dex_pc + targets[index]); 1060 } 1061 break; 1062 } 1063 case Instruction::SPARSE_SWITCH: { 1064 const uint16_t* switch_data = insns + dex_pc + inst->VRegB_31t(); 1065 int32_t test_val = shadow_frame.GetVReg(inst->VRegA_31t()); 1066 CHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature)); 1067 uint16_t size = switch_data[1]; 1068 CHECK_GT(size, 0); 1069 const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]); 1070 CHECK(IsAligned<4>(keys)); 1071 const int32_t* entries = keys + size; 1072 CHECK(IsAligned<4>(entries)); 1073 int lo = 0; 1074 int hi = size - 1; 1075 while (lo <= hi) { 1076 int mid = (lo + hi) / 2; 1077 int32_t foundVal = keys[mid]; 1078 if (test_val < foundVal) { 1079 hi = mid - 1; 1080 } else if (test_val > foundVal) { 1081 lo = mid + 1; 1082 } else { 1083 next_inst = Instruction::At(insns + dex_pc + entries[mid]); 1084 break; 1085 } 1086 } 1087 break; 1088 } 1089 case Instruction::CMPL_FLOAT: { 1090 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x()); 1091 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x()); 1092 int32_t result; 1093 // TODO: we should not test float equality like this. Reorder comparisons 1094 // or use a different comparison mechanism. 1095 if (val1 == val2) { 1096 result = 0; 1097 } else if (val1 > val2) { 1098 result = 1; 1099 } else { 1100 result = -1; 1101 } 1102 shadow_frame.SetVReg(inst->VRegA_23x(), result); 1103 break; 1104 } 1105 case Instruction::CMPG_FLOAT: { 1106 float val1 = shadow_frame.GetVRegFloat(inst->VRegB_23x()); 1107 float val2 = shadow_frame.GetVRegFloat(inst->VRegC_23x()); 1108 int32_t result; 1109 // TODO: we should not test float equality like this. Reorder comparisons 1110 // or use a different comparison mechanism. 1111 if (val1 == val2) { 1112 result = 0; 1113 } else if (val1 < val2) { 1114 result = -1; 1115 } else { 1116 result = 1; 1117 } 1118 shadow_frame.SetVReg(inst->VRegA_23x(), result); 1119 break; 1120 } 1121 case Instruction::CMPL_DOUBLE: { 1122 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x()); 1123 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x()); 1124 int32_t result; 1125 // TODO: we should not test double equality like this. Reorder comparisons 1126 // or use a different comparison mechanism. 1127 if (val1 == val2) { 1128 result = 0; 1129 } else if (val1 > val2) { 1130 result = 1; 1131 } else { 1132 result = -1; 1133 } 1134 shadow_frame.SetVReg(inst->VRegA_23x(), result); 1135 break; 1136 } 1137 1138 case Instruction::CMPG_DOUBLE: { 1139 double val1 = shadow_frame.GetVRegDouble(inst->VRegB_23x()); 1140 double val2 = shadow_frame.GetVRegDouble(inst->VRegC_23x()); 1141 int32_t result; 1142 // TODO: we should not test double equality like this. Reorder comparisons 1143 // or use a different comparison mechanism. 1144 if (val1 == val2) { 1145 result = 0; 1146 } else if (val1 < val2) { 1147 result = -1; 1148 } else { 1149 result = 1; 1150 } 1151 shadow_frame.SetVReg(inst->VRegA_23x(), result); 1152 break; 1153 } 1154 case Instruction::CMP_LONG: { 1155 int64_t val1 = shadow_frame.GetVRegLong(inst->VRegB_23x()); 1156 int64_t val2 = shadow_frame.GetVRegLong(inst->VRegC_23x()); 1157 int32_t result; 1158 if (val1 > val2) { 1159 result = 1; 1160 } else if (val1 == val2) { 1161 result = 0; 1162 } else { 1163 result = -1; 1164 } 1165 shadow_frame.SetVReg(inst->VRegA_23x(), result); 1166 break; 1167 } 1168 case Instruction::IF_EQ: { 1169 if (shadow_frame.GetVReg(inst->VRegA_22t()) == shadow_frame.GetVReg(inst->VRegB_22t())) { 1170 next_inst = Instruction::At(insns + dex_pc + inst->VRegC_22t()); 1171 } 1172 break; 1173 } 1174 case Instruction::IF_NE: { 1175 if (shadow_frame.GetVReg(inst->VRegA_22t()) != shadow_frame.GetVReg(inst->VRegB_22t())) { 1176 next_inst = Instruction::At(insns + dex_pc + inst->VRegC_22t()); 1177 } 1178 break; 1179 } 1180 case Instruction::IF_LT: { 1181 if (shadow_frame.GetVReg(inst->VRegA_22t()) < shadow_frame.GetVReg(inst->VRegB_22t())) { 1182 next_inst = Instruction::At(insns + dex_pc + inst->VRegC_22t()); 1183 } 1184 break; 1185 } 1186 case Instruction::IF_GE: { 1187 if (shadow_frame.GetVReg(inst->VRegA_22t()) >= shadow_frame.GetVReg(inst->VRegB_22t())) { 1188 next_inst = Instruction::At(insns + dex_pc + inst->VRegC_22t()); 1189 } 1190 break; 1191 } 1192 case Instruction::IF_GT: { 1193 if (shadow_frame.GetVReg(inst->VRegA_22t()) > shadow_frame.GetVReg(inst->VRegB_22t())) { 1194 next_inst = Instruction::At(insns + dex_pc + inst->VRegC_22t()); 1195 } 1196 break; 1197 } 1198 case Instruction::IF_LE: { 1199 if (shadow_frame.GetVReg(inst->VRegA_22t()) <= shadow_frame.GetVReg(inst->VRegB_22t())) { 1200 next_inst = Instruction::At(insns + dex_pc + inst->VRegC_22t()); 1201 } 1202 break; 1203 } 1204 case Instruction::IF_EQZ: { 1205 if (shadow_frame.GetVReg(inst->VRegA_21t()) == 0) { 1206 next_inst = Instruction::At(insns + dex_pc + inst->VRegB_21t()); 1207 } 1208 break; 1209 } 1210 case Instruction::IF_NEZ: { 1211 if (shadow_frame.GetVReg(inst->VRegA_21t()) != 0) { 1212 next_inst = Instruction::At(insns + dex_pc + inst->VRegB_21t()); 1213 } 1214 break; 1215 } 1216 case Instruction::IF_LTZ: { 1217 if (shadow_frame.GetVReg(inst->VRegA_21t()) < 0) { 1218 next_inst = Instruction::At(insns + dex_pc + inst->VRegB_21t()); 1219 } 1220 break; 1221 } 1222 case Instruction::IF_GEZ: { 1223 if (shadow_frame.GetVReg(inst->VRegA_21t()) >= 0) { 1224 next_inst = Instruction::At(insns + dex_pc + inst->VRegB_21t()); 1225 } 1226 break; 1227 } 1228 case Instruction::IF_GTZ: { 1229 if (shadow_frame.GetVReg(inst->VRegA_21t()) > 0) { 1230 next_inst = Instruction::At(insns + dex_pc + inst->VRegB_21t()); 1231 } 1232 break; 1233 } 1234 case Instruction::IF_LEZ: { 1235 if (shadow_frame.GetVReg(inst->VRegA_21t()) <= 0) { 1236 next_inst = Instruction::At(insns + dex_pc + inst->VRegB_21t()); 1237 } 1238 break; 1239 } 1240 case Instruction::AGET_BOOLEAN: { 1241 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1242 if (UNLIKELY(a == NULL)) { 1243 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1244 break; 1245 } 1246 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1247 shadow_frame.SetVReg(inst->VRegA_23x(), a->AsBooleanArray()->Get(index)); 1248 break; 1249 } 1250 case Instruction::AGET_BYTE: { 1251 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1252 if (UNLIKELY(a == NULL)) { 1253 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1254 break; 1255 } 1256 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1257 shadow_frame.SetVReg(inst->VRegA_23x(), a->AsByteArray()->Get(index)); 1258 break; 1259 } 1260 case Instruction::AGET_CHAR: { 1261 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1262 if (UNLIKELY(a == NULL)) { 1263 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1264 break; 1265 } 1266 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1267 shadow_frame.SetVReg(inst->VRegA_23x(), a->AsCharArray()->Get(index)); 1268 break; 1269 } 1270 case Instruction::AGET_SHORT: { 1271 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1272 if (UNLIKELY(a == NULL)) { 1273 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1274 break; 1275 } 1276 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1277 shadow_frame.SetVReg(inst->VRegA_23x(), a->AsShortArray()->Get(index)); 1278 break; 1279 } 1280 case Instruction::AGET: { 1281 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1282 if (UNLIKELY(a == NULL)) { 1283 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1284 break; 1285 } 1286 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1287 shadow_frame.SetVReg(inst->VRegA_23x(), a->AsIntArray()->Get(index)); 1288 break; 1289 } 1290 case Instruction::AGET_WIDE: { 1291 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1292 if (UNLIKELY(a == NULL)) { 1293 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1294 break; 1295 } 1296 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1297 shadow_frame.SetVRegLong(inst->VRegA_23x(), a->AsLongArray()->Get(index)); 1298 break; 1299 } 1300 case Instruction::AGET_OBJECT: { 1301 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1302 if (UNLIKELY(a == NULL)) { 1303 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1304 break; 1305 } 1306 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1307 shadow_frame.SetVRegReference(inst->VRegA_23x(), a->AsObjectArray<Object>()->Get(index)); 1308 break; 1309 } 1310 case Instruction::APUT_BOOLEAN: { 1311 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1312 if (UNLIKELY(a == NULL)) { 1313 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1314 break; 1315 } 1316 uint8_t val = shadow_frame.GetVReg(inst->VRegA_23x()); 1317 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1318 a->AsBooleanArray()->Set(index, val); 1319 break; 1320 } 1321 case Instruction::APUT_BYTE: { 1322 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1323 if (UNLIKELY(a == NULL)) { 1324 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1325 break; 1326 } 1327 int8_t val = shadow_frame.GetVReg(inst->VRegA_23x()); 1328 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1329 a->AsByteArray()->Set(index, val); 1330 break; 1331 } 1332 case Instruction::APUT_CHAR: { 1333 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1334 if (UNLIKELY(a == NULL)) { 1335 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1336 break; 1337 } 1338 uint16_t val = shadow_frame.GetVReg(inst->VRegA_23x()); 1339 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1340 a->AsCharArray()->Set(index, val); 1341 break; 1342 } 1343 case Instruction::APUT_SHORT: { 1344 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1345 if (UNLIKELY(a == NULL)) { 1346 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1347 break; 1348 } 1349 int16_t val = shadow_frame.GetVReg(inst->VRegA_23x()); 1350 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1351 a->AsShortArray()->Set(index, val); 1352 break; 1353 } 1354 case Instruction::APUT: { 1355 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1356 if (UNLIKELY(a == NULL)) { 1357 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1358 break; 1359 } 1360 int32_t val = shadow_frame.GetVReg(inst->VRegA_23x()); 1361 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1362 a->AsIntArray()->Set(index, val); 1363 break; 1364 } 1365 case Instruction::APUT_WIDE: { 1366 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1367 if (UNLIKELY(a == NULL)) { 1368 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1369 break; 1370 } 1371 int64_t val = shadow_frame.GetVRegLong(inst->VRegA_23x()); 1372 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1373 a->AsLongArray()->Set(index, val); 1374 break; 1375 } 1376 case Instruction::APUT_OBJECT: { 1377 Object* a = shadow_frame.GetVRegReference(inst->VRegB_23x()); 1378 if (UNLIKELY(a == NULL)) { 1379 ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow()); 1380 break; 1381 } 1382 Object* val = shadow_frame.GetVRegReference(inst->VRegA_23x()); 1383 int32_t index = shadow_frame.GetVReg(inst->VRegC_23x()); 1384 a->AsObjectArray<Object>()->Set(index, val); 1385 break; 1386 } 1387 case Instruction::IGET_BOOLEAN: 1388 DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimBoolean); 1389 break; 1390 case Instruction::IGET_BYTE: 1391 DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimByte); 1392 break; 1393 case Instruction::IGET_CHAR: 1394 DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimChar); 1395 break; 1396 case Instruction::IGET_SHORT: 1397 DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimShort); 1398 break; 1399 case Instruction::IGET: 1400 DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimInt); 1401 break; 1402 case Instruction::IGET_WIDE: 1403 DoFieldGet(self, shadow_frame, inst, InstancePrimitiveRead, Primitive::kPrimLong); 1404 break; 1405 case Instruction::IGET_OBJECT: 1406 DoFieldGet(self, shadow_frame, inst, InstanceObjectRead, Primitive::kPrimNot); 1407 break; 1408 case Instruction::SGET_BOOLEAN: 1409 DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimBoolean); 1410 break; 1411 case Instruction::SGET_BYTE: 1412 DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimByte); 1413 break; 1414 case Instruction::SGET_CHAR: 1415 DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimChar); 1416 break; 1417 case Instruction::SGET_SHORT: 1418 DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimShort); 1419 break; 1420 case Instruction::SGET: 1421 DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimInt); 1422 break; 1423 case Instruction::SGET_WIDE: 1424 DoFieldGet(self, shadow_frame, inst, StaticPrimitiveRead, Primitive::kPrimLong); 1425 break; 1426 case Instruction::SGET_OBJECT: 1427 DoFieldGet(self, shadow_frame, inst, StaticObjectRead, Primitive::kPrimNot); 1428 break; 1429 case Instruction::IPUT_BOOLEAN: 1430 DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimBoolean); 1431 break; 1432 case Instruction::IPUT_BYTE: 1433 DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimByte); 1434 break; 1435 case Instruction::IPUT_CHAR: 1436 DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimChar); 1437 break; 1438 case Instruction::IPUT_SHORT: 1439 DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimShort); 1440 break; 1441 case Instruction::IPUT: 1442 DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimInt); 1443 break; 1444 case Instruction::IPUT_WIDE: 1445 DoFieldPut(self, shadow_frame, inst, InstancePrimitiveWrite, Primitive::kPrimLong); 1446 break; 1447 case Instruction::IPUT_OBJECT: 1448 DoFieldPut(self, shadow_frame, inst, InstanceObjectWrite, Primitive::kPrimNot); 1449 break; 1450 case Instruction::SPUT_BOOLEAN: 1451 DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimBoolean); 1452 break; 1453 case Instruction::SPUT_BYTE: 1454 DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimByte); 1455 break; 1456 case Instruction::SPUT_CHAR: 1457 DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimChar); 1458 break; 1459 case Instruction::SPUT_SHORT: 1460 DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimShort); 1461 break; 1462 case Instruction::SPUT: 1463 DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimInt); 1464 break; 1465 case Instruction::SPUT_WIDE: 1466 DoFieldPut(self, shadow_frame, inst, StaticPrimitiveWrite, Primitive::kPrimLong); 1467 break; 1468 case Instruction::SPUT_OBJECT: 1469 DoFieldPut(self, shadow_frame, inst, StaticObjectWrite, Primitive::kPrimNot); 1470 break; 1471 case Instruction::INVOKE_VIRTUAL: 1472 DoInvoke(self, mh, shadow_frame, inst, kVirtual, false, &result_register); 1473 break; 1474 case Instruction::INVOKE_VIRTUAL_RANGE: 1475 DoInvoke(self, mh, shadow_frame, inst, kVirtual, true, &result_register); 1476 break; 1477 case Instruction::INVOKE_SUPER: 1478 DoInvoke(self, mh, shadow_frame, inst, kSuper, false, &result_register); 1479 break; 1480 case Instruction::INVOKE_SUPER_RANGE: 1481 DoInvoke(self, mh, shadow_frame, inst, kSuper, true, &result_register); 1482 break; 1483 case Instruction::INVOKE_DIRECT: 1484 DoInvoke(self, mh, shadow_frame, inst, kDirect, false, &result_register); 1485 break; 1486 case Instruction::INVOKE_DIRECT_RANGE: 1487 DoInvoke(self, mh, shadow_frame, inst, kDirect, true, &result_register); 1488 break; 1489 case Instruction::INVOKE_INTERFACE: 1490 DoInvoke(self, mh, shadow_frame, inst, kInterface, false, &result_register); 1491 break; 1492 case Instruction::INVOKE_INTERFACE_RANGE: 1493 DoInvoke(self, mh, shadow_frame, inst, kInterface, true, &result_register); 1494 break; 1495 case Instruction::INVOKE_STATIC: 1496 DoInvoke(self, mh, shadow_frame, inst, kStatic, false, &result_register); 1497 break; 1498 case Instruction::INVOKE_STATIC_RANGE: 1499 DoInvoke(self, mh, shadow_frame, inst, kStatic, true, &result_register); 1500 break; 1501 case Instruction::NEG_INT: 1502 shadow_frame.SetVReg(inst->VRegA_12x(), -shadow_frame.GetVReg(inst->VRegB_12x())); 1503 break; 1504 case Instruction::NOT_INT: 1505 shadow_frame.SetVReg(inst->VRegA_12x(), ~shadow_frame.GetVReg(inst->VRegB_12x())); 1506 break; 1507 case Instruction::NEG_LONG: 1508 shadow_frame.SetVRegLong(inst->VRegA_12x(), -shadow_frame.GetVRegLong(inst->VRegB_12x())); 1509 break; 1510 case Instruction::NOT_LONG: 1511 shadow_frame.SetVRegLong(inst->VRegA_12x(), ~shadow_frame.GetVRegLong(inst->VRegB_12x())); 1512 break; 1513 case Instruction::NEG_FLOAT: 1514 shadow_frame.SetVRegFloat(inst->VRegA_12x(), -shadow_frame.GetVRegFloat(inst->VRegB_12x())); 1515 break; 1516 case Instruction::NEG_DOUBLE: 1517 shadow_frame.SetVRegDouble(inst->VRegA_12x(), -shadow_frame.GetVRegDouble(inst->VRegB_12x())); 1518 break; 1519 case Instruction::INT_TO_LONG: 1520 shadow_frame.SetVRegLong(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x())); 1521 break; 1522 case Instruction::INT_TO_FLOAT: 1523 shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x())); 1524 break; 1525 case Instruction::INT_TO_DOUBLE: 1526 shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVReg(inst->VRegB_12x())); 1527 break; 1528 case Instruction::LONG_TO_INT: 1529 shadow_frame.SetVReg(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x())); 1530 break; 1531 case Instruction::LONG_TO_FLOAT: 1532 shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x())); 1533 break; 1534 case Instruction::LONG_TO_DOUBLE: 1535 shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVRegLong(inst->VRegB_12x())); 1536 break; 1537 case Instruction::FLOAT_TO_INT: { 1538 uint32_t dst = inst->VRegA_12x(); 1539 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x()); 1540 if (val != val) { 1541 shadow_frame.SetVReg(dst, 0); 1542 } else if (val > static_cast<float>(kMaxInt)) { 1543 shadow_frame.SetVReg(dst, kMaxInt); 1544 } else if (val < static_cast<float>(kMinInt)) { 1545 shadow_frame.SetVReg(dst, kMinInt); 1546 } else { 1547 shadow_frame.SetVReg(dst, val); 1548 } 1549 break; 1550 } 1551 case Instruction::FLOAT_TO_LONG: { 1552 uint32_t dst = inst->VRegA_12x(); 1553 float val = shadow_frame.GetVRegFloat(inst->VRegB_12x()); 1554 if (val != val) { 1555 shadow_frame.SetVRegLong(dst, 0); 1556 } else if (val > static_cast<float>(kMaxLong)) { 1557 shadow_frame.SetVRegLong(dst, kMaxLong); 1558 } else if (val < static_cast<float>(kMinLong)) { 1559 shadow_frame.SetVRegLong(dst, kMinLong); 1560 } else { 1561 shadow_frame.SetVRegLong(dst, val); 1562 } 1563 break; 1564 } 1565 case Instruction::FLOAT_TO_DOUBLE: 1566 shadow_frame.SetVRegDouble(inst->VRegA_12x(), shadow_frame.GetVRegFloat(inst->VRegB_12x())); 1567 break; 1568 case Instruction::DOUBLE_TO_INT: { 1569 uint32_t dst = inst->VRegA_12x(); 1570 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x()); 1571 if (val != val) { 1572 shadow_frame.SetVReg(dst, 0); 1573 } else if (val > static_cast<double>(kMaxInt)) { 1574 shadow_frame.SetVReg(dst, kMaxInt); 1575 } else if (val < static_cast<double>(kMinInt)) { 1576 shadow_frame.SetVReg(dst, kMinInt); 1577 } else { 1578 shadow_frame.SetVReg(dst, val); 1579 } 1580 break; 1581 } 1582 case Instruction::DOUBLE_TO_LONG: { 1583 uint32_t dst = inst->VRegA_12x(); 1584 double val = shadow_frame.GetVRegDouble(inst->VRegB_12x()); 1585 if (val != val) { 1586 shadow_frame.SetVRegLong(dst, 0); 1587 } else if (val > static_cast<double>(kMaxLong)) { 1588 shadow_frame.SetVRegLong(dst, kMaxLong); 1589 } else if (val < static_cast<double>(kMinLong)) { 1590 shadow_frame.SetVRegLong(dst, kMinLong); 1591 } else { 1592 shadow_frame.SetVRegLong(dst, val); 1593 } 1594 break; 1595 } 1596 case Instruction::DOUBLE_TO_FLOAT: 1597 shadow_frame.SetVRegFloat(inst->VRegA_12x(), shadow_frame.GetVRegDouble(inst->VRegB_12x())); 1598 break; 1599 case Instruction::INT_TO_BYTE: 1600 shadow_frame.SetVReg(inst->VRegA_12x(), 1601 static_cast<int8_t>(shadow_frame.GetVReg(inst->VRegB_12x()))); 1602 break; 1603 case Instruction::INT_TO_CHAR: 1604 shadow_frame.SetVReg(inst->VRegA_12x(), 1605 static_cast<uint16_t>(shadow_frame.GetVReg(inst->VRegB_12x()))); 1606 break; 1607 case Instruction::INT_TO_SHORT: 1608 shadow_frame.SetVReg(inst->VRegA_12x(), 1609 static_cast<int16_t>(shadow_frame.GetVReg(inst->VRegB_12x()))); 1610 break; 1611 case Instruction::ADD_INT: 1612 shadow_frame.SetVReg(inst->VRegA_23x(), 1613 shadow_frame.GetVReg(inst->VRegB_23x()) + 1614 shadow_frame.GetVReg(inst->VRegC_23x())); 1615 break; 1616 case Instruction::SUB_INT: 1617 shadow_frame.SetVReg(inst->VRegA_23x(), 1618 shadow_frame.GetVReg(inst->VRegB_23x()) - 1619 shadow_frame.GetVReg(inst->VRegC_23x())); 1620 break; 1621 case Instruction::MUL_INT: 1622 shadow_frame.SetVReg(inst->VRegA_23x(), 1623 shadow_frame.GetVReg(inst->VRegB_23x()) * 1624 shadow_frame.GetVReg(inst->VRegC_23x())); 1625 break; 1626 case Instruction::DIV_INT: 1627 DoIntDivide(self, shadow_frame, inst->VRegA_23x(), 1628 shadow_frame.GetVReg(inst->VRegB_23x()), 1629 shadow_frame.GetVReg(inst->VRegC_23x())); 1630 break; 1631 case Instruction::REM_INT: 1632 DoIntRemainder(self, shadow_frame, inst->VRegA_23x(), 1633 shadow_frame.GetVReg(inst->VRegB_23x()), 1634 shadow_frame.GetVReg(inst->VRegC_23x())); 1635 break; 1636 case Instruction::SHL_INT: 1637 shadow_frame.SetVReg(inst->VRegA_23x(), 1638 shadow_frame.GetVReg(inst->VRegB_23x()) << 1639 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f)); 1640 break; 1641 case Instruction::SHR_INT: 1642 shadow_frame.SetVReg(inst->VRegA_23x(), 1643 shadow_frame.GetVReg(inst->VRegB_23x()) >> 1644 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f)); 1645 break; 1646 case Instruction::USHR_INT: 1647 shadow_frame.SetVReg(inst->VRegA_23x(), 1648 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_23x())) >> 1649 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x1f)); 1650 break; 1651 case Instruction::AND_INT: 1652 shadow_frame.SetVReg(inst->VRegA_23x(), 1653 shadow_frame.GetVReg(inst->VRegB_23x()) & 1654 shadow_frame.GetVReg(inst->VRegC_23x())); 1655 break; 1656 case Instruction::OR_INT: 1657 shadow_frame.SetVReg(inst->VRegA_23x(), 1658 shadow_frame.GetVReg(inst->VRegB_23x()) | 1659 shadow_frame.GetVReg(inst->VRegC_23x())); 1660 break; 1661 case Instruction::XOR_INT: 1662 shadow_frame.SetVReg(inst->VRegA_23x(), 1663 shadow_frame.GetVReg(inst->VRegB_23x()) ^ 1664 shadow_frame.GetVReg(inst->VRegC_23x())); 1665 break; 1666 case Instruction::ADD_LONG: 1667 shadow_frame.SetVRegLong(inst->VRegA_23x(), 1668 shadow_frame.GetVRegLong(inst->VRegB_23x()) + 1669 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1670 break; 1671 case Instruction::SUB_LONG: 1672 shadow_frame.SetVRegLong(inst->VRegA_23x(), 1673 shadow_frame.GetVRegLong(inst->VRegB_23x()) - 1674 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1675 break; 1676 case Instruction::MUL_LONG: 1677 shadow_frame.SetVRegLong(inst->VRegA_23x(), 1678 shadow_frame.GetVRegLong(inst->VRegB_23x()) * 1679 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1680 break; 1681 case Instruction::DIV_LONG: 1682 DoLongDivide(self, shadow_frame, inst->VRegA_23x(), 1683 shadow_frame.GetVRegLong(inst->VRegB_23x()), 1684 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1685 break; 1686 case Instruction::REM_LONG: 1687 DoLongRemainder(self, shadow_frame, inst->VRegA_23x(), 1688 shadow_frame.GetVRegLong(inst->VRegB_23x()), 1689 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1690 break; 1691 case Instruction::AND_LONG: 1692 shadow_frame.SetVRegLong(inst->VRegA_23x(), 1693 shadow_frame.GetVRegLong(inst->VRegB_23x()) & 1694 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1695 break; 1696 case Instruction::OR_LONG: 1697 shadow_frame.SetVRegLong(inst->VRegA_23x(), 1698 shadow_frame.GetVRegLong(inst->VRegB_23x()) | 1699 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1700 break; 1701 case Instruction::XOR_LONG: 1702 shadow_frame.SetVRegLong(inst->VRegA_23x(), 1703 shadow_frame.GetVRegLong(inst->VRegB_23x()) ^ 1704 shadow_frame.GetVRegLong(inst->VRegC_23x())); 1705 break; 1706 case Instruction::SHL_LONG: 1707 shadow_frame.SetVRegLong(inst->VRegA_23x(), 1708 shadow_frame.GetVRegLong(inst->VRegB_23x()) << 1709 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f)); 1710 break; 1711 case Instruction::SHR_LONG: 1712 shadow_frame.SetVRegLong(inst->VRegA_23x(), 1713 shadow_frame.GetVRegLong(inst->VRegB_23x()) >> 1714 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f)); 1715 break; 1716 case Instruction::USHR_LONG: 1717 shadow_frame.SetVRegLong(inst->VRegA_23x(), 1718 static_cast<uint64_t>(shadow_frame.GetVRegLong(inst->VRegB_23x())) >> 1719 (shadow_frame.GetVReg(inst->VRegC_23x()) & 0x3f)); 1720 break; 1721 case Instruction::ADD_FLOAT: 1722 shadow_frame.SetVRegFloat(inst->VRegA_23x(), 1723 shadow_frame.GetVRegFloat(inst->VRegB_23x()) + 1724 shadow_frame.GetVRegFloat(inst->VRegC_23x())); 1725 break; 1726 case Instruction::SUB_FLOAT: 1727 shadow_frame.SetVRegFloat(inst->VRegA_23x(), 1728 shadow_frame.GetVRegFloat(inst->VRegB_23x()) - 1729 shadow_frame.GetVRegFloat(inst->VRegC_23x())); 1730 break; 1731 case Instruction::MUL_FLOAT: 1732 shadow_frame.SetVRegFloat(inst->VRegA_23x(), 1733 shadow_frame.GetVRegFloat(inst->VRegB_23x()) * 1734 shadow_frame.GetVRegFloat(inst->VRegC_23x())); 1735 break; 1736 case Instruction::DIV_FLOAT: 1737 shadow_frame.SetVRegFloat(inst->VRegA_23x(), 1738 shadow_frame.GetVRegFloat(inst->VRegB_23x()) / 1739 shadow_frame.GetVRegFloat(inst->VRegC_23x())); 1740 break; 1741 case Instruction::REM_FLOAT: 1742 shadow_frame.SetVRegFloat(inst->VRegA_23x(), 1743 fmodf(shadow_frame.GetVRegFloat(inst->VRegB_23x()), 1744 shadow_frame.GetVRegFloat(inst->VRegC_23x()))); 1745 break; 1746 case Instruction::ADD_DOUBLE: 1747 shadow_frame.SetVRegDouble(inst->VRegA_23x(), 1748 shadow_frame.GetVRegDouble(inst->VRegB_23x()) + 1749 shadow_frame.GetVRegDouble(inst->VRegC_23x())); 1750 break; 1751 case Instruction::SUB_DOUBLE: 1752 shadow_frame.SetVRegDouble(inst->VRegA_23x(), 1753 shadow_frame.GetVRegDouble(inst->VRegB_23x()) - 1754 shadow_frame.GetVRegDouble(inst->VRegC_23x())); 1755 break; 1756 case Instruction::MUL_DOUBLE: 1757 shadow_frame.SetVRegDouble(inst->VRegA_23x(), 1758 shadow_frame.GetVRegDouble(inst->VRegB_23x()) * 1759 shadow_frame.GetVRegDouble(inst->VRegC_23x())); 1760 break; 1761 case Instruction::DIV_DOUBLE: 1762 shadow_frame.SetVRegDouble(inst->VRegA_23x(), 1763 shadow_frame.GetVRegDouble(inst->VRegB_23x()) / 1764 shadow_frame.GetVRegDouble(inst->VRegC_23x())); 1765 break; 1766 case Instruction::REM_DOUBLE: 1767 shadow_frame.SetVRegDouble(inst->VRegA_23x(), 1768 fmod(shadow_frame.GetVRegDouble(inst->VRegB_23x()), 1769 shadow_frame.GetVRegDouble(inst->VRegC_23x()))); 1770 break; 1771 case Instruction::ADD_INT_2ADDR: { 1772 uint32_t vregA = inst->VRegA_12x(); 1773 shadow_frame.SetVReg(vregA, 1774 shadow_frame.GetVReg(vregA) + 1775 shadow_frame.GetVReg(inst->VRegB_12x())); 1776 break; 1777 } 1778 case Instruction::SUB_INT_2ADDR: { 1779 uint32_t vregA = inst->VRegA_12x(); 1780 shadow_frame.SetVReg(vregA, 1781 shadow_frame.GetVReg(vregA) - 1782 shadow_frame.GetVReg(inst->VRegB_12x())); 1783 break; 1784 } 1785 case Instruction::MUL_INT_2ADDR: { 1786 uint32_t vregA = inst->VRegA_12x(); 1787 shadow_frame.SetVReg(vregA, 1788 shadow_frame.GetVReg(vregA) * 1789 shadow_frame.GetVReg(inst->VRegB_12x())); 1790 break; 1791 } 1792 case Instruction::REM_INT_2ADDR: { 1793 uint32_t vregA = inst->VRegA_12x(); 1794 DoIntRemainder(self, shadow_frame, vregA, shadow_frame.GetVReg(vregA), 1795 shadow_frame.GetVReg(inst->VRegB_12x())); 1796 break; 1797 } 1798 case Instruction::SHL_INT_2ADDR:{ 1799 uint32_t vregA = inst->VRegA_12x(); 1800 shadow_frame.SetVReg(vregA, 1801 shadow_frame.GetVReg(vregA) << 1802 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f)); 1803 break; 1804 } 1805 case Instruction::SHR_INT_2ADDR: { 1806 uint32_t vregA = inst->VRegA_12x(); 1807 shadow_frame.SetVReg(vregA, 1808 shadow_frame.GetVReg(vregA) >> 1809 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f)); 1810 break; 1811 } 1812 case Instruction::USHR_INT_2ADDR: { 1813 uint32_t vregA = inst->VRegA_12x(); 1814 shadow_frame.SetVReg(vregA, 1815 static_cast<uint32_t>(shadow_frame.GetVReg(vregA)) >> 1816 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x1f)); 1817 break; 1818 } 1819 case Instruction::AND_INT_2ADDR: { 1820 uint32_t vregA = inst->VRegA_12x(); 1821 shadow_frame.SetVReg(vregA, 1822 shadow_frame.GetVReg(vregA) & 1823 shadow_frame.GetVReg(inst->VRegB_12x())); 1824 break; 1825 } 1826 case Instruction::OR_INT_2ADDR: { 1827 uint32_t vregA = inst->VRegA_12x(); 1828 shadow_frame.SetVReg(vregA, 1829 shadow_frame.GetVReg(vregA) | 1830 shadow_frame.GetVReg(inst->VRegB_12x())); 1831 break; 1832 } 1833 case Instruction::XOR_INT_2ADDR: { 1834 uint32_t vregA = inst->VRegA_12x(); 1835 shadow_frame.SetVReg(vregA, 1836 shadow_frame.GetVReg(vregA) ^ 1837 shadow_frame.GetVReg(inst->VRegB_12x())); 1838 break; 1839 } 1840 case Instruction::DIV_INT_2ADDR: { 1841 uint32_t vregA = inst->VRegA_12x(); 1842 DoIntDivide(self, shadow_frame, vregA, shadow_frame.GetVReg(vregA), 1843 shadow_frame.GetVReg(inst->VRegB_12x())); 1844 break; 1845 } 1846 case Instruction::ADD_LONG_2ADDR: { 1847 uint32_t vregA = inst->VRegA_12x(); 1848 shadow_frame.SetVRegLong(vregA, 1849 shadow_frame.GetVRegLong(vregA) + 1850 shadow_frame.GetVRegLong(inst->VRegB_12x())); 1851 break; 1852 } 1853 case Instruction::SUB_LONG_2ADDR: { 1854 uint32_t vregA = inst->VRegA_12x(); 1855 shadow_frame.SetVRegLong(vregA, 1856 shadow_frame.GetVRegLong(vregA) - 1857 shadow_frame.GetVRegLong(inst->VRegB_12x())); 1858 break; 1859 } 1860 case Instruction::MUL_LONG_2ADDR: { 1861 uint32_t vregA = inst->VRegA_12x(); 1862 shadow_frame.SetVRegLong(vregA, 1863 shadow_frame.GetVRegLong(vregA) * 1864 shadow_frame.GetVRegLong(inst->VRegB_12x())); 1865 break; 1866 } 1867 case Instruction::DIV_LONG_2ADDR: { 1868 uint32_t vregA = inst->VRegA_12x(); 1869 DoLongDivide(self, shadow_frame, vregA, shadow_frame.GetVRegLong(vregA), 1870 shadow_frame.GetVRegLong(inst->VRegB_12x())); 1871 break; 1872 } 1873 case Instruction::REM_LONG_2ADDR: { 1874 uint32_t vregA = inst->VRegA_12x(); 1875 DoLongRemainder(self, shadow_frame, vregA, shadow_frame.GetVRegLong(vregA), 1876 shadow_frame.GetVRegLong(inst->VRegB_12x())); 1877 break; 1878 } 1879 case Instruction::AND_LONG_2ADDR: { 1880 uint32_t vregA = inst->VRegA_12x(); 1881 shadow_frame.SetVRegLong(vregA, 1882 shadow_frame.GetVRegLong(vregA) & 1883 shadow_frame.GetVRegLong(inst->VRegB_12x())); 1884 break; 1885 } 1886 case Instruction::OR_LONG_2ADDR: { 1887 uint32_t vregA = inst->VRegA_12x(); 1888 shadow_frame.SetVRegLong(vregA, 1889 shadow_frame.GetVRegLong(vregA) | 1890 shadow_frame.GetVRegLong(inst->VRegB_12x())); 1891 break; 1892 } 1893 case Instruction::XOR_LONG_2ADDR: { 1894 uint32_t vregA = inst->VRegA_12x(); 1895 shadow_frame.SetVRegLong(vregA, 1896 shadow_frame.GetVRegLong(vregA) ^ 1897 shadow_frame.GetVRegLong(inst->VRegB_12x())); 1898 break; 1899 } 1900 case Instruction::SHL_LONG_2ADDR: { 1901 uint32_t vregA = inst->VRegA_12x(); 1902 shadow_frame.SetVRegLong(vregA, 1903 shadow_frame.GetVRegLong(vregA) << 1904 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f)); 1905 break; 1906 } 1907 case Instruction::SHR_LONG_2ADDR: { 1908 uint32_t vregA = inst->VRegA_12x(); 1909 shadow_frame.SetVRegLong(vregA, 1910 shadow_frame.GetVRegLong(vregA) >> 1911 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f)); 1912 break; 1913 } 1914 case Instruction::USHR_LONG_2ADDR: { 1915 uint32_t vregA = inst->VRegA_12x(); 1916 shadow_frame.SetVRegLong(vregA, 1917 static_cast<uint64_t>(shadow_frame.GetVRegLong(vregA)) >> 1918 (shadow_frame.GetVReg(inst->VRegB_12x()) & 0x3f)); 1919 break; 1920 } 1921 case Instruction::ADD_FLOAT_2ADDR: { 1922 uint32_t vregA = inst->VRegA_12x(); 1923 shadow_frame.SetVRegFloat(vregA, 1924 shadow_frame.GetVRegFloat(vregA) + 1925 shadow_frame.GetVRegFloat(inst->VRegB_12x())); 1926 break; 1927 } 1928 case Instruction::SUB_FLOAT_2ADDR: { 1929 uint32_t vregA = inst->VRegA_12x(); 1930 shadow_frame.SetVRegFloat(vregA, 1931 shadow_frame.GetVRegFloat(vregA) - 1932 shadow_frame.GetVRegFloat(inst->VRegB_12x())); 1933 break; 1934 } 1935 case Instruction::MUL_FLOAT_2ADDR: { 1936 uint32_t vregA = inst->VRegA_12x(); 1937 shadow_frame.SetVRegFloat(vregA, 1938 shadow_frame.GetVRegFloat(vregA) * 1939 shadow_frame.GetVRegFloat(inst->VRegB_12x())); 1940 break; 1941 } 1942 case Instruction::DIV_FLOAT_2ADDR: { 1943 uint32_t vregA = inst->VRegA_12x(); 1944 shadow_frame.SetVRegFloat(vregA, 1945 shadow_frame.GetVRegFloat(vregA) / 1946 shadow_frame.GetVRegFloat(inst->VRegB_12x())); 1947 break; 1948 } 1949 case Instruction::REM_FLOAT_2ADDR: { 1950 uint32_t vregA = inst->VRegA_12x(); 1951 shadow_frame.SetVRegFloat(vregA, 1952 fmodf(shadow_frame.GetVRegFloat(vregA), 1953 shadow_frame.GetVRegFloat(inst->VRegB_12x()))); 1954 break; 1955 } 1956 case Instruction::ADD_DOUBLE_2ADDR: { 1957 uint32_t vregA = inst->VRegA_12x(); 1958 shadow_frame.SetVRegDouble(vregA, 1959 shadow_frame.GetVRegDouble(vregA) + 1960 shadow_frame.GetVRegDouble(inst->VRegB_12x())); 1961 break; 1962 } 1963 case Instruction::SUB_DOUBLE_2ADDR: { 1964 uint32_t vregA = inst->VRegA_12x(); 1965 shadow_frame.SetVRegDouble(vregA, 1966 shadow_frame.GetVRegDouble(vregA) - 1967 shadow_frame.GetVRegDouble(inst->VRegB_12x())); 1968 break; 1969 } 1970 case Instruction::MUL_DOUBLE_2ADDR: { 1971 uint32_t vregA = inst->VRegA_12x(); 1972 shadow_frame.SetVRegDouble(vregA, 1973 shadow_frame.GetVRegDouble(vregA) * 1974 shadow_frame.GetVRegDouble(inst->VRegB_12x())); 1975 break; 1976 } 1977 case Instruction::DIV_DOUBLE_2ADDR: { 1978 uint32_t vregA = inst->VRegA_12x(); 1979 shadow_frame.SetVRegDouble(vregA, 1980 shadow_frame.GetVRegDouble(vregA) / 1981 shadow_frame.GetVRegDouble(inst->VRegB_12x())); 1982 break; 1983 } 1984 case Instruction::REM_DOUBLE_2ADDR: { 1985 uint32_t vregA = inst->VRegA_12x(); 1986 shadow_frame.SetVRegDouble(vregA, 1987 fmod(shadow_frame.GetVRegDouble(vregA), 1988 shadow_frame.GetVRegDouble(inst->VRegB_12x()))); 1989 break; 1990 } 1991 case Instruction::ADD_INT_LIT16: 1992 shadow_frame.SetVReg(inst->VRegA_22s(), 1993 shadow_frame.GetVReg(inst->VRegB_22s()) + 1994 inst->VRegC_22s()); 1995 break; 1996 case Instruction::RSUB_INT: 1997 shadow_frame.SetVReg(inst->VRegA_22s(), 1998 inst->VRegC_22s() - 1999 shadow_frame.GetVReg(inst->VRegB_22s())); 2000 break; 2001 case Instruction::MUL_INT_LIT16: 2002 shadow_frame.SetVReg(inst->VRegA_22s(), 2003 shadow_frame.GetVReg(inst->VRegB_22s()) * 2004 inst->VRegC_22s()); 2005 break; 2006 case Instruction::DIV_INT_LIT16: 2007 DoIntDivide(self, shadow_frame, inst->VRegA_22s(), 2008 shadow_frame.GetVReg(inst->VRegB_22s()), inst->VRegC_22s()); 2009 break; 2010 case Instruction::REM_INT_LIT16: 2011 DoIntRemainder(self, shadow_frame, inst->VRegA_22s(), 2012 shadow_frame.GetVReg(inst->VRegB_22s()), inst->VRegC_22s()); 2013 break; 2014 case Instruction::AND_INT_LIT16: 2015 shadow_frame.SetVReg(inst->VRegA_22s(), 2016 shadow_frame.GetVReg(inst->VRegB_22s()) & 2017 inst->VRegC_22s()); 2018 break; 2019 case Instruction::OR_INT_LIT16: 2020 shadow_frame.SetVReg(inst->VRegA_22s(), 2021 shadow_frame.GetVReg(inst->VRegB_22s()) | 2022 inst->VRegC_22s()); 2023 break; 2024 case Instruction::XOR_INT_LIT16: 2025 shadow_frame.SetVReg(inst->VRegA_22s(), 2026 shadow_frame.GetVReg(inst->VRegB_22s()) ^ 2027 inst->VRegC_22s()); 2028 break; 2029 case Instruction::ADD_INT_LIT8: 2030 shadow_frame.SetVReg(inst->VRegA_22b(), 2031 shadow_frame.GetVReg(inst->VRegB_22b()) + 2032 inst->VRegC_22b()); 2033 break; 2034 case Instruction::RSUB_INT_LIT8: 2035 shadow_frame.SetVReg(inst->VRegA_22b(), 2036 inst->VRegC_22b() - 2037 shadow_frame.GetVReg(inst->VRegB_22b())); 2038 break; 2039 case Instruction::MUL_INT_LIT8: 2040 shadow_frame.SetVReg(inst->VRegA_22b(), 2041 shadow_frame.GetVReg(inst->VRegB_22b()) * 2042 inst->VRegC_22b()); 2043 break; 2044 case Instruction::DIV_INT_LIT8: 2045 DoIntDivide(self, shadow_frame, inst->VRegA_22b(), 2046 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()); 2047 break; 2048 case Instruction::REM_INT_LIT8: 2049 DoIntRemainder(self, shadow_frame, inst->VRegA_22b(), 2050 shadow_frame.GetVReg(inst->VRegB_22b()), inst->VRegC_22b()); 2051 break; 2052 case Instruction::AND_INT_LIT8: 2053 shadow_frame.SetVReg(inst->VRegA_22b(), 2054 shadow_frame.GetVReg(inst->VRegB_22b()) & 2055 inst->VRegC_22b()); 2056 break; 2057 case Instruction::OR_INT_LIT8: 2058 shadow_frame.SetVReg(inst->VRegA_22b(), 2059 shadow_frame.GetVReg(inst->VRegB_22b()) | 2060 inst->VRegC_22b()); 2061 break; 2062 case Instruction::XOR_INT_LIT8: 2063 shadow_frame.SetVReg(inst->VRegA_22b(), 2064 shadow_frame.GetVReg(inst->VRegB_22b()) ^ 2065 inst->VRegC_22b()); 2066 break; 2067 case Instruction::SHL_INT_LIT8: 2068 shadow_frame.SetVReg(inst->VRegA_22b(), 2069 shadow_frame.GetVReg(inst->VRegB_22b()) << 2070 (inst->VRegC_22b() & 0x1f)); 2071 break; 2072 case Instruction::SHR_INT_LIT8: 2073 shadow_frame.SetVReg(inst->VRegA_22b(), 2074 shadow_frame.GetVReg(inst->VRegB_22b()) >> 2075 (inst->VRegC_22b() & 0x1f)); 2076 break; 2077 case Instruction::USHR_INT_LIT8: 2078 shadow_frame.SetVReg(inst->VRegA_22b(), 2079 static_cast<uint32_t>(shadow_frame.GetVReg(inst->VRegB_22b())) >> 2080 (inst->VRegC_22b() & 0x1f)); 2081 break; 2082 default: 2083 LOG(FATAL) << "Unexpected instruction: " << inst->DumpString(&mh.GetDexFile()); 2084 break; 2085 } 2086 if (UNLIKELY(self->IsExceptionPending())) { 2087 self->VerifyStack(); 2088 ThrowLocation throw_location; 2089 mirror::Throwable* exception = self->GetException(&throw_location); 2090 uint32_t found_dex_pc = shadow_frame.GetMethod()->FindCatchBlock(exception->GetClass(), dex_pc); 2091 if (found_dex_pc == DexFile::kDexNoIndex) { 2092 JValue result; 2093 result.SetJ(0); 2094 instrumentation->MethodUnwindEvent(self, this_object_ref.get(), 2095 shadow_frame.GetMethod(), dex_pc); 2096 return result; // Handler in caller. 2097 } else { 2098 instrumentation->ExceptionCaughtEvent(self, throw_location, 2099 shadow_frame.GetMethod(), 2100 found_dex_pc, exception); 2101 next_inst = Instruction::At(insns + found_dex_pc); 2102 } 2103 } 2104 inst = next_inst; 2105 } 2106} 2107 2108void EnterInterpreterFromInvoke(Thread* self, AbstractMethod* method, Object* receiver, 2109 uint32_t* args, JValue* result) { 2110 DCHECK_EQ(self, Thread::Current()); 2111 if (__builtin_frame_address(0) < self->GetStackEnd()) { 2112 ThrowStackOverflowError(self); 2113 return; 2114 } 2115 2116 MethodHelper mh(method); 2117 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 2118 uint16_t num_regs; 2119 uint16_t num_ins; 2120 if (code_item != NULL) { 2121 num_regs = code_item->registers_size_; 2122 num_ins = code_item->ins_size_; 2123 } else if (method->IsAbstract()) { 2124 ThrowLocation throw_location = self->GetCurrentLocationForThrow(); 2125 self->ThrowNewExceptionF(throw_location, "Ljava/lang/AbstractMethodError;", 2126 "abstract method \"%s\"", PrettyMethod(method).c_str()); 2127 return; 2128 } else { 2129 DCHECK(method->IsNative()); 2130 num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty()); 2131 if (!method->IsStatic()) { 2132 num_regs++; 2133 num_ins++; 2134 } 2135 } 2136 // Set up shadow frame with matching number of reference slots to vregs. 2137 ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame(); 2138 UniquePtr<ShadowFrame> shadow_frame(ShadowFrame::Create(num_regs, 2139 last_shadow_frame, 2140 method, 0)); 2141 self->PushShadowFrame(shadow_frame.get()); 2142 size_t cur_reg = num_regs - num_ins; 2143 if (!method->IsStatic()) { 2144 CHECK(receiver != NULL); 2145 shadow_frame->SetVRegReference(cur_reg, receiver); 2146 ++cur_reg; 2147 } else if (UNLIKELY(!method->GetDeclaringClass()->IsInitializing())) { 2148 ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 2149 if (UNLIKELY(!class_linker->EnsureInitialized(method->GetDeclaringClass(), 2150 true, true))) { 2151 CHECK(self->IsExceptionPending()); 2152 self->PopShadowFrame(); 2153 return; 2154 } 2155 CHECK(method->GetDeclaringClass()->IsInitializing()); 2156 } 2157 const char* shorty = mh.GetShorty(); 2158 for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) { 2159 DCHECK_LT(shorty_pos + 1, mh.GetShortyLength()); 2160 switch (shorty[shorty_pos + 1]) { 2161 case 'L': { 2162 Object* o = reinterpret_cast<Object*>(args[arg_pos]); 2163 shadow_frame->SetVRegReference(cur_reg, o); 2164 break; 2165 } 2166 case 'J': case 'D': { 2167 uint64_t wide_value = (static_cast<uint64_t>(args[arg_pos + 1]) << 32) | args[arg_pos]; 2168 shadow_frame->SetVRegLong(cur_reg, wide_value); 2169 cur_reg++; 2170 arg_pos++; 2171 break; 2172 } 2173 default: 2174 shadow_frame->SetVReg(cur_reg, args[arg_pos]); 2175 break; 2176 } 2177 } 2178 if (LIKELY(!method->IsNative())) { 2179 JValue r = Execute(self, mh, code_item, *shadow_frame.get(), JValue()); 2180 if (result != NULL) { 2181 *result = r; 2182 } 2183 } else { 2184 // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 2185 // generated stub) except during testing and image writing. 2186 if (!Runtime::Current()->IsStarted()) { 2187 UnstartedRuntimeJni(self, method, receiver, args, result); 2188 } else { 2189 InterpreterJni(self, method, shorty, receiver, args, result); 2190 } 2191 } 2192 self->PopShadowFrame(); 2193} 2194 2195void EnterInterpreterFromDeoptimize(Thread* self, ShadowFrame* shadow_frame, JValue* ret_val) 2196 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2197 JValue value; 2198 value.SetJ(ret_val->GetJ()); // Set value to last known result in case the shadow frame chain is empty. 2199 MethodHelper mh; 2200 while (shadow_frame != NULL) { 2201 self->SetTopOfShadowStack(shadow_frame); 2202 mh.ChangeMethod(shadow_frame->GetMethod()); 2203 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 2204 value = Execute(self, mh, code_item, *shadow_frame, value); 2205 ShadowFrame* old_frame = shadow_frame; 2206 shadow_frame = shadow_frame->GetLink(); 2207 delete old_frame; 2208 } 2209 ret_val->SetJ(value.GetJ()); 2210} 2211 2212JValue EnterInterpreterFromStub(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 2213 ShadowFrame& shadow_frame) 2214 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2215 DCHECK_EQ(self, Thread::Current()); 2216 if (__builtin_frame_address(0) < self->GetStackEnd()) { 2217 ThrowStackOverflowError(self); 2218 return JValue(); 2219 } 2220 2221 return Execute(self, mh, code_item, shadow_frame, JValue()); 2222} 2223 2224JValue EnterInterpreterFromInterpreter(Thread* self, ShadowFrame* shadow_frame) 2225 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2226 if (__builtin_frame_address(0) < self->GetStackEnd()) { 2227 ThrowStackOverflowError(self); 2228 return JValue(); 2229 } 2230 2231 AbstractMethod* method = shadow_frame->GetMethod(); 2232 if (method->IsStatic() && !method->GetDeclaringClass()->IsInitializing()) { 2233 if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(), 2234 true, true)) { 2235 DCHECK(Thread::Current()->IsExceptionPending()); 2236 return JValue(); 2237 } 2238 CHECK(method->GetDeclaringClass()->IsInitializing()); 2239 } 2240 2241 self->PushShadowFrame(shadow_frame); 2242 2243 MethodHelper mh(method); 2244 const DexFile::CodeItem* code_item = mh.GetCodeItem(); 2245 JValue result; 2246 if (LIKELY(!method->IsNative())) { 2247 result = Execute(self, mh, code_item, *shadow_frame, JValue()); 2248 } else { 2249 // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 2250 // generated stub) except during testing and image writing. 2251 CHECK(!Runtime::Current()->IsStarted()); 2252 Object* receiver = method->IsStatic() ? NULL : shadow_frame->GetVRegReference(0); 2253 uint32_t* args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1); 2254 UnstartedRuntimeJni(self, method, receiver, args, &result); 2255 } 2256 2257 self->PopShadowFrame(); 2258 return result; 2259} 2260 2261} // namespace interpreter 2262} // namespace art 2263