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