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