interpreter.cc revision 167436311a08a65dea28dda079a137893821c9c7
189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/*
289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Copyright (C) 2012 The Android Open Source Project
389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * you may not use this file except in compliance with the License.
689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * You may obtain a copy of the License at
789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * See the License for the specific language governing permissions and
1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * limitations under the License.
1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project */
1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "interpreter.h"
1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <math.h>
2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
2189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "base/logging.h"
2289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "class_linker-inl.h"
2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "common_throws.h"
2489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "dex_file-inl.h"
2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "dex_instruction.h"
2689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "gc/card_table-inl.h"
2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "invoke_arg_array_builder.h"
2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "nth_caller_visitor.h"
2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "mirror/class.h"
3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "mirror/class-inl.h"
3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "mirror/field-inl.h"
3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "mirror/abstract_method.h"
3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "mirror/abstract_method-inl.h"
3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "mirror/object-inl.h"
357562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include "mirror/object_array-inl.h"
367562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include "object_utils.h"
3789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "runtime_support.h"
3838ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent#include "ScopedLocalRef.h"
3989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include "scoped_thread_state_change.h"
40fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin#include "thread.h"
41fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
42fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinusing namespace art::mirror;
43fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin
44fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinnamespace art {
4589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace interpreter {
4789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
4889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic const int32_t kMaxInt = std::numeric_limits<int32_t>::max();
4933005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yehstatic const int32_t kMinInt = std::numeric_limits<int32_t>::min();
5033005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yehstatic const int64_t kMaxLong = std::numeric_limits<int64_t>::max();
5133005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yehstatic const int64_t kMinLong = std::numeric_limits<int64_t>::min();
5233005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh
5333005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yehstatic void UnstartedRuntimeInvoke(Thread* self, AbstractMethod* target_method,
5433005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh                                   ShadowFrame* shadow_frame, JValue* result, size_t arg_offset)
5533005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
5633005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh  // In a runtime that's not started we intercept certain methods to avoid complicated dependency
5733005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh  // problems in core libraries.
5833005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh  std::string name(PrettyMethod(target_method));
5933005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh  if (name == "java.lang.Class java.lang.Class.forName(java.lang.String)") {
6033005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    std::string descriptor(DotToDescriptor(shadow_frame->GetVRegReference(arg_offset)->AsString()->ToModifiedUtf8().c_str()));
6133005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    ClassLoader* class_loader = NULL; // shadow_frame.GetMethod()->GetDeclaringClass()->GetClassLoader();
6233005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    Class* found = Runtime::Current()->GetClassLinker()->FindClass(descriptor.c_str(),
6333005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh                                                                   class_loader);
6433005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    CHECK(found != NULL) << "Class.forName failed in un-started runtime for class: "
6533005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh        << PrettyDescriptor(descriptor);
6633005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    result->SetL(found);
6733005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh  } else if (name == "java.lang.Object java.lang.Class.newInstance()") {
6833005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
6933005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    AbstractMethod* c = klass->FindDeclaredDirectMethod("<init>", "()V");
7033005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    CHECK(c != NULL);
7133005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    Object* obj = klass->AllocObject(self);
7233005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    CHECK(obj != NULL);
7333005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    EnterInterpreterFromInvoke(self, c, obj, NULL, NULL);
7433005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    result->SetL(obj);
7533005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh  } else if (name == "java.lang.reflect.Field java.lang.Class.getDeclaredField(java.lang.String)") {
7633005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
7733005a932c60a0780fe9b7307d5988df3d9f6c26Chia-chi Yeh    // going the reflective Dex way.
7889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Class* klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
7989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    String* name = shadow_frame->GetVRegReference(arg_offset + 1)->AsString();
8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    Field* found = NULL;
8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    FieldHelper fh;
8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    ObjectArray<Field>* fields = klass->GetIFields();
8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    for (int32_t i = 0; i < fields->GetLength() && found == NULL; ++i) {
8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      Field* f = fields->Get(i);
8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      fh.ChangeField(f);
8689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      if (name->Equals(fh.GetName())) {
8789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        found = f;
8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
90c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    if (found == NULL) {
9189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      fields = klass->GetSFields();
9289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      for (int32_t i = 0; i < fields->GetLength() && found == NULL; ++i) {
9389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Field* f = fields->Get(i);
9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        fh.ChangeField(f);
95be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        if (name->Equals(fh.GetName())) {
96be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent          found = f;
9789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
9889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
99c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    }
100a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent    CHECK(found != NULL)
101a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent      << "Failed to find field in Class.getDeclaredField in un-started runtime. name="
10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      << name->ToModifiedUtf8() << " class=" << PrettyDescriptor(klass);
10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // TODO: getDeclaredField calls GetType once the field is found to ensure a
10489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    //       NoClassDefFoundError is thrown if the field's type cannot be resolved.
10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetL(found);
10689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (name == "void java.lang.System.arraycopy(java.lang.Object, int, java.lang.Object, int, int)") {
10789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Special case array copying without initializing System.
108c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    Class* ctype = shadow_frame->GetVRegReference(arg_offset)->GetClass()->GetComponentType();
10989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    jint srcPos = shadow_frame->GetVReg(arg_offset + 1);
11089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    jint dstPos = shadow_frame->GetVReg(arg_offset + 3);
11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    jint length = shadow_frame->GetVReg(arg_offset + 4);
11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (!ctype->IsPrimitive()) {
113be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent      ObjectArray<Object>* src = shadow_frame->GetVRegReference(arg_offset)->AsObjectArray<Object>();
114be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent      ObjectArray<Object>* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsObjectArray<Object>();
11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      for (jint i = 0; i < length; ++i) {
11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        dst->Set(dstPos + i, src->Get(srcPos + i));
117c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent      }
118a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent    } else if (ctype->IsPrimitiveChar()) {
119a514bdb58b5de4986679f72b7204b4764f7a2778Eric Laurent      CharArray* src = shadow_frame->GetVRegReference(arg_offset)->AsCharArray();
12089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      CharArray* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsCharArray();
12189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      for (jint i = 0; i < length; ++i) {
12289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        dst->Set(dstPos + i, src->Get(srcPos + i));
12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
12489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else if (ctype->IsPrimitiveInt()) {
12589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      IntArray* src = shadow_frame->GetVRegReference(arg_offset)->AsIntArray();
12689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      IntArray* dst = shadow_frame->GetVRegReference(arg_offset + 2)->AsIntArray();
12789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      for (jint i = 0; i < length; ++i) {
12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        dst->Set(dstPos + i, src->Get(srcPos + i));
12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
13089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else {
13189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      UNIMPLEMENTED(FATAL) << "System.arraycopy of unexpected type: " << PrettyDescriptor(ctype);
13289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else {
13489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Not special, continue with regular interpreter execution.
13589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetJ(EnterInterpreterFromInterpreter(self, shadow_frame).GetJ());
13689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  }
13789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
13889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// Hand select a number of methods to be run in a not yet started runtime without using JNI.
14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void UnstartedRuntimeJni(Thread* self, AbstractMethod* method,
14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                Object* receiver, uint32_t* args, JValue* result)
14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
14389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  std::string name(PrettyMethod(method));
144c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent  if (name == "java.lang.ClassLoader dalvik.system.VMStack.getCallingClassLoader()") {
14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetL(NULL);
14689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (name == "java.lang.Class dalvik.system.VMStack.getStackClass2()") {
14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    NthCallerVisitor visitor(self, 3);
14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    visitor.WalkStack();
14989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetL(visitor.caller->GetDeclaringClass());
15089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (name == "double java.lang.Math.log(double)") {
151be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    JValue value;
152be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetD(log(value.GetD()));
15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (name == "java.lang.String java.lang.Class.getNameNative()") {
15589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetL(receiver->AsClass()->ComputeName());
15689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (name == "int java.lang.Float.floatToRawIntBits(float)") {
1571703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    result->SetI(args[0]);
1581dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent  } else if (name == "float java.lang.Float.intBitsToFloat(int)") {
15989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetI(args[0]);
16089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (name == "double java.lang.Math.exp(double)") {
16189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    JValue value;
16289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]);
16389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetD(exp(value.GetD()));
16489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (name == "java.lang.Object java.lang.Object.internalClone()") {
16589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetL(receiver->Clone(self));
16689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (name == "void java.lang.Object.notifyAll()") {
16789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    receiver->NotifyAll(self);
16889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (name == "int java.lang.String.compareTo(java.lang.String)") {
16989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    String* rhs = reinterpret_cast<Object*>(args[0])->AsString();
17089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    CHECK(rhs != NULL);
17189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetI(receiver->AsString()->CompareTo(rhs));
17289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (name == "java.lang.String java.lang.String.intern()") {
173fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    result->SetL(receiver->AsString()->Intern());
174fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin  } else if (name == "int java.lang.String.fastIndexOf(int, int)") {
17589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetI(receiver->AsString()->FastIndexOf(args[0], args[1]));
17689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (name == "java.lang.Object java.lang.reflect.Array.createMultiArray(java.lang.Class, int[])") {
17789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetL(Array::CreateMultiArray(self, reinterpret_cast<Object*>(args[0])->AsClass(), reinterpret_cast<Object*>(args[1])->AsIntArray()));
17889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (name == "java.lang.Object java.lang.Throwable.nativeFillInStackTrace()") {
17989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    ScopedObjectAccessUnchecked soa(self);
18089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetL(soa.Decode<Object*>(self->CreateInternalStackTrace(soa)));
181fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin  } else if (name == "boolean java.nio.ByteOrder.isLittleEndian()") {
18289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetJ(JNI_TRUE);
183c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent  } else if (name == "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)") {
184fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    Object* obj = reinterpret_cast<Object*>(args[0]);
18589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1];
18689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    jint expectedValue = args[3];
18789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    jint newValue = args[4];
188fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    byte* raw_addr = reinterpret_cast<byte*>(obj) + offset;
18989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    volatile int32_t* address = reinterpret_cast<volatile int32_t*>(raw_addr);
19089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    // Note: android_atomic_release_cas() returns 0 on success, not failure.
19189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int r = android_atomic_release_cas(expectedValue, newValue, address);
192c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    result->SetZ(r == 0);
193c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent  } else if (name == "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)") {
194fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    Object* obj = reinterpret_cast<Object*>(args[0]);
195fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    Object* newValue = reinterpret_cast<Object*>(args[3]);
196c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    obj->SetFieldObject(MemberOffset((static_cast<uint64_t>(args[2]) << 32) | args[1]), newValue, false);
197c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent  } else {
198fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    LOG(FATAL) << "Attempt to invoke native method in non-started runtime: " << name;
199c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent  }
20089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
20189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
202fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavinstatic void InterpreterJni(Thread* self, AbstractMethod* method, StringPiece shorty,
20389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                           Object* receiver, uint32_t* args, JValue* result)
204fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
205fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin  // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler,
206fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin  //       it should be removed and JNI compiled stubs used instead.
207fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin  ScopedObjectAccessUnchecked soa(self);
20889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  if (method->IsStatic()) {
209c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    if (shorty == "L") {
210c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent      typedef jobject (fnptr)(JNIEnv*, jclass);
211c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
21289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jclass> klass(soa.Env(),
21389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
21434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      jobject jresult;
21534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      {
216be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        ScopedThreadStateChange tsc(self, kNative);
217d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        jresult = fn(soa.Env(), klass.get());
218d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      }
219be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent      result->SetL(soa.Decode<Object*>(jresult));
2202beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent    } else if (shorty == "V") {
221be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent      typedef void (fnptr)(JNIEnv*, jclass);
22234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
2231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      ScopedLocalRef<jclass> klass(soa.Env(),
2241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                                   soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
2251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      ScopedThreadStateChange tsc(self, kNative);
2261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      fn(soa.Env(), klass.get());
2271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    } else if (shorty == "Z") {
2281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      typedef jboolean (fnptr)(JNIEnv*, jclass);
2291703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
2301703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      ScopedLocalRef<jclass> klass(soa.Env(),
2311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                                   soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
23289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedThreadStateChange tsc(self, kNative);
23334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      result->SetZ(fn(soa.Env(), klass.get()));
23489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else if (shorty == "BI") {
23589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      typedef jbyte (fnptr)(JNIEnv*, jclass, jint);
23634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
23789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jclass> klass(soa.Env(),
23889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
23989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedThreadStateChange tsc(self, kNative);
24089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      result->SetB(fn(soa.Env(), klass.get(), args[0]));
24189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else if (shorty == "II") {
24289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      typedef jint (fnptr)(JNIEnv*, jclass, jint);
24389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
24489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jclass> klass(soa.Env(),
24589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
24689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedThreadStateChange tsc(self, kNative);
24789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      result->SetI(fn(soa.Env(), klass.get(), args[0]));
24889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else if (shorty == "LL") {
249c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent      typedef jobject (fnptr)(JNIEnv*, jclass, jobject);
25089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
25189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jclass> klass(soa.Env(),
25289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
25389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jobject> arg0(soa.Env(),
25489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0])));
25589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      jobject jresult;
25689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      {
25789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        ScopedThreadStateChange tsc(self, kNative);
2582c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi        jresult = fn(soa.Env(), klass.get(), arg0.get());
25989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
26089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      result->SetL(soa.Decode<Object*>(jresult));
261c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    } else if (shorty == "IIZ") {
26289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      typedef jint (fnptr)(JNIEnv*, jclass, jint, jboolean);
26389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
26489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jclass> klass(soa.Env(),
26589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
26689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedThreadStateChange tsc(self, kNative);
26789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      result->SetI(fn(soa.Env(), klass.get(), args[0], args[1]));
26889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else if (shorty == "ILI") {
26989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      typedef jint (fnptr)(JNIEnv*, jclass, jobject, jint);
27089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
27189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jclass> klass(soa.Env(),
27289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
27389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jobject> arg0(soa.Env(),
27489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0])));
27589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedThreadStateChange tsc(self, kNative);
27689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1]));
27789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else if (shorty == "SIZ") {
27889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      typedef jshort (fnptr)(JNIEnv*, jclass, jint, jboolean);
27989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
28089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jclass> klass(soa.Env(),
28189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
28289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedThreadStateChange tsc(self, kNative);
28389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      result->SetS(fn(soa.Env(), klass.get(), args[0], args[1]));
28489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else if (shorty == "VIZ") {
28589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      typedef void (fnptr)(JNIEnv*, jclass, jint, jboolean);
28689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
28789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jclass> klass(soa.Env(),
28889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
28989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedThreadStateChange tsc(self, kNative);
29089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      fn(soa.Env(), klass.get(), args[0], args[1]);
29189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else if (shorty == "ZLL") {
29289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      typedef jboolean (fnptr)(JNIEnv*, jclass, jobject, jobject);
29389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
29489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jclass> klass(soa.Env(),
295d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent                                   soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
29689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jobject> arg0(soa.Env(),
29789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0])));
29889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jobject> arg1(soa.Env(),
29989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1])));
300fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin      ScopedThreadStateChange tsc(self, kNative);
301fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin      result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get()));
302c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    } else if (shorty == "ZILL") {
303c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent      typedef jboolean (fnptr)(JNIEnv*, jclass, jint, jobject, jobject);
304c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
30589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jclass> klass(soa.Env(),
30689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
30789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jobject> arg1(soa.Env(),
30889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1])));
30989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jobject> arg2(soa.Env(),
31089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[2])));
31189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedThreadStateChange tsc(self, kNative);
31289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      result->SetZ(fn(soa.Env(), klass.get(), args[0], arg1.get(), arg2.get()));
31389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else if (shorty == "VILII") {
31489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      typedef void (fnptr)(JNIEnv*, jclass, jint, jobject, jint, jint);
31589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
31689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jclass> klass(soa.Env(),
317d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent                                   soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
31889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jobject> arg1(soa.Env(),
31989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1])));
32089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedThreadStateChange tsc(self, kNative);
32189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      fn(soa.Env(), klass.get(), args[0], arg1.get(), args[2], args[3]);
32289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else if (shorty == "VLILII") {
32389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      typedef void (fnptr)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint);
32489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
32589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jclass> klass(soa.Env(),
32689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jclass>(method->GetDeclaringClass()));
32789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jobject> arg0(soa.Env(),
32889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                   soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0])));
32989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      ScopedLocalRef<jobject> arg2(soa.Env(),
330f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent                                   soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[2])));
3311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      ScopedThreadStateChange tsc(self, kNative);
3321703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      fn(soa.Env(), klass.get(), arg0.get(), args[1], arg2.get(), args[3], args[4]);
3331703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    } else {
3341703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      LOG(FATAL) << "Do something with static native method: " << PrettyMethod(method)
3351703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          << " shorty: " << shorty;
3361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    }
337f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent  } else {
338f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent    if (shorty == "L") {
3391703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      typedef jobject (fnptr)(JNIEnv*, jobject);
34033797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
3411703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      ScopedLocalRef<jobject> rcvr(soa.Env(),
3421703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                                   soa.AddLocalReference<jobject>(receiver));
34338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent      jobject jresult;
3442b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent      {
3452b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent        ScopedThreadStateChange tsc(self, kNative);
3462b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent        jresult = fn(soa.Env(), rcvr.get());
3472b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent      }
3482b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent      result->SetL(soa.Decode<Object*>(jresult));
3492b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent    } else if (shorty == "LL") {
3501703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      typedef jobject (fnptr)(JNIEnv*, jobject, jobject);
3511703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
3521703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      ScopedLocalRef<jobject> rcvr(soa.Env(),
353d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent                                   soa.AddLocalReference<jobject>(receiver));
3541703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      ScopedLocalRef<jobject> arg0(soa.Env(),
3551703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                                   soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0])));
35638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent      jobject jresult;
3576100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent      {
3582b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent        ScopedThreadStateChange tsc(self, kNative);
3591703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        jresult = fn(soa.Env(), rcvr.get(), arg0.get());
3601703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
3611703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      }
3621703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      result->SetL(soa.Decode<Object*>(jresult));
3632b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent      ScopedThreadStateChange tsc(self, kNative);
3642b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent    } else if (shorty == "III") {
365f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent      typedef jint (fnptr)(JNIEnv*, jobject, jint, jint);
36634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      fnptr* fn = reinterpret_cast<fnptr*>(method->GetNativeMethod());
3672b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent      ScopedLocalRef<jobject> rcvr(soa.Env(),
36834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                   soa.AddLocalReference<jobject>(receiver));
3692b584244930c9de0e3bc46898a801e9ccb731900Eric Laurent      ScopedThreadStateChange tsc(self, kNative);
37034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      result->SetI(fn(soa.Env(), rcvr.get(), args[0], args[1]));
37189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else {
37289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      LOG(FATAL) << "Do something with native method: " << PrettyMethod(method)
37389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          << " shorty: " << shorty;
37489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
37589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  }
37689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
37789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
37889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoMonitorEnter(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS {
37989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  ref->MonitorEnter(self);
38089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
38189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoMonitorExit(Thread* self, Object* ref) NO_THREAD_SAFETY_ANALYSIS {
38389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  ref->MonitorExit(self);
38489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
38589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
38689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoInvoke(Thread* self, MethodHelper& mh, ShadowFrame& shadow_frame,
38789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                     const DecodedInstruction& dec_insn, InvokeType type, bool is_range,
388f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent                     JValue* result)
389f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
390f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent  Object* receiver;
3911dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent  if (type == kStatic) {
39289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    receiver = NULL;
39389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else {
39489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    receiver = shadow_frame.GetVRegReference(dec_insn.vC);
3951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent  }
3962c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi  uint32_t method_idx = dec_insn.vB;
3972c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi  AbstractMethod* target_method = FindMethodFromCode(method_idx, receiver,
3982c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi                                                     shadow_frame.GetMethod(), self, true,
39989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                                     type);
40089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  if (UNLIKELY(target_method == NULL)) {
40189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    CHECK(self->IsExceptionPending());
4021703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    result->SetJ(0);
40389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return;
40489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  }
40589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  mh.ChangeMethod(target_method);
40689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
40789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  const DexFile::CodeItem* code_item = mh.GetCodeItem();
40889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  uint16_t num_regs;
40989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  uint16_t num_ins;
41089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  if (code_item != NULL) {
41189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    num_regs = code_item->registers_size_;
41289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    num_ins = code_item->ins_size_;
41389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (target_method->IsAbstract()) {
41489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    ThrowLocation throw_location = self->GetCurrentLocationForThrow();
41589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    self->ThrowNewExceptionF(throw_location, "Ljava/lang/AbstractMethodError;",
41689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                             "abstract method \"%s\"", PrettyMethod(target_method).c_str());
41789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return;
41889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else {
41989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    DCHECK(target_method->IsNative() || target_method->IsProxyMethod());
42089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty());
42189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (!target_method->IsStatic()) {
42289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      num_regs++;
4231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      num_ins++;
4241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    }
4251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent  }
4261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent
4271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent  Runtime* runtime = Runtime::Current();
4281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent  UniquePtr<ShadowFrame> new_shadow_frame(ShadowFrame::Create(num_regs, &shadow_frame,
4291703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                                                              target_method, 0));
43089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  size_t cur_reg = num_regs - num_ins;
431c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent  if (receiver != NULL) {
4322c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi    new_shadow_frame->SetVRegReference(cur_reg, receiver);
4332c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi    ++cur_reg;
4342c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi  }
4352c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi
436c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent  size_t arg_offset = (receiver == NULL) ? 0 : 1;
43789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  const char* shorty = mh.GetShorty();
43889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  for (size_t shorty_pos = 0; cur_reg < num_regs; ++shorty_pos, cur_reg++, arg_offset++) {
43989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    DCHECK_LT(shorty_pos + 1, mh.GetShortyLength());
44089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    size_t arg_pos = is_range ? dec_insn.vC + arg_offset : dec_insn.arg[arg_offset];
44189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    switch (shorty[shorty_pos + 1]) {
44289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case 'L': {
44389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Object* o = shadow_frame.GetVRegReference(arg_pos);
44489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        new_shadow_frame->SetVRegReference(cur_reg, o);
44589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
44689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
44789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case 'J': case 'D': {
448f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent        uint64_t wide_value = (static_cast<uint64_t>(shadow_frame.GetVReg(arg_pos + 1)) << 32) |
449f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent                              static_cast<uint32_t>(shadow_frame.GetVReg(arg_pos));
450f5aafb209d01ba2ab6cb55d1a12cfc653e2b4be0Eric Laurent        new_shadow_frame->SetVRegLong(cur_reg, wide_value);
45189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        cur_reg++;
45289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        arg_offset++;
45389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
45489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
45589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      default:
45689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        new_shadow_frame->SetVReg(cur_reg, shadow_frame.GetVReg(arg_pos));
45789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
45889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
45989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  }
46089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
46189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  if (LIKELY(runtime->IsStarted())) {
46289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    result->SetJ((target_method->GetEntryPointFromInterpreter())(self, new_shadow_frame.get()).GetJ());
46389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else {
46489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    UnstartedRuntimeInvoke(self, target_method, new_shadow_frame.get(), result, num_regs - num_ins);
46589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  }
466be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent  mh.ChangeMethod(shadow_frame.GetMethod());
46789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
468be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent
469be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurentstatic void DoFieldGet(Thread* self, ShadowFrame& shadow_frame,
470be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent                       const DecodedInstruction& dec_insn, FindFieldType find_type,
471be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent                       Primitive::Type field_type)
4721703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
47389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead);
47489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC;
47589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self,
47689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                               find_type, Primitive::FieldSize(field_type));
477be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent  if (LIKELY(f != NULL)) {
478be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    Object* obj;
479be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    if (is_static) {
48089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      obj = f->GetDeclaringClass();
48189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else {
48289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      obj = shadow_frame.GetVRegReference(dec_insn.vB);
48389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      if (UNLIKELY(obj == NULL)) {
484be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(), f, true);
485be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        return;
486be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent      }
487be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    }
488be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent    switch (field_type) {
489be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent      case Primitive::kPrimBoolean:
490be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        shadow_frame.SetVReg(dec_insn.vA, f->GetBoolean(obj));
491be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        break;
4922beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent      case Primitive::kPrimByte:
493be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        shadow_frame.SetVReg(dec_insn.vA, f->GetByte(obj));
4942beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        break;
495be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent      case Primitive::kPrimChar:
496be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        shadow_frame.SetVReg(dec_insn.vA, f->GetChar(obj));
497be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        break;
4981703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Primitive::kPrimShort:
499be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        shadow_frame.SetVReg(dec_insn.vA, f->GetShort(obj));
500be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        break;
501be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent      case Primitive::kPrimInt:
502be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        shadow_frame.SetVReg(dec_insn.vA, f->GetInt(obj));
503be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        break;
504be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent      case Primitive::kPrimLong:
505be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        shadow_frame.SetVRegLong(dec_insn.vA, f->GetLong(obj));
506be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        break;
5072beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent      case Primitive::kPrimNot:
508be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        shadow_frame.SetVRegReference(dec_insn.vA, f->GetObject(obj));
509be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        break;
510be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent      default:
511be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        LOG(FATAL) << "Unreachable: " << field_type;
51289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
51389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  }
514573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent}
51589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
51689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoFieldPut(Thread* self, ShadowFrame& shadow_frame,
51789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                       const DecodedInstruction& dec_insn, FindFieldType find_type,
51889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                       Primitive::Type field_type)
519573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
52089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  bool is_static = (find_type == StaticObjectWrite) || (find_type == StaticPrimitiveWrite);
52189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  uint32_t field_idx = is_static ? dec_insn.vB : dec_insn.vC;
522573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent  Field* f = FindFieldFromCode(field_idx, shadow_frame.GetMethod(), self,
52389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                               find_type, Primitive::FieldSize(field_type));
5241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent  if (LIKELY(f != NULL)) {
525573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent    Object* obj;
526573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent    if (is_static) {
52789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      obj = f->GetDeclaringClass();
52889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    } else {
52989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      obj = shadow_frame.GetVRegReference(dec_insn.vB);
53089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      if (UNLIKELY(obj == NULL)) {
5311703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        ThrowNullPointerExceptionForFieldAccess(shadow_frame.GetCurrentLocationForThrow(),
532573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent                                                f, false);
53389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        return;
53489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
53589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
53689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    switch (field_type) {
5371703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Primitive::kPrimBoolean:
5381703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        f->SetBoolean(obj, shadow_frame.GetVReg(dec_insn.vA));
5391703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
5401703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Primitive::kPrimByte:
5411703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        f->SetByte(obj, shadow_frame.GetVReg(dec_insn.vA));
5421703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
5431703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Primitive::kPrimChar:
54489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        f->SetChar(obj, shadow_frame.GetVReg(dec_insn.vA));
54589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
54689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Primitive::kPrimShort:
54789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        f->SetShort(obj, shadow_frame.GetVReg(dec_insn.vA));
54889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
54989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Primitive::kPrimInt:
55089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        f->SetInt(obj, shadow_frame.GetVReg(dec_insn.vA));
55189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
55289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Primitive::kPrimLong:
55389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        f->SetLong(obj, shadow_frame.GetVRegLong(dec_insn.vA));
55489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
55589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Primitive::kPrimNot:
55689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        f->SetObj(obj, shadow_frame.GetVRegReference(dec_insn.vA));
5579b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent        break;
5589b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent      default:
559d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        LOG(FATAL) << "Unreachable: " << field_type;
56089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
56189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  }
56289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
5639b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent
56489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoIntDivide(Thread* self, ShadowFrame& shadow_frame, size_t result_reg,
565d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent    int32_t dividend, int32_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
56689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  if (UNLIKELY(divisor == 0)) {
567c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent    ThrowArithmeticExceptionDivideByZero(self);
56889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (UNLIKELY(dividend == kMinInt && divisor == -1)) {
56989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    shadow_frame.SetVReg(result_reg, kMinInt);
57089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else {
57189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    shadow_frame.SetVReg(result_reg, dividend / divisor);
57289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  }
57389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
57489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
57589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoIntRemainder(Thread* self, ShadowFrame& shadow_frame, size_t result_reg,
57689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int32_t dividend, int32_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
57789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  if (UNLIKELY(divisor == 0)) {
57889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    ThrowArithmeticExceptionDivideByZero(self);
5791703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent  } else if (UNLIKELY(dividend == kMinInt && divisor == -1)) {
58089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    shadow_frame.SetVReg(result_reg, 0);
58189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else {
58289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    shadow_frame.SetVReg(result_reg, dividend % divisor);
58389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  }
58489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
58589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
58689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoLongDivide(Thread* self, ShadowFrame& shadow_frame, size_t result_reg,
58789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int64_t dividend, int64_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
58889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  if (UNLIKELY(divisor == 0)) {
58989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    ThrowArithmeticExceptionDivideByZero(self);
59089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (UNLIKELY(dividend == kMinLong && divisor == -1)) {
59189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    shadow_frame.SetVRegLong(result_reg, kMinLong);
59289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else {
59389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    shadow_frame.SetVRegLong(result_reg, dividend / divisor);
59489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  }
59589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
59689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
59789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic void DoLongRemainder(Thread* self, ShadowFrame& shadow_frame, size_t result_reg,
59889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    int64_t dividend, int64_t divisor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
59989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  if (UNLIKELY(divisor == 0)) {
60089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    ThrowArithmeticExceptionDivideByZero(self);
60189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else if (UNLIKELY(dividend == kMinLong && divisor == -1)) {
6022c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi    shadow_frame.SetVRegLong(result_reg, 0);
60389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  } else {
60489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    shadow_frame.SetVRegLong(result_reg, dividend % divisor);
60589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  }
60689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}
60789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
60889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatic JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
60989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                      ShadowFrame& shadow_frame, JValue result_register)
61089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
61189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  if (UNLIKELY(!shadow_frame.HasReferenceArray())) {
61289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    LOG(FATAL) << "Invalid shadow frame for interpreter use";
61389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    return JValue();
61489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  }
61589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  self->VerifyStack();
61689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
61789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  const uint16_t* insns = code_item->insns_;
61889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  const Instruction* inst = Instruction::At(insns + shadow_frame.GetDexPC());
61989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  if (inst->GetDexPc(insns) == 0) {  // We are entering the method as opposed to deoptimizing..
62089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(), shadow_frame.GetMethod(),
62189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                      0);
62289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  }
62389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project  while (true) {
62489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    CheckSuspend(self);
62589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    uint32_t dex_pc = inst->GetDexPc(insns);
62689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    shadow_frame.SetDexPC(dex_pc);
62789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    instrumentation->DexPcMovedEvent(self, shadow_frame.GetThisObject(), shadow_frame.GetMethod(),
62889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                                     dex_pc);
62989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    DecodedInstruction dec_insn(inst);
63089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const bool kTracing = false;
63189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    if (kTracing) {
63289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define TRACE_LOG std::cerr
63389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      TRACE_LOG << PrettyMethod(shadow_frame.GetMethod())
63489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                << StringPrintf("\n0x%x: ", inst->GetDexPc(insns))
63589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                << inst->DumpString(&mh.GetDexFile()) << "\n";
63689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      for (size_t i = 0; i < shadow_frame.NumberOfVRegs(); ++i) {
63789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint32_t raw_value = shadow_frame.GetVReg(i);
63889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Object* ref_value = shadow_frame.GetVRegReference(i);
6391703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        TRACE_LOG << StringPrintf(" vreg%d=0x%08X", i, raw_value);
64089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (ref_value != NULL) {
64189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          if (ref_value->GetClass()->IsStringClass() &&
64289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project              ref_value->AsString()->GetCharArray() != NULL) {
64389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            TRACE_LOG << "/java.lang.String \"" << ref_value->AsString()->ToModifiedUtf8() << "\"";
64489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          } else {
64589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            TRACE_LOG << "/" << PrettyTypeOf(ref_value);
64689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          }
64738ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        }
648c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent      }
64989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      TRACE_LOG << "\n";
65089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#undef TRACE_LOG
65189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    }
65289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    const Instruction* next_inst = inst->Next();
65389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    switch (dec_insn.opcode) {
65489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::NOP:
6551703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
65689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::MOVE:
65789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::MOVE_FROM16:
65889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::MOVE_16:
65989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
66089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
66189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::MOVE_WIDE:
66289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::MOVE_WIDE_FROM16:
6631703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::MOVE_WIDE_16:
6641703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
66589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
666c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent      case Instruction::MOVE_OBJECT:
6671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::MOVE_OBJECT_FROM16:
66889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::MOVE_OBJECT_16:
669d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        shadow_frame.SetVRegReference(dec_insn.vA, shadow_frame.GetVRegReference(dec_insn.vB));
67089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
67189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::MOVE_RESULT:
67289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        shadow_frame.SetVReg(dec_insn.vA, result_register.GetI());
67389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
674c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent      case Instruction::MOVE_RESULT_WIDE:
675c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        shadow_frame.SetVRegLong(dec_insn.vA, result_register.GetJ());
6761703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
6771703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::MOVE_RESULT_OBJECT:
6781703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        shadow_frame.SetVRegReference(dec_insn.vA, result_register.GetL());
6791703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
6801703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::MOVE_EXCEPTION: {
6811703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        Throwable* exception = self->GetException(NULL);
6821703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        self->ClearException();
683fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        shadow_frame.SetVRegReference(dec_insn.vA, exception);
684fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        break;
685c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent      }
686c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent      case Instruction::RETURN_VOID: {
687be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        JValue result;
688be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(),
689be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent                                         shadow_frame.GetMethod(), shadow_frame.GetDexPC(),
690be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent                                         result);
691be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        return result;
692be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent      }
693be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent      case Instruction::RETURN: {
6942beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        JValue result;
6952beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        result.SetJ(0);
6962beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        result.SetI(shadow_frame.GetVReg(dec_insn.vA));
6972beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(),
6982beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent                                         shadow_frame.GetMethod(), shadow_frame.GetDexPC(),
6992beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent                                         result);
700be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent        return result;
701be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent      }
70289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::RETURN_WIDE: {
70389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        JValue result;
7041703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        result.SetJ(shadow_frame.GetVRegLong(dec_insn.vA));
7051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(),
70634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                         shadow_frame.GetMethod(), shadow_frame.GetDexPC(),
70734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                         result);
70834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        return result;
70934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      }
71034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      case Instruction::RETURN_OBJECT: {
71134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        JValue result;
71234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        result.SetJ(0);
713d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        result.SetL(shadow_frame.GetVRegReference(dec_insn.vA));
714d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        instrumentation->MethodExitEvent(self, shadow_frame.GetThisObject(),
71534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                         shadow_frame.GetMethod(), shadow_frame.GetDexPC(),
71634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent                                         result);
71734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        return result;
71834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      }
71934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      case Instruction::CONST_4: {
72034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        int32_t val = static_cast<int32_t>(dec_insn.vB << 28) >> 28;
72134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        shadow_frame.SetVReg(dec_insn.vA, val);
72234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        if (val == 0) {
723d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent          shadow_frame.SetVRegReference(dec_insn.vA, NULL);
724d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        }
725d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        break;
726d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      }
727d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      case Instruction::CONST_16: {
728d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        int32_t val = static_cast<int16_t>(dec_insn.vB);
729d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        shadow_frame.SetVReg(dec_insn.vA, val);
730d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        if (val == 0) {
731d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent          shadow_frame.SetVRegReference(dec_insn.vA, NULL);
732d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        }
733d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        break;
734d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      }
735d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      case Instruction::CONST: {
736d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        int32_t val = dec_insn.vB;
737fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        shadow_frame.SetVReg(dec_insn.vA, val);
738d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        if (val == 0) {
739d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent          shadow_frame.SetVRegReference(dec_insn.vA, NULL);
740d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        }
741d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        break;
742d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      }
743d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      case Instruction::CONST_HIGH16: {
744d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        int32_t val = dec_insn.vB << 16;
745d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        shadow_frame.SetVReg(dec_insn.vA, val);
746d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        if (val == 0) {
747d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent          shadow_frame.SetVRegReference(dec_insn.vA, NULL);
748d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        }
749d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        break;
750d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      }
751d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      case Instruction::CONST_WIDE_16:
752d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        shadow_frame.SetVRegLong(dec_insn.vA, static_cast<int16_t>(dec_insn.vB));
753d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        break;
754d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      case Instruction::CONST_WIDE_32:
755d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        shadow_frame.SetVRegLong(dec_insn.vA, static_cast<int32_t>(dec_insn.vB));
756d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        break;
757d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      case Instruction::CONST_WIDE:
758d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        shadow_frame.SetVRegLong(dec_insn.vA, dec_insn.vB_wide);
759d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        break;
760d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      case Instruction::CONST_WIDE_HIGH16:
761d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        shadow_frame.SetVRegLong(dec_insn.vA, static_cast<uint64_t>(dec_insn.vB) << 48);
762d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        break;
763d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      case Instruction::CONST_STRING:
764d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      case Instruction::CONST_STRING_JUMBO: {
765d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        if (UNLIKELY(!String::GetJavaLangString()->IsInitialized())) {
766d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent          Runtime::Current()->GetClassLinker()->EnsureInitialized(String::GetJavaLangString(),
767d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent                                                                  true, true);
768d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        }
769d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        String* s = mh.ResolveString(dec_insn.vB);
770d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        shadow_frame.SetVRegReference(dec_insn.vA, s);
771d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        break;
772d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      }
773d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      case Instruction::CONST_CLASS: {
774d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        Class* c = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true);
775d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        shadow_frame.SetVRegReference(dec_insn.vA, c);
776d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        break;
777d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      }
77834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      case Instruction::MONITOR_ENTER: {
77934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        Object* obj = shadow_frame.GetVRegReference(dec_insn.vA);
78034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        if (UNLIKELY(obj == NULL)) {
78134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
78234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        } else {
78334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent          DoMonitorEnter(self, obj);
78434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        }
78534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        break;
78634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      }
787be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent      case Instruction::MONITOR_EXIT: {
78834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        Object* obj = shadow_frame.GetVRegReference(dec_insn.vA);
78934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        if (UNLIKELY(obj == NULL)) {
79034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
79134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        } else {
79234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent          DoMonitorExit(self, obj);
79334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        }
79434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        break;
79534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      }
79634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      case Instruction::CHECK_CAST: {
79734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        Class* c = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true);
79834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        if (UNLIKELY(c == NULL)) {
79934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent          CHECK(self->IsExceptionPending());
80034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        } else {
80134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent          Object* obj = shadow_frame.GetVRegReference(dec_insn.vA);
80234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent          if (UNLIKELY(obj != NULL && !obj->InstanceOf(c))) {
80334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent            ThrowClassCastException(c, obj->GetClass());
80438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent          }
80534f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        }
80634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        break;
80734f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      }
80834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      case Instruction::INSTANCE_OF: {
80934f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        Class* c = ResolveVerifyAndClinit(dec_insn.vC, shadow_frame.GetMethod(), self, false, true);
810d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        if (UNLIKELY(c == NULL)) {
81134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent          CHECK(self->IsExceptionPending());
81234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        } else {
813be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent          Object* obj = shadow_frame.GetVRegReference(dec_insn.vB);
814be916aa1267e2e6b1c148f51d11bcbbc79cb864cEric Laurent          shadow_frame.SetVReg(dec_insn.vA, (obj != NULL && obj->InstanceOf(c)) ? 1 : 0);
8152beeb50b1bba9e92f6cacfeca37fe9fa9d36ead1Eric Laurent        }
8166100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent        break;
8176100d2d60517ff33ed8eb35d0b7ea63cde0831c9Eric Laurent      }
818d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent      case Instruction::ARRAY_LENGTH:  {
819d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        Object* array = shadow_frame.GetVRegReference(dec_insn.vB);
82034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        if (UNLIKELY(array == NULL)) {
82134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
82234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent          break;
82389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
82489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        shadow_frame.SetVReg(dec_insn.vA, array->AsArray()->GetLength());
8251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
82689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
82789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::NEW_INSTANCE: {
82889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Object* obj = AllocObjectFromCode(dec_insn.vB, shadow_frame.GetMethod(), self, true);
82989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        shadow_frame.SetVRegReference(dec_insn.vA, obj);
8301dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent        break;
83189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
83289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::NEW_ARRAY: {
83389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int32_t length = shadow_frame.GetVReg(dec_insn.vB);
83489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Object* obj = AllocArrayFromCode(dec_insn.vC, shadow_frame.GetMethod(), length, self, true);
83589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        shadow_frame.SetVRegReference(dec_insn.vA, obj);
83689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
8379b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent      }
8389b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent      case Instruction::FILLED_NEW_ARRAY:
8399b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent      case Instruction::FILLED_NEW_ARRAY_RANGE: {
8409b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent        bool is_range = (dec_insn.opcode == Instruction::FILLED_NEW_ARRAY_RANGE);
8419b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent        int32_t length = dec_insn.vA;
8429b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent        CHECK(is_range || length <= 5);
84389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (UNLIKELY(length < 0)) {
84434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent          ThrowNegativeArraySizeException(length);
84589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          break;
84689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
84789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Class* arrayClass = ResolveVerifyAndClinit(dec_insn.vB, shadow_frame.GetMethod(), self, false, true);
84889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (UNLIKELY(arrayClass == NULL)) {
84989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          CHECK(self->IsExceptionPending());
85034f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent          break;
85189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
85289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        CHECK(arrayClass->IsArrayClass());
85334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        Class* componentClass = arrayClass->GetComponentType();
85434f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        if (UNLIKELY(componentClass->IsPrimitive() && !componentClass->IsPrimitiveInt())) {
85589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          if (componentClass->IsPrimitiveLong() || componentClass->IsPrimitiveDouble()) {
85634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent            ThrowRuntimeException("Bad filled array request for type %s",
857d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent                                  PrettyDescriptor(componentClass).c_str());
8581703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          } else {
859d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent            self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
8601703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                                     "Ljava/lang/InternalError;",
8611703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                                     "Found type %s; filled-new-array not implemented for anything but \'int\'",
8621703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                                     PrettyDescriptor(componentClass).c_str());
8631703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          }
8641703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          break;
8651703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
866d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        Object* newArray = Array::Alloc(self, arrayClass, length);
8671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (newArray != NULL) {
868d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent          for (int32_t i = 0; i < length; ++i) {
869d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent            if (is_range) {
870d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent              if (componentClass->IsPrimitiveInt()) {
871c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent                newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(dec_insn.vC + i));
8721dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent              } else {
87389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(dec_insn.vC + i));
87489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project              }
87589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            } else {
87689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project              if (componentClass->IsPrimitiveInt()) {
87789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project                newArray->AsIntArray()->Set(i, shadow_frame.GetVReg(dec_insn.arg[i]));
87889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project              } else {
879c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent                newArray->AsObjectArray<Object>()->Set(i, shadow_frame.GetVRegReference(dec_insn.arg[i]));
88089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project              }
88134f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent            }
8821703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          }
88334f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        }
88438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        result_register.SetL(newArray);
885d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        break;
8861703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      }
8871703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::CMPL_FLOAT: {
8881703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        float val1 = shadow_frame.GetVRegFloat(dec_insn.vB);
8891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        float val2 = shadow_frame.GetVRegFloat(dec_insn.vC);
8901703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        int32_t result;
8911703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (val1 == val2) {
89234f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent          result = 0;
89389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else if (val1 > val2) {
89489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          result = 1;
89589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
896c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent          result = -1;
89789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
89834f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent        shadow_frame.SetVReg(dec_insn.vA, result);
89989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
90089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
90189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::CMPG_FLOAT: {
90289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        float val1 = shadow_frame.GetVRegFloat(dec_insn.vB);
90389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        float val2 = shadow_frame.GetVRegFloat(dec_insn.vC);
90489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int32_t result;
90589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (val1 == val2) {
90634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent          result = 0;
90789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else if (val1 < val2) {
90889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          result = -1;
90944d9848d6656777a18019223e0d35f2fcc67719aEric Laurent        } else {
9101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          result = 1;
91138ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        }
91238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        shadow_frame.SetVReg(dec_insn.vA, result);
91338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        break;
91444d9848d6656777a18019223e0d35f2fcc67719aEric Laurent      }
91544d9848d6656777a18019223e0d35f2fcc67719aEric Laurent      case Instruction::CMPL_DOUBLE: {
91689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        double val1 = shadow_frame.GetVRegDouble(dec_insn.vB);
917c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        double val2 = shadow_frame.GetVRegDouble(dec_insn.vC);
91889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int32_t result;
91989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (val1 == val2) {
92089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          result = 0;
92189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else if (val1 > val2) {
92289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          result = 1;
92389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
92489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          result = -1;
92589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
92689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        shadow_frame.SetVReg(dec_insn.vA, result);
92789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
92889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
929c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent
930c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent      case Instruction::CMPG_DOUBLE: {
931c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        double val1 = shadow_frame.GetVRegDouble(dec_insn.vB);
932c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        double val2 = shadow_frame.GetVRegDouble(dec_insn.vC);
933fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        int32_t result;
934fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        if (val1 == val2) {
935c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent          result = 0;
936c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        } else if (val1 < val2) {
937c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent          result = -1;
938c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        } else {
93989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          result = 1;
94089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
94189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        shadow_frame.SetVReg(dec_insn.vA, result);
94289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
94389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
94489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::CMP_LONG: {
9451703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        int64_t val1 = shadow_frame.GetVRegLong(dec_insn.vB);
9461703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        int64_t val2 = shadow_frame.GetVRegLong(dec_insn.vC);
94789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int32_t result;
94889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (val1 > val2) {
94989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          result = 1;
95089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else if (val1 == val2) {
95189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          result = 0;
95289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
95389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          result = -1;
95489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
95589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        shadow_frame.SetVReg(dec_insn.vA, result);
95689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
95789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
95889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::THROW: {
95989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Object* exception = shadow_frame.GetVRegReference(dec_insn.vA);
96089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (exception == NULL) {
96189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          ThrowNullPointerException(NULL, "throw with null exception");
96289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
96389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          self->SetException(shadow_frame.GetCurrentLocationForThrow(), exception->AsThrowable());
96489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
9651703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
9661703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      }
9671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::GOTO:
9681703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::GOTO_16:
9691703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::GOTO_32: {
9701703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        uint32_t dex_pc = inst->GetDexPc(insns);
9711703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        next_inst = Instruction::At(insns + dex_pc + dec_insn.vA);
97289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
97389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
97489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::PACKED_SWITCH: {
97533797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent        uint32_t dex_pc = inst->GetDexPc(insns);
97689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        const uint16_t* switch_data = insns + dex_pc + dec_insn.vB;
97789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int32_t test_val = shadow_frame.GetVReg(dec_insn.vA);
97833797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent        CHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kPackedSwitchSignature));
979c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        uint16_t size = switch_data[1];
98089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        CHECK_GT(size, 0);
98189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]);
98289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        CHECK(IsAligned<4>(keys));
98389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int32_t first_key = keys[0];
98489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        const int32_t* targets = reinterpret_cast<const int32_t*>(&switch_data[4]);
98589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        CHECK(IsAligned<4>(targets));
98689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int32_t index = test_val - first_key;
98789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (index >= 0 && index < size) {
98889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          next_inst = Instruction::At(insns + dex_pc + targets[index]);
98989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
99089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
991c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent      }
992fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin      case Instruction::SPARSE_SWITCH: {
99389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint32_t dex_pc = inst->GetDexPc(insns);
99489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        const uint16_t* switch_data = insns + dex_pc + dec_insn.vB;
99589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int32_t test_val = shadow_frame.GetVReg(dec_insn.vA);
99689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        CHECK_EQ(switch_data[0], static_cast<uint16_t>(Instruction::kSparseSwitchSignature));
99789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        uint16_t size = switch_data[1];
99889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        CHECK_GT(size, 0);
99989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        const int32_t* keys = reinterpret_cast<const int32_t*>(&switch_data[2]);
100089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        CHECK(IsAligned<4>(keys));
10013302526f6276911b2dc40c731ea7fa0e7972d908Eric Laurent        const int32_t* entries = keys + size;
100289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        CHECK(IsAligned<4>(entries));
100389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int lo = 0;
100489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int hi = size - 1;
100589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        while (lo <= hi) {
100689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          int mid = (lo + hi) / 2;
100789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          int32_t foundVal = keys[mid];
100889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          if (test_val < foundVal) {
100989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            hi = mid - 1;
101033797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent          } else if (test_val > foundVal) {
101189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            lo = mid + 1;
101289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          } else {
101389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            next_inst = Instruction::At(insns + dex_pc + entries[mid]);
101489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project            break;
101589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          }
101689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
101789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
101889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
101989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::FILL_ARRAY_DATA: {
102089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Object* obj = shadow_frame.GetVRegReference(dec_insn.vA);
102189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (UNLIKELY(obj == NULL)) {
102289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          ThrowNullPointerException(NULL, "null array in FILL_ARRAY_DATA");
10231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          break;
10241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
10251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        Array* array = obj->AsArray();
10261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        DCHECK(array->IsArrayInstance() && !array->IsObjectArray());
10271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        uint32_t dex_pc = inst->GetDexPc(insns);
10281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        const Instruction::ArrayDataPayload* payload =
10291703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent            reinterpret_cast<const Instruction::ArrayDataPayload*>(insns + dex_pc + dec_insn.vB);
10301703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (UNLIKELY(static_cast<int32_t>(payload->element_count) > array->GetLength())) {
103189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          self->ThrowNewExceptionF(shadow_frame.GetCurrentLocationForThrow(),
103238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent                                   "Ljava/lang/ArrayIndexOutOfBoundsException;",
10331703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent                                   "failed FILL_ARRAY_DATA; length=%d, index=%d",
103438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent                                   array->GetLength(), payload->element_count);
103589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          break;
10361703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
1037c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        uint32_t size_in_bytes = payload->element_count * payload->element_width;
103889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        memcpy(array->GetRawData(payload->element_width), payload->data, size_in_bytes);
103989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
104089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
104189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IF_EQ: {
1042c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        if (shadow_frame.GetVReg(dec_insn.vA) == shadow_frame.GetVReg(dec_insn.vB)) {
104389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          uint32_t dex_pc = inst->GetDexPc(insns);
10441703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
104589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
104689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
104789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
104889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IF_NE: {
104989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (shadow_frame.GetVReg(dec_insn.vA) != shadow_frame.GetVReg(dec_insn.vB)) {
105089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          uint32_t dex_pc = inst->GetDexPc(insns);
105189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
105289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
10532c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi        break;
10541703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      }
105589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IF_LT: {
10562c22aeb65e801f663a754d043062f85e49f77739Jean-Michel Trivi        if (shadow_frame.GetVReg(dec_insn.vA) < shadow_frame.GetVReg(dec_insn.vB)) {
105789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          uint32_t dex_pc = inst->GetDexPc(insns);
105889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
105989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
106089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
1061c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent      }
10621703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::IF_GE: {
106389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (shadow_frame.GetVReg(dec_insn.vA) >= shadow_frame.GetVReg(dec_insn.vB)) {
106489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          uint32_t dex_pc = inst->GetDexPc(insns);
106589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
106689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
106789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
106889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
106989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IF_GT: {
107089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (shadow_frame.GetVReg(dec_insn.vA) > shadow_frame.GetVReg(dec_insn.vB)) {
107189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          uint32_t dex_pc = inst->GetDexPc(insns);
107289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
107389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
107489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
107589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
107689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IF_LE: {
107789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (shadow_frame.GetVReg(dec_insn.vA) <= shadow_frame.GetVReg(dec_insn.vB)) {
1078c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent          uint32_t dex_pc = inst->GetDexPc(insns);
1079c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent          next_inst = Instruction::At(insns + dex_pc + dec_insn.vC);
1080c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        }
1081c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        break;
108289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
108389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IF_EQZ: {
108489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (shadow_frame.GetVReg(dec_insn.vA) == 0) {
10851dd70b9f04961a06fcb73a97fca10a53b3245d3cEric Laurent          uint32_t dex_pc = inst->GetDexPc(insns);
108689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
108789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
108889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
108989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
109089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IF_NEZ: {
109189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (shadow_frame.GetVReg(dec_insn.vA) != 0) {
109289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          uint32_t dex_pc = inst->GetDexPc(insns);
109389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
109489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
1095fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin        break;
109689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
109789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IF_LTZ: {
109889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (shadow_frame.GetVReg(dec_insn.vA) < 0) {
109989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          uint32_t dex_pc = inst->GetDexPc(insns);
110089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
110189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
110289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
110389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
11048555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project      case Instruction::IF_GEZ: {
11058555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project        if (shadow_frame.GetVReg(dec_insn.vA) >= 0) {
11068555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project          uint32_t dex_pc = inst->GetDexPc(insns);
11078555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project          next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
11088555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project        }
11098555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project        break;
11108555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project      }
11118555d0867c3e8fe6cc5c7ad40af557fe6b92fa72The Android Open Source Project      case Instruction::IF_GTZ: {
111289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (shadow_frame.GetVReg(dec_insn.vA) > 0) {
111389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          uint32_t dex_pc = inst->GetDexPc(insns);
1114fce7a473248381cc83a01855f92581077d3c9ee2Dima Zavin          next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
111589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
111689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
111789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
111889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IF_LEZ:  {
111989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (shadow_frame.GetVReg(dec_insn.vA) <= 0) {
112089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          uint32_t dex_pc = inst->GetDexPc(insns);
112189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          next_inst = Instruction::At(insns + dex_pc + dec_insn.vB);
112289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
112389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
112489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
112589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::AGET_BOOLEAN: {
1126c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
1127c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        if (UNLIKELY(a == NULL)) {
1128c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
1129c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent          break;
1130c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        }
113189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int32_t index = shadow_frame.GetVReg(dec_insn.vC);
113289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        shadow_frame.SetVReg(dec_insn.vA, a->AsBooleanArray()->Get(index));
113389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
113489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
113589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::AGET_BYTE: {
113689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
113789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (UNLIKELY(a == NULL)) {
1138d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
113989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          break;
114089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
114189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int32_t index = shadow_frame.GetVReg(dec_insn.vC);
114289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        shadow_frame.SetVReg(dec_insn.vA, a->AsByteArray()->Get(index));
114389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
114489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
11451703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::AGET_CHAR: {
11461703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
11471703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (UNLIKELY(a == NULL)) {
11481703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
11491703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          break;
11501703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
11511703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        int32_t index = shadow_frame.GetVReg(dec_insn.vC);
115238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        shadow_frame.SetVReg(dec_insn.vA, a->AsCharArray()->Get(index));
11531703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
11541703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      }
11551703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::AGET_SHORT: {
11561703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
11571703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (UNLIKELY(a == NULL)) {
11581703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
11591703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          break;
11601703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
11611703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        int32_t index = shadow_frame.GetVReg(dec_insn.vC);
11621703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        shadow_frame.SetVReg(dec_insn.vA, a->AsShortArray()->Get(index));
11631703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
11641703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      }
11651703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::AGET: {
11661703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
11671703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (UNLIKELY(a == NULL)) {
11681703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
11691703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          break;
11701703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
11711703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        int32_t index = shadow_frame.GetVReg(dec_insn.vC);
11721703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        shadow_frame.SetVReg(dec_insn.vA, a->AsIntArray()->Get(index));
11731703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
11741703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      }
11759b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent      case Instruction::AGET_WIDE:  {
11769b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent        Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
11779b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent        if (UNLIKELY(a == NULL)) {
11789b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
11799b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent          break;
11809b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent        }
11819b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent        int32_t index = shadow_frame.GetVReg(dec_insn.vC);
11829b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent        shadow_frame.SetVRegLong(dec_insn.vA, a->AsLongArray()->Get(index));
11831703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
11841703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      }
11851703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::AGET_OBJECT: {
11869b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent        Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
11879b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent        if (UNLIKELY(a == NULL)) {
11889b7d950f1f3b0c526712b713dbceb0e22762c015Eric Laurent          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
11891703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          break;
11901703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
11911703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        int32_t index = shadow_frame.GetVReg(dec_insn.vC);
11921703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        shadow_frame.SetVRegReference(dec_insn.vA, a->AsObjectArray<Object>()->Get(index));
11931703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
11941703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      }
11951703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::APUT_BOOLEAN: {
11961703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        uint8_t val = shadow_frame.GetVReg(dec_insn.vA);
11971703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
119838ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        if (UNLIKELY(a == NULL)) {
11991703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
12001703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          break;
12011703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
12021703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        int32_t index = shadow_frame.GetVReg(dec_insn.vC);
12031703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        a->AsBooleanArray()->Set(index, val);
12041703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
12051703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      }
12061703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::APUT_BYTE: {
12071703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        int8_t val = shadow_frame.GetVReg(dec_insn.vA);
12081703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
12091703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (UNLIKELY(a == NULL)) {
12101703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
12111703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          break;
12121703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
12131703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        int32_t index = shadow_frame.GetVReg(dec_insn.vC);
12141703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        a->AsByteArray()->Set(index, val);
12151703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
12161703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      }
12171703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::APUT_CHAR: {
12181703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        uint16_t val = shadow_frame.GetVReg(dec_insn.vA);
12191703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
12201703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        if (UNLIKELY(a == NULL)) {
12211703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
12221703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent          break;
12231703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        }
12241703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        int32_t index = shadow_frame.GetVReg(dec_insn.vC);
12251703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        a->AsCharArray()->Set(index, val);
12261703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
12271703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      }
12281703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::APUT_SHORT: {
12291703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        int16_t val = shadow_frame.GetVReg(dec_insn.vA);
123089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
123189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (UNLIKELY(a == NULL)) {
123289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
123389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          break;
123489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
123589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int32_t index = shadow_frame.GetVReg(dec_insn.vC);
123689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        a->AsShortArray()->Set(index, val);
123789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
123889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
123989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::APUT: {
1240d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        int32_t val = shadow_frame.GetVReg(dec_insn.vA);
124189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
1242573266210fb2b2e7d86fbd46d0dfe16763611d91Eric Laurent        if (UNLIKELY(a == NULL)) {
124389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
124489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          break;
124589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
124689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int32_t index = shadow_frame.GetVReg(dec_insn.vC);
124789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        a->AsIntArray()->Set(index, val);
124889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
124989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
125089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::APUT_WIDE: {
125189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int64_t val = shadow_frame.GetVRegLong(dec_insn.vA);
125289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
125389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (UNLIKELY(a == NULL)) {
125489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
125589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          break;
125689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
125789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int32_t index = shadow_frame.GetVReg(dec_insn.vC);
125889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        a->AsLongArray()->Set(index, val);
125989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
126089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
126189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::APUT_OBJECT: {
126289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Object* val = shadow_frame.GetVRegReference(dec_insn.vA);
126389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        Object* a = shadow_frame.GetVRegReference(dec_insn.vB);
126489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        if (UNLIKELY(a == NULL)) {
126589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          ThrowNullPointerExceptionFromDexPC(shadow_frame.GetCurrentLocationForThrow());
126689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          break;
126789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        }
126889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        int32_t index = shadow_frame.GetVReg(dec_insn.vC);
126989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        a->AsObjectArray<Object>()->Set(index, val);
127089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
127189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      }
127289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IGET_BOOLEAN:
127338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimBoolean);
127489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
127554b1a0550411c2fd2084d82d28934d505c37349aMathias Agopian      case Instruction::IGET_BYTE:
127654b1a0550411c2fd2084d82d28934d505c37349aMathias Agopian        DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimByte);
127754b1a0550411c2fd2084d82d28934d505c37349aMathias Agopian        break;
127838ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent      case Instruction::IGET_CHAR:
127989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimChar);
128089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
128189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IGET_SHORT:
128289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimShort);
128389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
128489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IGET:
128589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimInt);
128689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
128789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IGET_WIDE:
1288d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        DoFieldGet(self, shadow_frame, dec_insn, InstancePrimitiveRead, Primitive::kPrimLong);
128989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
129089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IGET_OBJECT:
129189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldGet(self, shadow_frame, dec_insn, InstanceObjectRead, Primitive::kPrimNot);
129289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
129389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::SGET_BOOLEAN:
129489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimBoolean);
129589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
129689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::SGET_BYTE:
129789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimByte);
129889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
129989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::SGET_CHAR:
130089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimChar);
130189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
130289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::SGET_SHORT:
130389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimShort);
130489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
130533797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent      case Instruction::SGET:
130638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimInt);
130733797ea64d067dfeaacbfd7ebe7f3383b73961b5Eric Laurent        break;
130889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::SGET_WIDE:
130989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldGet(self, shadow_frame, dec_insn, StaticPrimitiveRead, Primitive::kPrimLong);
131089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
131189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::SGET_OBJECT:
131289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldGet(self, shadow_frame, dec_insn, StaticObjectRead, Primitive::kPrimNot);
131389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
131438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent      case Instruction::IPUT_BOOLEAN:
131538ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimBoolean);
131689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
131789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IPUT_BYTE:
131889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimByte);
131989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
132089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IPUT_CHAR:
132189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimChar);
1322d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        break;
132389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IPUT_SHORT:
132489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimShort);
132589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
132634f1d8ecd23169a5f299937e3aaf1bd7937578a0Eric Laurent      case Instruction::IPUT:
1327c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimInt);
132889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
132989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IPUT_WIDE:
133089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldPut(self, shadow_frame, dec_insn, InstancePrimitiveWrite, Primitive::kPrimLong);
133189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
133289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::IPUT_OBJECT:
133389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldPut(self, shadow_frame, dec_insn, InstanceObjectWrite, Primitive::kPrimNot);
133489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
133589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::SPUT_BOOLEAN:
133689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimBoolean);
133789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
133889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::SPUT_BYTE:
133989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimByte);
134089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
134189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::SPUT_CHAR:
134289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimChar);
134389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
134489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::SPUT_SHORT:
134589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimShort);
134689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
134789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::SPUT:
134889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimInt);
134989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
135089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::SPUT_WIDE:
135189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoFieldPut(self, shadow_frame, dec_insn, StaticPrimitiveWrite, Primitive::kPrimLong);
13521703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        break;
13531703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent      case Instruction::SPUT_OBJECT:
13541703cdfee717b1b312bf8979816a9e2f16a82e5dEric Laurent        DoFieldPut(self, shadow_frame, dec_insn, StaticObjectWrite, Primitive::kPrimNot);
135589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
135689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::INVOKE_VIRTUAL:
135789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoInvoke(self, mh, shadow_frame, dec_insn, kVirtual, false, &result_register);
135889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
135989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::INVOKE_VIRTUAL_RANGE:
136089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoInvoke(self, mh, shadow_frame, dec_insn, kVirtual, true, &result_register);
1361c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent        break;
136289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::INVOKE_SUPER:
136389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoInvoke(self, mh, shadow_frame, dec_insn, kSuper, false, &result_register);
136489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
136589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::INVOKE_SUPER_RANGE:
136689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoInvoke(self, mh, shadow_frame, dec_insn, kSuper, true, &result_register);
136789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
136889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::INVOKE_DIRECT:
136989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoInvoke(self, mh, shadow_frame, dec_insn, kDirect, false, &result_register);
137089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
137189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::INVOKE_DIRECT_RANGE:
137289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoInvoke(self, mh, shadow_frame, dec_insn, kDirect, true, &result_register);
137389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
137489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::INVOKE_INTERFACE:
1375d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        DoInvoke(self, mh, shadow_frame, dec_insn, kInterface, false, &result_register);
137689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
137789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::INVOKE_INTERFACE_RANGE:
137889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoInvoke(self, mh, shadow_frame, dec_insn, kInterface, true, &result_register);
137989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
138089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::INVOKE_STATIC:
138189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoInvoke(self, mh, shadow_frame, dec_insn, kStatic, false, &result_register);
138289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
138389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::INVOKE_STATIC_RANGE:
138489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        DoInvoke(self, mh, shadow_frame, dec_insn, kStatic, true, &result_register);
138589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
138689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::NEG_INT:
138789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        shadow_frame.SetVReg(dec_insn.vA, -shadow_frame.GetVReg(dec_insn.vB));
1388d1b449aad6c087a69f5ec66b7facb2845b73f1cbEric Laurent        break;
138989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::NOT_INT:
139089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        shadow_frame.SetVReg(dec_insn.vA, ~shadow_frame.GetVReg(dec_insn.vB));
139189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
139238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent      case Instruction::NEG_LONG:
139338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        shadow_frame.SetVRegLong(dec_insn.vA, -shadow_frame.GetVRegLong(dec_insn.vB));
139438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        break;
139538ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent      case Instruction::NOT_LONG:
139638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        shadow_frame.SetVRegLong(dec_insn.vA, ~shadow_frame.GetVRegLong(dec_insn.vB));
139738ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        break;
139889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::NEG_FLOAT:
139938ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        shadow_frame.SetVRegFloat(dec_insn.vA, -shadow_frame.GetVRegFloat(dec_insn.vB));
140089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
140138ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent      case Instruction::NEG_DOUBLE:
140238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        shadow_frame.SetVRegDouble(dec_insn.vA, -shadow_frame.GetVRegDouble(dec_insn.vB));
140389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
140489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::INT_TO_LONG:
140589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        shadow_frame.SetVRegLong(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
140689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        break;
140789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project      case Instruction::INT_TO_FLOAT:
140889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
140938ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        break;
141038ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent      case Instruction::INT_TO_DOUBLE:
141138ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB));
141238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        break;
141338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent      case Instruction::LONG_TO_INT:
141438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
141538ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        break;
141638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent      case Instruction::LONG_TO_FLOAT:
141738ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
141838ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        break;
141938ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent      case Instruction::LONG_TO_DOUBLE:
142038ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB));
142138ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        break;
142238ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent      case Instruction::FLOAT_TO_INT: {
142338ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        float val = shadow_frame.GetVRegFloat(dec_insn.vB);
142438ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        if (val != val) {
142538ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent          shadow_frame.SetVReg(dec_insn.vA, 0);
142638ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent        } else if (val > static_cast<float>(kMaxInt)) {
142738ccae2c0324daa305f3fe77d25fdf5edec0b0e1Eric Laurent          shadow_frame.SetVReg(dec_insn.vA, kMaxInt);
142889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else if (val < static_cast<float>(kMinInt)) {
142989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          shadow_frame.SetVReg(dec_insn.vA, kMinInt);
143089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project        } else {
143189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project          shadow_frame.SetVReg(dec_insn.vA, val);
1432        }
1433        break;
1434      }
1435      case Instruction::FLOAT_TO_LONG: {
1436        float val = shadow_frame.GetVRegFloat(dec_insn.vB);
1437        if (val != val) {
1438          shadow_frame.SetVRegLong(dec_insn.vA, 0);
1439        } else if (val > static_cast<float>(kMaxLong)) {
1440          shadow_frame.SetVRegLong(dec_insn.vA, kMaxLong);
1441        } else if (val < static_cast<float>(kMinLong)) {
1442          shadow_frame.SetVRegLong(dec_insn.vA, kMinLong);
1443        } else {
1444          shadow_frame.SetVRegLong(dec_insn.vA, val);
1445        }
1446        break;
1447      }
1448      case Instruction::FLOAT_TO_DOUBLE:
1449        shadow_frame.SetVRegDouble(dec_insn.vA, shadow_frame.GetVRegFloat(dec_insn.vB));
1450        break;
1451      case Instruction::DOUBLE_TO_INT: {
1452        double val = shadow_frame.GetVRegDouble(dec_insn.vB);
1453        if (val != val) {
1454          shadow_frame.SetVReg(dec_insn.vA, 0);
1455        } else if (val > static_cast<double>(kMaxInt)) {
1456          shadow_frame.SetVReg(dec_insn.vA, kMaxInt);
1457        } else if (val < static_cast<double>(kMinInt)) {
1458          shadow_frame.SetVReg(dec_insn.vA, kMinInt);
1459        } else {
1460          shadow_frame.SetVReg(dec_insn.vA, val);
1461        }
1462        break;
1463      }
1464      case Instruction::DOUBLE_TO_LONG: {
1465        double val = shadow_frame.GetVRegDouble(dec_insn.vB);
1466        if (val != val) {
1467          shadow_frame.SetVRegLong(dec_insn.vA, 0);
1468        } else if (val > static_cast<double>(kMaxLong)) {
1469          shadow_frame.SetVRegLong(dec_insn.vA, kMaxLong);
1470        } else if (val < static_cast<double>(kMinLong)) {
1471          shadow_frame.SetVRegLong(dec_insn.vA, kMinLong);
1472        } else {
1473          shadow_frame.SetVRegLong(dec_insn.vA, val);
1474        }
1475        break;
1476      }
1477      case Instruction::DOUBLE_TO_FLOAT:
1478        shadow_frame.SetVRegFloat(dec_insn.vA, shadow_frame.GetVRegDouble(dec_insn.vB));
1479        break;
1480      case Instruction::INT_TO_BYTE:
1481        shadow_frame.SetVReg(dec_insn.vA, static_cast<int8_t>(shadow_frame.GetVReg(dec_insn.vB)));
1482        break;
1483      case Instruction::INT_TO_CHAR:
1484        shadow_frame.SetVReg(dec_insn.vA, static_cast<uint16_t>(shadow_frame.GetVReg(dec_insn.vB)));
1485        break;
1486      case Instruction::INT_TO_SHORT:
1487        shadow_frame.SetVReg(dec_insn.vA, static_cast<int16_t>(shadow_frame.GetVReg(dec_insn.vB)));
1488        break;
1489      case Instruction::ADD_INT:
1490        shadow_frame.SetVReg(dec_insn.vA,
1491                             shadow_frame.GetVReg(dec_insn.vB) + shadow_frame.GetVReg(dec_insn.vC));
1492        break;
1493      case Instruction::SUB_INT:
1494        shadow_frame.SetVReg(dec_insn.vA,
1495                             shadow_frame.GetVReg(dec_insn.vB) - shadow_frame.GetVReg(dec_insn.vC));
1496        break;
1497      case Instruction::MUL_INT:
1498        shadow_frame.SetVReg(dec_insn.vA,
1499                             shadow_frame.GetVReg(dec_insn.vB) * shadow_frame.GetVReg(dec_insn.vC));
1500        break;
1501      case Instruction::REM_INT:
1502        DoIntRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB),
1503                       shadow_frame.GetVReg(dec_insn.vC));
1504        break;
1505      case Instruction::DIV_INT:
1506        DoIntDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB),
1507                    shadow_frame.GetVReg(dec_insn.vC));
1508        break;
1509      case Instruction::SHL_INT:
1510        shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) <<
1511                             (shadow_frame.GetVReg(dec_insn.vC) & 0x1f));
1512        break;
1513      case Instruction::SHR_INT:
1514        shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) >>
1515                             (shadow_frame.GetVReg(dec_insn.vC) & 0x1f));
1516        break;
1517      case Instruction::USHR_INT:
1518        shadow_frame.SetVReg(dec_insn.vA,
1519                             static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vB)) >>
1520                             (shadow_frame.GetVReg(dec_insn.vC) & 0x1f));
1521        break;
1522      case Instruction::AND_INT:
1523        shadow_frame.SetVReg(dec_insn.vA,
1524                             shadow_frame.GetVReg(dec_insn.vB) & shadow_frame.GetVReg(dec_insn.vC));
1525        break;
1526      case Instruction::OR_INT:
1527        shadow_frame.SetVReg(dec_insn.vA,
1528                             shadow_frame.GetVReg(dec_insn.vB) | shadow_frame.GetVReg(dec_insn.vC));
1529        break;
1530      case Instruction::XOR_INT:
1531        shadow_frame.SetVReg(dec_insn.vA,
1532                             shadow_frame.GetVReg(dec_insn.vB) ^ shadow_frame.GetVReg(dec_insn.vC));
1533        break;
1534      case Instruction::ADD_LONG:
1535        shadow_frame.SetVRegLong(dec_insn.vA,
1536                                 shadow_frame.GetVRegLong(dec_insn.vB) +
1537                                 shadow_frame.GetVRegLong(dec_insn.vC));
1538        break;
1539      case Instruction::SUB_LONG:
1540        shadow_frame.SetVRegLong(dec_insn.vA,
1541                                 shadow_frame.GetVRegLong(dec_insn.vB) -
1542                                 shadow_frame.GetVRegLong(dec_insn.vC));
1543        break;
1544      case Instruction::MUL_LONG:
1545        shadow_frame.SetVRegLong(dec_insn.vA,
1546                                 shadow_frame.GetVRegLong(dec_insn.vB) *
1547                                 shadow_frame.GetVRegLong(dec_insn.vC));
1548        break;
1549      case Instruction::DIV_LONG:
1550        DoLongDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB),
1551                    shadow_frame.GetVRegLong(dec_insn.vC));
1552        break;
1553      case Instruction::REM_LONG:
1554        DoLongRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vB),
1555                        shadow_frame.GetVRegLong(dec_insn.vC));
1556        break;
1557      case Instruction::AND_LONG:
1558        shadow_frame.SetVRegLong(dec_insn.vA,
1559                                 shadow_frame.GetVRegLong(dec_insn.vB) &
1560                                 shadow_frame.GetVRegLong(dec_insn.vC));
1561        break;
1562      case Instruction::OR_LONG:
1563        shadow_frame.SetVRegLong(dec_insn.vA,
1564                                 shadow_frame.GetVRegLong(dec_insn.vB) |
1565                                 shadow_frame.GetVRegLong(dec_insn.vC));
1566        break;
1567      case Instruction::XOR_LONG:
1568        shadow_frame.SetVRegLong(dec_insn.vA,
1569                                 shadow_frame.GetVRegLong(dec_insn.vB) ^
1570                                 shadow_frame.GetVRegLong(dec_insn.vC));
1571        break;
1572      case Instruction::SHL_LONG:
1573        shadow_frame.SetVRegLong(dec_insn.vA,
1574                                 shadow_frame.GetVRegLong(dec_insn.vB) <<
1575                                 (shadow_frame.GetVReg(dec_insn.vC) & 0x3f));
1576        break;
1577      case Instruction::SHR_LONG:
1578        shadow_frame.SetVRegLong(dec_insn.vA,
1579                                 shadow_frame.GetVRegLong(dec_insn.vB) >>
1580                                 (shadow_frame.GetVReg(dec_insn.vC) & 0x3f));
1581        break;
1582      case Instruction::USHR_LONG:
1583        shadow_frame.SetVRegLong(dec_insn.vA,
1584                                 static_cast<uint64_t>(shadow_frame.GetVRegLong(dec_insn.vB)) >>
1585                                 (shadow_frame.GetVReg(dec_insn.vC) & 0x3f));
1586        break;
1587      case Instruction::ADD_FLOAT:
1588        shadow_frame.SetVRegFloat(dec_insn.vA,
1589                                  shadow_frame.GetVRegFloat(dec_insn.vB) +
1590                                  shadow_frame.GetVRegFloat(dec_insn.vC));
1591        break;
1592      case Instruction::SUB_FLOAT:
1593        shadow_frame.SetVRegFloat(dec_insn.vA,
1594                                  shadow_frame.GetVRegFloat(dec_insn.vB) -
1595                                  shadow_frame.GetVRegFloat(dec_insn.vC));
1596        break;
1597      case Instruction::MUL_FLOAT:
1598        shadow_frame.SetVRegFloat(dec_insn.vA,
1599                                  shadow_frame.GetVRegFloat(dec_insn.vB) *
1600                                  shadow_frame.GetVRegFloat(dec_insn.vC));
1601        break;
1602      case Instruction::DIV_FLOAT:
1603        shadow_frame.SetVRegFloat(dec_insn.vA,
1604                                  shadow_frame.GetVRegFloat(dec_insn.vB) /
1605                                  shadow_frame.GetVRegFloat(dec_insn.vC));
1606        break;
1607      case Instruction::REM_FLOAT:
1608        shadow_frame.SetVRegFloat(dec_insn.vA,
1609                                  fmodf(shadow_frame.GetVRegFloat(dec_insn.vB),
1610                                        shadow_frame.GetVRegFloat(dec_insn.vC)));
1611        break;
1612      case Instruction::ADD_DOUBLE:
1613        shadow_frame.SetVRegDouble(dec_insn.vA,
1614                                   shadow_frame.GetVRegDouble(dec_insn.vB) +
1615                                   shadow_frame.GetVRegDouble(dec_insn.vC));
1616        break;
1617      case Instruction::SUB_DOUBLE:
1618        shadow_frame.SetVRegDouble(dec_insn.vA,
1619                                   shadow_frame.GetVRegDouble(dec_insn.vB) -
1620                                   shadow_frame.GetVRegDouble(dec_insn.vC));
1621        break;
1622      case Instruction::MUL_DOUBLE:
1623        shadow_frame.SetVRegDouble(dec_insn.vA,
1624                                   shadow_frame.GetVRegDouble(dec_insn.vB) *
1625                                   shadow_frame.GetVRegDouble(dec_insn.vC));
1626        break;
1627      case Instruction::DIV_DOUBLE:
1628        shadow_frame.SetVRegDouble(dec_insn.vA,
1629                                   shadow_frame.GetVRegDouble(dec_insn.vB) /
1630                                   shadow_frame.GetVRegDouble(dec_insn.vC));
1631        break;
1632      case Instruction::REM_DOUBLE:
1633        shadow_frame.SetVRegDouble(dec_insn.vA,
1634                                   fmod(shadow_frame.GetVRegDouble(dec_insn.vB),
1635                                        shadow_frame.GetVRegDouble(dec_insn.vC)));
1636        break;
1637      case Instruction::ADD_INT_2ADDR:
1638        shadow_frame.SetVReg(dec_insn.vA,
1639                             shadow_frame.GetVReg(dec_insn.vA) + shadow_frame.GetVReg(dec_insn.vB));
1640        break;
1641      case Instruction::SUB_INT_2ADDR:
1642        shadow_frame.SetVReg(dec_insn.vA,
1643                             shadow_frame.GetVReg(dec_insn.vA) - shadow_frame.GetVReg(dec_insn.vB));
1644        break;
1645      case Instruction::MUL_INT_2ADDR:
1646        shadow_frame.SetVReg(dec_insn.vA,
1647                             shadow_frame.GetVReg(dec_insn.vA) * shadow_frame.GetVReg(dec_insn.vB));
1648        break;
1649      case Instruction::REM_INT_2ADDR:
1650        DoIntRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA),
1651                       shadow_frame.GetVReg(dec_insn.vB));
1652        break;
1653      case Instruction::SHL_INT_2ADDR:
1654        shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA) <<
1655                             (shadow_frame.GetVReg(dec_insn.vB) & 0x1f));
1656        break;
1657      case Instruction::SHR_INT_2ADDR:
1658        shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA) >>
1659                             (shadow_frame.GetVReg(dec_insn.vB) & 0x1f));
1660        break;
1661      case Instruction::USHR_INT_2ADDR:
1662        shadow_frame.SetVReg(dec_insn.vA,
1663                             static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vA)) >>
1664                             (shadow_frame.GetVReg(dec_insn.vB) & 0x1f));
1665        break;
1666      case Instruction::AND_INT_2ADDR:
1667        shadow_frame.SetVReg(dec_insn.vA,
1668                             shadow_frame.GetVReg(dec_insn.vA) & shadow_frame.GetVReg(dec_insn.vB));
1669        break;
1670      case Instruction::OR_INT_2ADDR:
1671        shadow_frame.SetVReg(dec_insn.vA,
1672                             shadow_frame.GetVReg(dec_insn.vA) | shadow_frame.GetVReg(dec_insn.vB));
1673        break;
1674      case Instruction::XOR_INT_2ADDR:
1675        shadow_frame.SetVReg(dec_insn.vA,
1676                             shadow_frame.GetVReg(dec_insn.vA) ^ shadow_frame.GetVReg(dec_insn.vB));
1677        break;
1678      case Instruction::DIV_INT_2ADDR:
1679        DoIntDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vA),
1680                    shadow_frame.GetVReg(dec_insn.vB));
1681        break;
1682      case Instruction::ADD_LONG_2ADDR:
1683        shadow_frame.SetVRegLong(dec_insn.vA,
1684                                 shadow_frame.GetVRegLong(dec_insn.vA) +
1685                                 shadow_frame.GetVRegLong(dec_insn.vB));
1686        break;
1687      case Instruction::SUB_LONG_2ADDR:
1688        shadow_frame.SetVRegLong(dec_insn.vA,
1689                                 shadow_frame.GetVRegLong(dec_insn.vA) -
1690                                 shadow_frame.GetVRegLong(dec_insn.vB));
1691        break;
1692      case Instruction::MUL_LONG_2ADDR:
1693        shadow_frame.SetVRegLong(dec_insn.vA,
1694                                 shadow_frame.GetVRegLong(dec_insn.vA) *
1695                                 shadow_frame.GetVRegLong(dec_insn.vB));
1696        break;
1697      case Instruction::DIV_LONG_2ADDR:
1698        DoLongDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vA),
1699                    shadow_frame.GetVRegLong(dec_insn.vB));
1700        break;
1701      case Instruction::REM_LONG_2ADDR:
1702        DoLongRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVRegLong(dec_insn.vA),
1703                        shadow_frame.GetVRegLong(dec_insn.vB));
1704        break;
1705      case Instruction::AND_LONG_2ADDR:
1706        shadow_frame.SetVRegLong(dec_insn.vA,
1707                                 shadow_frame.GetVRegLong(dec_insn.vA) &
1708                                 shadow_frame.GetVRegLong(dec_insn.vB));
1709        break;
1710      case Instruction::OR_LONG_2ADDR:
1711        shadow_frame.SetVRegLong(dec_insn.vA,
1712                                 shadow_frame.GetVRegLong(dec_insn.vA) |
1713                                 shadow_frame.GetVRegLong(dec_insn.vB));
1714        break;
1715      case Instruction::XOR_LONG_2ADDR:
1716        shadow_frame.SetVRegLong(dec_insn.vA,
1717                                 shadow_frame.GetVRegLong(dec_insn.vA) ^
1718                                 shadow_frame.GetVRegLong(dec_insn.vB));
1719        break;
1720      case Instruction::SHL_LONG_2ADDR:
1721        shadow_frame.SetVRegLong(dec_insn.vA,
1722                                 shadow_frame.GetVRegLong(dec_insn.vA) <<
1723                                 (shadow_frame.GetVReg(dec_insn.vB) & 0x3f));
1724        break;
1725      case Instruction::SHR_LONG_2ADDR:
1726        shadow_frame.SetVRegLong(dec_insn.vA,
1727                                 shadow_frame.GetVRegLong(dec_insn.vA) >>
1728                                 (shadow_frame.GetVReg(dec_insn.vB) & 0x3f));
1729        break;
1730      case Instruction::USHR_LONG_2ADDR:
1731        shadow_frame.SetVRegLong(dec_insn.vA,
1732                                 static_cast<uint64_t>(shadow_frame.GetVRegLong(dec_insn.vA)) >>
1733                                 (shadow_frame.GetVReg(dec_insn.vB) & 0x3f));
1734        break;
1735      case Instruction::ADD_FLOAT_2ADDR:
1736        shadow_frame.SetVRegFloat(dec_insn.vA,
1737                                  shadow_frame.GetVRegFloat(dec_insn.vA) +
1738                                  shadow_frame.GetVRegFloat(dec_insn.vB));
1739        break;
1740      case Instruction::SUB_FLOAT_2ADDR:
1741        shadow_frame.SetVRegFloat(dec_insn.vA,
1742                                  shadow_frame.GetVRegFloat(dec_insn.vA) -
1743                                  shadow_frame.GetVRegFloat(dec_insn.vB));
1744        break;
1745      case Instruction::MUL_FLOAT_2ADDR:
1746        shadow_frame.SetVRegFloat(dec_insn.vA,
1747                                  shadow_frame.GetVRegFloat(dec_insn.vA) *
1748                                  shadow_frame.GetVRegFloat(dec_insn.vB));
1749        break;
1750      case Instruction::DIV_FLOAT_2ADDR:
1751        shadow_frame.SetVRegFloat(dec_insn.vA,
1752                                  shadow_frame.GetVRegFloat(dec_insn.vA) /
1753                                  shadow_frame.GetVRegFloat(dec_insn.vB));
1754        break;
1755      case Instruction::REM_FLOAT_2ADDR:
1756        shadow_frame.SetVRegFloat(dec_insn.vA,
1757                                  fmodf(shadow_frame.GetVRegFloat(dec_insn.vA),
1758                                        shadow_frame.GetVRegFloat(dec_insn.vB)));
1759        break;
1760      case Instruction::ADD_DOUBLE_2ADDR:
1761        shadow_frame.SetVRegDouble(dec_insn.vA,
1762                                   shadow_frame.GetVRegDouble(dec_insn.vA) +
1763                                   shadow_frame.GetVRegDouble(dec_insn.vB));
1764        break;
1765      case Instruction::SUB_DOUBLE_2ADDR:
1766        shadow_frame.SetVRegDouble(dec_insn.vA,
1767                                   shadow_frame.GetVRegDouble(dec_insn.vA) -
1768                                   shadow_frame.GetVRegDouble(dec_insn.vB));
1769        break;
1770      case Instruction::MUL_DOUBLE_2ADDR:
1771        shadow_frame.SetVRegDouble(dec_insn.vA,
1772                                   shadow_frame.GetVRegDouble(dec_insn.vA) *
1773                                   shadow_frame.GetVRegDouble(dec_insn.vB));
1774        break;
1775      case Instruction::DIV_DOUBLE_2ADDR:
1776        shadow_frame.SetVRegDouble(dec_insn.vA,
1777                                   shadow_frame.GetVRegDouble(dec_insn.vA) /
1778                                   shadow_frame.GetVRegDouble(dec_insn.vB));
1779        break;
1780      case Instruction::REM_DOUBLE_2ADDR:
1781        shadow_frame.SetVRegDouble(dec_insn.vA,
1782                                   fmod(shadow_frame.GetVRegDouble(dec_insn.vA),
1783                                        shadow_frame.GetVRegDouble(dec_insn.vB)));
1784        break;
1785      case Instruction::ADD_INT_LIT16:
1786      case Instruction::ADD_INT_LIT8:
1787        shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) + dec_insn.vC);
1788        break;
1789      case Instruction::RSUB_INT:
1790      case Instruction::RSUB_INT_LIT8:
1791        shadow_frame.SetVReg(dec_insn.vA, dec_insn.vC - shadow_frame.GetVReg(dec_insn.vB));
1792        break;
1793      case Instruction::MUL_INT_LIT16:
1794      case Instruction::MUL_INT_LIT8:
1795        shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) * dec_insn.vC);
1796        break;
1797      case Instruction::DIV_INT_LIT16:
1798      case Instruction::DIV_INT_LIT8:
1799        DoIntDivide(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB),
1800                    dec_insn.vC);
1801        break;
1802      case Instruction::REM_INT_LIT16:
1803      case Instruction::REM_INT_LIT8:
1804        DoIntRemainder(self, shadow_frame, dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB),
1805                       dec_insn.vC);
1806        break;
1807      case Instruction::AND_INT_LIT16:
1808      case Instruction::AND_INT_LIT8:
1809        shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) & dec_insn.vC);
1810        break;
1811      case Instruction::OR_INT_LIT16:
1812      case Instruction::OR_INT_LIT8:
1813        shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) | dec_insn.vC);
1814        break;
1815      case Instruction::XOR_INT_LIT16:
1816      case Instruction::XOR_INT_LIT8:
1817        shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) ^ dec_insn.vC);
1818        break;
1819      case Instruction::SHL_INT_LIT8:
1820        shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) <<
1821                             (dec_insn.vC & 0x1f));
1822        break;
1823      case Instruction::SHR_INT_LIT8:
1824        shadow_frame.SetVReg(dec_insn.vA, shadow_frame.GetVReg(dec_insn.vB) >>
1825                             (dec_insn.vC & 0x1f));
1826        break;
1827      case Instruction::USHR_INT_LIT8:
1828        shadow_frame.SetVReg(dec_insn.vA,
1829                             static_cast<uint32_t>(shadow_frame.GetVReg(dec_insn.vB)) >>
1830                             (dec_insn.vC & 0x1f));
1831        break;
1832      default:
1833        LOG(FATAL) << "Unexpected instruction: " << inst->DumpString(&mh.GetDexFile());
1834        break;
1835    }
1836    if (UNLIKELY(self->IsExceptionPending())) {
1837      self->VerifyStack();
1838      ThrowLocation throw_location;
1839      mirror::Throwable* exception = self->GetException(&throw_location);
1840      uint32_t found_dex_pc =
1841          shadow_frame.GetMethod()->FindCatchBlock(exception->GetClass(), inst->GetDexPc(insns));
1842      if (found_dex_pc == DexFile::kDexNoIndex) {
1843        JValue result;
1844        result.SetJ(0);
1845        instrumentation->MethodUnwindEvent(self, shadow_frame.GetThisObject(),
1846                                           shadow_frame.GetMethod(), shadow_frame.GetDexPC());
1847        return result;  // Handler in caller.
1848      } else {
1849        Runtime::Current()->GetInstrumentation()->ExceptionCaughtEvent(self, throw_location,
1850                                                                       shadow_frame.GetMethod(),
1851                                                                       found_dex_pc, exception);
1852        next_inst = Instruction::At(insns + found_dex_pc);
1853      }
1854    }
1855    inst = next_inst;
1856  }
1857}
1858
1859void EnterInterpreterFromInvoke(Thread* self, AbstractMethod* method, Object* receiver,
1860                                uint32_t* args, JValue* result) {
1861  DCHECK_EQ(self, Thread::Current());
1862  if (__builtin_frame_address(0) < self->GetStackEnd()) {
1863    ThrowStackOverflowError(self);
1864    return;
1865  }
1866
1867  MethodHelper mh(method);
1868  const DexFile::CodeItem* code_item = mh.GetCodeItem();
1869  uint16_t num_regs;
1870  uint16_t num_ins;
1871  if (code_item != NULL) {
1872    num_regs =  code_item->registers_size_;
1873    num_ins = code_item->ins_size_;
1874  } else if (method->IsAbstract()) {
1875    ThrowLocation throw_location = self->GetCurrentLocationForThrow();
1876    self->ThrowNewExceptionF(throw_location, "Ljava/lang/AbstractMethodError;",
1877                             "abstract method \"%s\"", PrettyMethod(method).c_str());
1878    return;
1879  } else {
1880    DCHECK(method->IsNative());
1881    num_regs = num_ins = AbstractMethod::NumArgRegisters(mh.GetShorty());
1882    if (!method->IsStatic()) {
1883      num_regs++;
1884      num_ins++;
1885    }
1886  }
1887  // Set up shadow frame with matching number of reference slots to vregs.
1888  ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame();
1889  UniquePtr<ShadowFrame> shadow_frame(ShadowFrame::Create(num_regs,
1890                                                          last_shadow_frame,
1891                                                          method, 0));
1892  self->PushShadowFrame(shadow_frame.get());
1893  size_t cur_reg = num_regs - num_ins;
1894  if (!method->IsStatic()) {
1895    CHECK(receiver != NULL);
1896    shadow_frame->SetVRegReference(cur_reg, receiver);
1897    ++cur_reg;
1898  } else if (!method->GetDeclaringClass()->IsInitializing()) {
1899    if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(),
1900                                                                 true, true)) {
1901      DCHECK(Thread::Current()->IsExceptionPending());
1902      return;
1903    }
1904    CHECK(method->GetDeclaringClass()->IsInitializing());
1905  }
1906  const char* shorty = mh.GetShorty();
1907  for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) {
1908    DCHECK_LT(shorty_pos + 1, mh.GetShortyLength());
1909    switch (shorty[shorty_pos + 1]) {
1910      case 'L': {
1911        Object* o = reinterpret_cast<Object*>(args[arg_pos]);
1912        shadow_frame->SetVRegReference(cur_reg, o);
1913        break;
1914      }
1915      case 'J': case 'D': {
1916        uint64_t wide_value = (static_cast<uint64_t>(args[arg_pos + 1]) << 32) | args[arg_pos];
1917        shadow_frame->SetVRegLong(cur_reg, wide_value);
1918        cur_reg++;
1919        arg_pos++;
1920        break;
1921      }
1922      default:
1923        shadow_frame->SetVReg(cur_reg, args[arg_pos]);
1924        break;
1925    }
1926  }
1927  if (LIKELY(!method->IsNative())) {
1928    JValue r = Execute(self, mh, code_item, *shadow_frame.get(), JValue());
1929    if (result != NULL) {
1930      *result = r;
1931    }
1932  } else {
1933    // We don't expect to be asked to interpret native code (which is entered via a JNI compiler
1934    // generated stub) except during testing and image writing.
1935    if (!Runtime::Current()->IsStarted()) {
1936      UnstartedRuntimeJni(self, method, receiver, args, result);
1937    } else {
1938      InterpreterJni(self, method, shorty, receiver, args, result);
1939    }
1940  }
1941  self->PopShadowFrame();
1942}
1943
1944void EnterInterpreterFromDeoptimize(Thread* self, ShadowFrame* shadow_frame, JValue* ret_val)
1945    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1946  JValue value;
1947  value.SetJ(ret_val->GetJ());  // Set value to last known result in case the shadow frame chain is empty.
1948  MethodHelper mh;
1949  while (shadow_frame != NULL) {
1950    self->SetTopOfShadowStack(shadow_frame);
1951    mh.ChangeMethod(shadow_frame->GetMethod());
1952    const DexFile::CodeItem* code_item = mh.GetCodeItem();
1953    value = Execute(self, mh, code_item, *shadow_frame, value);
1954    ShadowFrame* old_frame = shadow_frame;
1955    shadow_frame = shadow_frame->GetLink();
1956    delete old_frame;
1957  }
1958  ret_val->SetJ(value.GetJ());
1959}
1960
1961JValue EnterInterpreterFromStub(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item,
1962                                ShadowFrame& shadow_frame)
1963    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1964  DCHECK_EQ(self, Thread::Current());
1965  if (__builtin_frame_address(0) < self->GetStackEnd()) {
1966    ThrowStackOverflowError(self);
1967    return JValue();
1968  }
1969
1970  return Execute(self, mh, code_item, shadow_frame, JValue());
1971}
1972
1973JValue EnterInterpreterFromInterpreter(Thread* self, ShadowFrame* shadow_frame)
1974    SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
1975  if (__builtin_frame_address(0) < self->GetStackEnd()) {
1976    ThrowStackOverflowError(self);
1977    return JValue();
1978  }
1979
1980  AbstractMethod* method = shadow_frame->GetMethod();
1981  if (method->IsStatic() && !method->GetDeclaringClass()->IsInitializing()) {
1982    if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(method->GetDeclaringClass(),
1983                                                                 true, true)) {
1984      DCHECK(Thread::Current()->IsExceptionPending());
1985      return JValue();
1986    }
1987    CHECK(method->GetDeclaringClass()->IsInitializing());
1988  }
1989
1990  self->PushShadowFrame(shadow_frame);
1991
1992  MethodHelper mh(method);
1993  const DexFile::CodeItem* code_item = mh.GetCodeItem();
1994  JValue result;
1995  if (LIKELY(!method->IsNative())) {
1996    result = Execute(self, mh, code_item, *shadow_frame, JValue());
1997  } else {
1998    // We don't expect to be asked to interpret native code (which is entered via a JNI compiler
1999    // generated stub) except during testing and image writing.
2000    CHECK(!Runtime::Current()->IsStarted());
2001    Object* receiver = method->IsStatic() ? NULL : shadow_frame->GetVRegReference(0);
2002    uint32_t* args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1);
2003    UnstartedRuntimeJni(self, method, receiver, args, &result);
2004  }
2005
2006  self->PopShadowFrame();
2007  return result;
2008}
2009
2010}  // namespace interpreter
2011}  // namespace art
2012