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