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