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