interpreter.cc revision d2fe10a3a34af171bf1631219cd2d6ff6b7778b5
12fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers/* 22fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * Copyright (C) 2012 The Android Open Source Project 32fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * 42fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * Licensed under the Apache License, Version 2.0 (the "License"); 52fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * you may not use this file except in compliance with the License. 62fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * You may obtain a copy of the License at 72fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * 82fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * http://www.apache.org/licenses/LICENSE-2.0 92fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * 102fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * Unless required by applicable law or agreed to in writing, software 112fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * distributed under the License is distributed on an "AS IS" BASIS, 122fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 132fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * See the License for the specific language governing permissions and 142fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers * limitations under the License. 152fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers */ 162fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 178ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz#include "interpreter_common.h" 18d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz#include <limits> 192dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 202fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogersnamespace art { 212fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogersnamespace interpreter { 222fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 2364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers// Hand select a number of methods to be run in a not yet started runtime without using JNI. 24ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromstatic void UnstartedRuntimeJni(Thread* self, ArtMethod* method, 255d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* receiver, uint32_t* args, JValue* result) 2664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 27d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz DCHECK(Runtime::Current()->IsActiveTransaction()) << "Calling native method " 28d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz << PrettyMethod(method) 29d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz << " in unstarted runtime should only happen" 30d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz << " in a transaction"; 3164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers std::string name(PrettyMethod(method)); 3264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (name == "java.lang.ClassLoader dalvik.system.VMStack.getCallingClassLoader()") { 3364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(NULL); 3464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.Class dalvik.system.VMStack.getStackClass2()") { 357a22fa657b972e8323692368975bc5a7be1cc0f5Ian Rogers NthCallerVisitor visitor(self, 3); 3664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers visitor.WalkStack(); 3764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(visitor.caller->GetDeclaringClass()); 3864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "double java.lang.Math.log(double)") { 395d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao JValue value; 405d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]); 415d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetD(log(value.GetD())); 4264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.String java.lang.Class.getNameNative()") { 4364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(receiver->AsClass()->ComputeName()); 4464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "int java.lang.Float.floatToRawIntBits(float)") { 455d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(args[0]); 4664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "float java.lang.Float.intBitsToFloat(int)") { 475d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(args[0]); 4864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "double java.lang.Math.exp(double)") { 495d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao JValue value; 505d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]); 515d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetD(exp(value.GetD())); 5264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.Object java.lang.Object.internalClone()") { 5364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(receiver->Clone(self)); 5464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "void java.lang.Object.notifyAll()") { 5505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers receiver->NotifyAll(self); 5664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "int java.lang.String.compareTo(java.lang.String)") { 575d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao String* rhs = reinterpret_cast<Object*>(args[0])->AsString(); 5864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers CHECK(rhs != NULL); 5964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetI(receiver->AsString()->CompareTo(rhs)); 6064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.String java.lang.String.intern()") { 6164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(receiver->AsString()->Intern()); 6264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "int java.lang.String.fastIndexOf(int, int)") { 635d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(receiver->AsString()->FastIndexOf(args[0], args[1])); 6464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.Object java.lang.reflect.Array.createMultiArray(java.lang.Class, int[])") { 655bb99037bef70784ae4630c2e4b81688d2a18621Mathieu Chartier SirtRef<mirror::Class> sirt_class(self, reinterpret_cast<Object*>(args[0])->AsClass()); 665bb99037bef70784ae4630c2e4b81688d2a18621Mathieu Chartier SirtRef<mirror::IntArray> sirt_dimensions(self, 675bb99037bef70784ae4630c2e4b81688d2a18621Mathieu Chartier reinterpret_cast<Object*>(args[1])->AsIntArray()); 685bb99037bef70784ae4630c2e4b81688d2a18621Mathieu Chartier result->SetL(Array::CreateMultiArray(self, sirt_class, sirt_dimensions)); 6964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.Object java.lang.Throwable.nativeFillInStackTrace()") { 7064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedObjectAccessUnchecked soa(self); 7164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(soa.Decode<Object*>(self->CreateInternalStackTrace(soa))); 7264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "boolean java.nio.ByteOrder.isLittleEndian()") { 7364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetJ(JNI_TRUE); 7464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)") { 755d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* obj = reinterpret_cast<Object*>(args[0]); 765d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1]; 775d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao jint expectedValue = args[3]; 785d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao jint newValue = args[4]; 7964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers byte* raw_addr = reinterpret_cast<byte*>(obj) + offset; 8064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers volatile int32_t* address = reinterpret_cast<volatile int32_t*>(raw_addr); 81d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Check offset is 32bits to fit in MemberOffset. 82d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz CHECK_GE(offset, static_cast<jlong>(std::numeric_limits<int32_t>::min())); 83d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz CHECK_LE(offset, static_cast<jlong>(std::numeric_limits<int32_t>::max())); 84d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz Runtime::Current()->RecordWriteField32(obj, MemberOffset(offset), *address, true); 8564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // Note: android_atomic_release_cas() returns 0 on success, not failure. 8664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers int r = android_atomic_release_cas(expectedValue, newValue, address); 8764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetZ(r == 0); 8864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)") { 895d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* obj = reinterpret_cast<Object*>(args[0]); 905d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* newValue = reinterpret_cast<Object*>(args[3]); 91d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz obj->SetFieldObject<true>(MemberOffset((static_cast<uint64_t>(args[2]) << 32) | args[1]), 92d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz newValue, false); 934d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi } else if (name == "int sun.misc.Unsafe.getArrayBaseOffsetForComponentType(java.lang.Class)") { 944d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi mirror::Class* component = reinterpret_cast<Object*>(args[0])->AsClass(); 954d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi Primitive::Type primitive_type = component->GetPrimitiveType(); 964d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value()); 974d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi } else if (name == "int sun.misc.Unsafe.getArrayIndexScaleForComponentType(java.lang.Class)") { 984d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi mirror::Class* component = reinterpret_cast<Object*>(args[0])->AsClass(); 994d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi Primitive::Type primitive_type = component->GetPrimitiveType(); 1004d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi result->SetI(Primitive::ComponentSize(primitive_type)); 10164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 102d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz // Throw an exception so we can abort the transaction and undo every change. 103d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz ThrowLocation throw_location; 104d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz self->ThrowNewExceptionF(throw_location, "Ljava/lang/InternalError;", 105d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz "Attempt to invoke native method in non-started runtime: %s", 106d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz name.c_str()); 10764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 10864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers} 10964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 110fc0e94bed3f88ed7e50854fd8dfaf5dcb345250fIan Rogersstatic void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& shorty, 1115d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* receiver, uint32_t* args, JValue* result) 11264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 11364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler, 11464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // it should be removed and JNI compiled stubs used instead. 11564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedObjectAccessUnchecked soa(self); 11664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (method->IsStatic()) { 11764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (shorty == "L") { 118460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jclass); 119460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 12064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 12164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 122556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 123556d637764b71563030c479bc35364a75188d559Ian Rogers { 124556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 125556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), klass.get()); 126556d637764b71563030c479bc35364a75188d559Ian Rogers } 127556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 12864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "V") { 129460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass); 130460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 13164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 13264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 13364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 13464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers fn(soa.Env(), klass.get()); 13564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "Z") { 136460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass); 137460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 13864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 13964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 14064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 14164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetZ(fn(soa.Env(), klass.get())); 14264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "BI") { 143460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jbyte (fntype)(JNIEnv*, jclass, jint); 144460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 14564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 14664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 14764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1485d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetB(fn(soa.Env(), klass.get(), args[0])); 14964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "II") { 150460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jint); 151460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 15264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 15364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 15464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1555d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), args[0])); 15664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "LL") { 157460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jclass, jobject); 158460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 15964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 16064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 16164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 1625d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 163556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 164556d637764b71563030c479bc35364a75188d559Ian Rogers { 165556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 166556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), klass.get(), arg0.get()); 167556d637764b71563030c479bc35364a75188d559Ian Rogers } 168556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 16964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "IIZ") { 170460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jint, jboolean); 171460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 17264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 17364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 17464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1755d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), args[0], args[1])); 17664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ILI") { 177460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jobject, jint); 178460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 17964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 18064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 18164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 1825d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 18364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1845d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1])); 18564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "SIZ") { 186460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jshort (fntype)(JNIEnv*, jclass, jint, jboolean); 187460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 18864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 18964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 19064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1915d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetS(fn(soa.Env(), klass.get(), args[0], args[1])); 19264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VIZ") { 193460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jint, jboolean); 194460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 19564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 19664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 19764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1985d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), args[0], args[1]); 19964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ZLL") { 200460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass, jobject, jobject); 201460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 20264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 20364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 20464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 2055d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 20664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 2075d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 20864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 20964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get())); 21064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ZILL") { 211460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass, jint, jobject, jobject); 212460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 21364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 21464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 21564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 2165d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 21764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg2(soa.Env(), 2185d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[2]))); 21964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2205d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetZ(fn(soa.Env(), klass.get(), args[0], arg1.get(), arg2.get())); 22164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VILII") { 222460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jint, jobject, jint, jint); 223460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 22464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 22564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 22664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 2275d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 22864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2295d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), args[0], arg1.get(), args[2], args[3]); 23064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VLILII") { 231460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint); 232460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 23364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 23464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 23564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 2365d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 23764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg2(soa.Env(), 2385d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[2]))); 23964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2405d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), arg0.get(), args[1], arg2.get(), args[3], args[4]); 24164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 24264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers LOG(FATAL) << "Do something with static native method: " << PrettyMethod(method) 24364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers << " shorty: " << shorty; 24464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 24564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 24664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (shorty == "L") { 247460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jobject); 248460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 24964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 25064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 251556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 252556d637764b71563030c479bc35364a75188d559Ian Rogers { 253556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 254556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), rcvr.get()); 255556d637764b71563030c479bc35364a75188d559Ian Rogers } 256556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 2573dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao } else if (shorty == "V") { 258460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jobject); 259460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 2603dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao ScopedLocalRef<jobject> rcvr(soa.Env(), 2613dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao soa.AddLocalReference<jobject>(receiver)); 2623dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao ScopedThreadStateChange tsc(self, kNative); 2633dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao fn(soa.Env(), rcvr.get()); 26464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "LL") { 265460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jobject, jobject); 266460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 26764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 26864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 26964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 2705d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 271556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 272556d637764b71563030c479bc35364a75188d559Ian Rogers { 273556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 274556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), rcvr.get(), arg0.get()); 275556d637764b71563030c479bc35364a75188d559Ian Rogers } 276556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 27764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 27864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "III") { 279460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jobject, jint, jint); 280460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetNativeMethod())); 28164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 28264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 28364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2845d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), rcvr.get(), args[0], args[1])); 28564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 28664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers LOG(FATAL) << "Do something with native method: " << PrettyMethod(method) 28764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers << " shorty: " << shorty; 28864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 28964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 29064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers} 29164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 2928ece050d85fc244c72610244e440b0e00aa618faSebastien Hertzenum InterpreterImplKind { 2938ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz kSwitchImpl, // switch-based interpreter implementation. 2948ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz kComputedGotoImplKind // computed-goto-based interpreter implementation. 2958ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz}; 296fa46d3ee8cba2985c5c8bdfe47d15daf0613ebdcIan Rogers 2972c88b38ec22278c325c2917fdc60f0674e8b7976Sebastien Hertzstatic const InterpreterImplKind kInterpreterImplKind = kComputedGotoImplKind; 2982fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 299233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertzstatic JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 300233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz ShadowFrame& shadow_frame, JValue result_register) 301233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 302233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 303233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertzstatic inline JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 304233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz ShadowFrame& shadow_frame, JValue result_register) { 305848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers DCHECK(shadow_frame.GetMethod() == mh.GetMethod() || 306848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers shadow_frame.GetMethod()->GetDeclaringClass()->IsProxyClass()); 307848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers DCHECK(!shadow_frame.GetMethod()->IsAbstract()); 308848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers DCHECK(!shadow_frame.GetMethod()->IsNative()); 3098ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz 310d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz bool transaction_active = Runtime::Current()->IsActiveTransaction(); 3118ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz if (LIKELY(shadow_frame.GetMethod()->IsPreverified())) { 312233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz // Enter the "without access check" interpreter. 3138ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz if (kInterpreterImplKind == kSwitchImpl) { 314d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 315d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return ExecuteSwitchImpl<false, true>(self, mh, code_item, shadow_frame, result_register); 316d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 317d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return ExecuteSwitchImpl<false, false>(self, mh, code_item, shadow_frame, result_register); 318d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3198ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } else { 3208ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz DCHECK_EQ(kInterpreterImplKind, kComputedGotoImplKind); 321d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 322d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return ExecuteGotoImpl<false, true>(self, mh, code_item, shadow_frame, result_register); 323d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 324d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return ExecuteGotoImpl<false, false>(self, mh, code_item, shadow_frame, result_register); 325d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3268ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } 327233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } else { 328233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz // Enter the "with access check" interpreter. 3298ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz if (kInterpreterImplKind == kSwitchImpl) { 330d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 331d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return ExecuteSwitchImpl<true, true>(self, mh, code_item, shadow_frame, result_register); 332d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 333d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return ExecuteSwitchImpl<true, false>(self, mh, code_item, shadow_frame, result_register); 334d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3358ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } else { 3368ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz DCHECK_EQ(kInterpreterImplKind, kComputedGotoImplKind); 337d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 338d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return ExecuteGotoImpl<true, true>(self, mh, code_item, shadow_frame, result_register); 339d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 340d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz return ExecuteGotoImpl<true, false>(self, mh, code_item, shadow_frame, result_register); 341d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3428ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } 343233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } 344233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz} 345233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 346ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receiver, 3476474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao uint32_t* args, JValue* result) { 34864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers DCHECK_EQ(self, Thread::Current()); 349790ad90ccd2f3e297e2cf0a47adbf4f9ffb10149Jeff Hao if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) { 350d752132c73072084a3def9257cca4fcee76047b6jeffhao ThrowStackOverflowError(self); 351d752132c73072084a3def9257cca4fcee76047b6jeffhao return; 352d752132c73072084a3def9257cca4fcee76047b6jeffhao } 353d752132c73072084a3def9257cca4fcee76047b6jeffhao 354e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier const char* old_cause = self->StartAssertNoThreadSuspension("EnterInterpreterFromInvoke"); 3552fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers MethodHelper mh(method); 3562fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers const DexFile::CodeItem* code_item = mh.GetCodeItem(); 3572fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers uint16_t num_regs; 3582fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers uint16_t num_ins; 3592fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (code_item != NULL) { 3602fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_regs = code_item->registers_size_; 3612fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_ins = code_item->ins_size_; 3620a9bb73c70298922ad33d67c209a4e440b216fa2jeffhao } else if (method->IsAbstract()) { 363e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->EndAssertNoThreadSuspension(old_cause); 36456adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz ThrowAbstractMethodError(method); 3650a9bb73c70298922ad33d67c209a4e440b216fa2jeffhao return; 3662fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 3672fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers DCHECK(method->IsNative()); 368ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom num_regs = num_ins = ArtMethod::NumArgRegisters(mh.GetShorty()); 3692fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (!method->IsStatic()) { 3702fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_regs++; 3712fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_ins++; 3722fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3732fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3742fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers // Set up shadow frame with matching number of reference slots to vregs. 3752fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame(); 3766613519990bdb5616f2858c146f162ef760f03d2Jeff Hao void* memory = alloca(ShadowFrame::ComputeSize(num_regs)); 3776613519990bdb5616f2858c146f162ef760f03d2Jeff Hao ShadowFrame* shadow_frame(ShadowFrame::Create(num_regs, last_shadow_frame, method, 0, memory)); 3786613519990bdb5616f2858c146f162ef760f03d2Jeff Hao self->PushShadowFrame(shadow_frame); 379e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->EndAssertNoThreadSuspension(old_cause); 380e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier 3812fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers size_t cur_reg = num_regs - num_ins; 3822fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (!method->IsStatic()) { 3832fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers CHECK(receiver != NULL); 384ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa shadow_frame->SetVRegReference(cur_reg, receiver); 3852fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ++cur_reg; 386807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz } else if (UNLIKELY(!method->GetDeclaringClass()->IsInitializing())) { 387807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 388c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier SirtRef<mirror::Class> sirt_c(self, method->GetDeclaringClass()); 389c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier if (UNLIKELY(!class_linker->EnsureInitialized(sirt_c, true, true))) { 390807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz CHECK(self->IsExceptionPending()); 391807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz self->PopShadowFrame(); 39294d6df471a406a03bb1afba8ca3ae9c0fbf366b5jeffhao return; 39394d6df471a406a03bb1afba8ca3ae9c0fbf366b5jeffhao } 394c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier CHECK(sirt_c->IsInitializing()); 3952fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 39664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers const char* shorty = mh.GetShorty(); 3975d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) { 3985d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao DCHECK_LT(shorty_pos + 1, mh.GetShortyLength()); 3995d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao switch (shorty[shorty_pos + 1]) { 4002fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers case 'L': { 401ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Object* o = reinterpret_cast<StackReference<Object>*>(&args[arg_pos])->AsMirrorPtr(); 402ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa shadow_frame->SetVRegReference(cur_reg, o); 4032fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 4042fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4055d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao case 'J': case 'D': { 4065d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao uint64_t wide_value = (static_cast<uint64_t>(args[arg_pos + 1]) << 32) | args[arg_pos]; 4075d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao shadow_frame->SetVRegLong(cur_reg, wide_value); 4082fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers cur_reg++; 4095d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_pos++; 4102fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 4115d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } 4122fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers default: 4135d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao shadow_frame->SetVReg(cur_reg, args[arg_pos]); 4142fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 4152fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4162fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 41764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (LIKELY(!method->IsNative())) { 4186613519990bdb5616f2858c146f162ef760f03d2Jeff Hao JValue r = Execute(self, mh, code_item, *shadow_frame, JValue()); 4196474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao if (result != NULL) { 4206474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao *result = r; 4212fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4222fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 42364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 42464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // generated stub) except during testing and image writing. 42564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!Runtime::Current()->IsStarted()) { 4266474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao UnstartedRuntimeJni(self, method, receiver, args, result); 4272fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 4286474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao InterpreterJni(self, method, shorty, receiver, args, result); 4292fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4302fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4312fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers self->PopShadowFrame(); 4322fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} 4332fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 43462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid EnterInterpreterFromDeoptimize(Thread* self, ShadowFrame* shadow_frame, JValue* ret_val) 43511ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 43611ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao JValue value; 43762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers value.SetJ(ret_val->GetJ()); // Set value to last known result in case the shadow frame chain is empty. 43862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers MethodHelper mh; 43911ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao while (shadow_frame != NULL) { 44062d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->SetTopOfShadowStack(shadow_frame); 44162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mh.ChangeMethod(shadow_frame->GetMethod()); 44262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const DexFile::CodeItem* code_item = mh.GetCodeItem(); 44311ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao value = Execute(self, mh, code_item, *shadow_frame, value); 44411ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao ShadowFrame* old_frame = shadow_frame; 44511ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao shadow_frame = shadow_frame->GetLink(); 44611ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao delete old_frame; 44711ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao } 44811ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao ret_val->SetJ(value.GetJ()); 44911ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao} 45011ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao 4517db619bb2a4e01e8532a04b613745d4926b205d7Ian RogersJValue EnterInterpreterFromStub(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 452848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers ShadowFrame& shadow_frame) { 453f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers DCHECK_EQ(self, Thread::Current()); 454790ad90ccd2f3e297e2cf0a47adbf4f9ffb10149Jeff Hao if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) { 455f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers ThrowStackOverflowError(self); 456f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers return JValue(); 457f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers } 458f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers 4597db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers return Execute(self, mh, code_item, shadow_frame, JValue()); 4607db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers} 4617db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers 462848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogersextern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper& mh, 463848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers const DexFile::CodeItem* code_item, 464848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers ShadowFrame* shadow_frame, JValue* result) { 465790ad90ccd2f3e297e2cf0a47adbf4f9ffb10149Jeff Hao if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) { 466167436311a08a65dea28dda079a137893821c9c7Jeff Hao ThrowStackOverflowError(self); 4676951067ee14754454e17221fdef0d3d5ed7c4f7eJeff Hao return; 468167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 469167436311a08a65dea28dda079a137893821c9c7Jeff Hao 470e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->PushShadowFrame(shadow_frame); 471ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = shadow_frame->GetMethod(); 472c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz // Ensure static methods are initialized. 473c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz if (method->IsStatic()) { 474c528dba35b5faece51ca658fc008b688f8b690adMathieu Chartier SirtRef<Class> declaringClass(self, method->GetDeclaringClass()); 475c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz if (UNLIKELY(!declaringClass->IsInitializing())) { 476590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(declaringClass, true, 477590fee9e8972f872301c2d16a575d579ee564beeMathieu Chartier true))) { 478c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz DCHECK(Thread::Current()->IsExceptionPending()); 479e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->PopShadowFrame(); 480c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz return; 481c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz } 482c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz CHECK(declaringClass->IsInitializing()); 483167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 484167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 485167436311a08a65dea28dda079a137893821c9c7Jeff Hao 486167436311a08a65dea28dda079a137893821c9c7Jeff Hao if (LIKELY(!method->IsNative())) { 4876951067ee14754454e17221fdef0d3d5ed7c4f7eJeff Hao result->SetJ(Execute(self, mh, code_item, *shadow_frame, JValue()).GetJ()); 488167436311a08a65dea28dda079a137893821c9c7Jeff Hao } else { 489167436311a08a65dea28dda079a137893821c9c7Jeff Hao // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 490167436311a08a65dea28dda079a137893821c9c7Jeff Hao // generated stub) except during testing and image writing. 491167436311a08a65dea28dda079a137893821c9c7Jeff Hao CHECK(!Runtime::Current()->IsStarted()); 492e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier Object* receiver = method->IsStatic() ? nullptr : shadow_frame->GetVRegReference(0); 493167436311a08a65dea28dda079a137893821c9c7Jeff Hao uint32_t* args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1); 4946951067ee14754454e17221fdef0d3d5ed7c4f7eJeff Hao UnstartedRuntimeJni(self, method, receiver, args, result); 495167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 496167436311a08a65dea28dda079a137893821c9c7Jeff Hao 497167436311a08a65dea28dda079a137893821c9c7Jeff Hao self->PopShadowFrame(); 498167436311a08a65dea28dda079a137893821c9c7Jeff Hao} 499167436311a08a65dea28dda079a137893821c9c7Jeff Hao 5002fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} // namespace interpreter 5012fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} // namespace art 502