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