interpreter.cc revision 2c88b38ec22278c325c2917fdc60f0674e8b7976
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" 182dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 192fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogersnamespace art { 202fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogersnamespace interpreter { 212fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 2264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers// Hand select a number of methods to be run in a not yet started runtime without using JNI. 23ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromstatic void UnstartedRuntimeJni(Thread* self, ArtMethod* method, 245d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* receiver, uint32_t* args, JValue* result) 2564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 2664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers std::string name(PrettyMethod(method)); 2764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (name == "java.lang.ClassLoader dalvik.system.VMStack.getCallingClassLoader()") { 2864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(NULL); 2964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.Class dalvik.system.VMStack.getStackClass2()") { 307a22fa657b972e8323692368975bc5a7be1cc0f5Ian Rogers NthCallerVisitor visitor(self, 3); 3164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers visitor.WalkStack(); 3264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(visitor.caller->GetDeclaringClass()); 3364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "double java.lang.Math.log(double)") { 345d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao JValue value; 355d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]); 365d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetD(log(value.GetD())); 3764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.String java.lang.Class.getNameNative()") { 3864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(receiver->AsClass()->ComputeName()); 3964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "int java.lang.Float.floatToRawIntBits(float)") { 405d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(args[0]); 4164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "float java.lang.Float.intBitsToFloat(int)") { 425d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(args[0]); 4364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "double java.lang.Math.exp(double)") { 445d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao JValue value; 455d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]); 465d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetD(exp(value.GetD())); 4764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.Object java.lang.Object.internalClone()") { 4864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(receiver->Clone(self)); 4964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "void java.lang.Object.notifyAll()") { 5005f3057d6a4d23d712092ccd36a531590bff323bIan Rogers receiver->NotifyAll(self); 5164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "int java.lang.String.compareTo(java.lang.String)") { 525d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao String* rhs = reinterpret_cast<Object*>(args[0])->AsString(); 5364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers CHECK(rhs != NULL); 5464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetI(receiver->AsString()->CompareTo(rhs)); 5564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.String java.lang.String.intern()") { 5664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(receiver->AsString()->Intern()); 5764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "int java.lang.String.fastIndexOf(int, int)") { 585d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(receiver->AsString()->FastIndexOf(args[0], args[1])); 5964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.Object java.lang.reflect.Array.createMultiArray(java.lang.Class, int[])") { 605d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetL(Array::CreateMultiArray(self, reinterpret_cast<Object*>(args[0])->AsClass(), reinterpret_cast<Object*>(args[1])->AsIntArray())); 6164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.Object java.lang.Throwable.nativeFillInStackTrace()") { 6264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedObjectAccessUnchecked soa(self); 6364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(soa.Decode<Object*>(self->CreateInternalStackTrace(soa))); 6464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "boolean java.nio.ByteOrder.isLittleEndian()") { 6564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetJ(JNI_TRUE); 6664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)") { 675d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* obj = reinterpret_cast<Object*>(args[0]); 685d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1]; 695d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao jint expectedValue = args[3]; 705d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao jint newValue = args[4]; 7164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers byte* raw_addr = reinterpret_cast<byte*>(obj) + offset; 7264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers volatile int32_t* address = reinterpret_cast<volatile int32_t*>(raw_addr); 7364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // Note: android_atomic_release_cas() returns 0 on success, not failure. 7464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers int r = android_atomic_release_cas(expectedValue, newValue, address); 7564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetZ(r == 0); 7664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)") { 775d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* obj = reinterpret_cast<Object*>(args[0]); 785d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* newValue = reinterpret_cast<Object*>(args[3]); 795d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao obj->SetFieldObject(MemberOffset((static_cast<uint64_t>(args[2]) << 32) | args[1]), newValue, false); 8064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 8164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers LOG(FATAL) << "Attempt to invoke native method in non-started runtime: " << name; 8264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 8364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers} 8464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 85fc0e94bed3f88ed7e50854fd8dfaf5dcb345250fIan Rogersstatic void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& shorty, 865d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* receiver, uint32_t* args, JValue* result) 8764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 8864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler, 8964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // it should be removed and JNI compiled stubs used instead. 9064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedObjectAccessUnchecked soa(self); 9164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (method->IsStatic()) { 9264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (shorty == "L") { 9364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef jobject (fnptr)(JNIEnv*, jclass); 94d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 9564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 9664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 97556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 98556d637764b71563030c479bc35364a75188d559Ian Rogers { 99556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 100556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), klass.get()); 101556d637764b71563030c479bc35364a75188d559Ian Rogers } 102556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 10364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "V") { 10464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef void (fnptr)(JNIEnv*, jclass); 105d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 10664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 10764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 10864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 10964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers fn(soa.Env(), klass.get()); 11064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "Z") { 11164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef jboolean (fnptr)(JNIEnv*, jclass); 112d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 11364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 11464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 11564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 11664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetZ(fn(soa.Env(), klass.get())); 11764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "BI") { 11864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef jbyte (fnptr)(JNIEnv*, jclass, jint); 119d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 12064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 12164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 12264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1235d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetB(fn(soa.Env(), klass.get(), args[0])); 12464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "II") { 12564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef jint (fnptr)(JNIEnv*, jclass, jint); 126d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 12764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 12864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 12964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1305d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), args[0])); 13164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "LL") { 13264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef jobject (fnptr)(JNIEnv*, jclass, jobject); 133d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 13464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 13564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 13664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 1375d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 138556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 139556d637764b71563030c479bc35364a75188d559Ian Rogers { 140556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 141556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), klass.get(), arg0.get()); 142556d637764b71563030c479bc35364a75188d559Ian Rogers } 143556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 14464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "IIZ") { 14564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef jint (fnptr)(JNIEnv*, jclass, jint, jboolean); 146d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 14764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 14864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 14964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1505d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), args[0], args[1])); 15164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ILI") { 15264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef jint (fnptr)(JNIEnv*, jclass, jobject, jint); 153d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 15464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 15564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 15664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 1575d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 15864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1595d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1])); 16064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "SIZ") { 16164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef jshort (fnptr)(JNIEnv*, jclass, jint, jboolean); 162d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 16364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 16464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 16564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1665d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetS(fn(soa.Env(), klass.get(), args[0], args[1])); 16764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VIZ") { 16864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef void (fnptr)(JNIEnv*, jclass, jint, jboolean); 169d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 17064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 17164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 17264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1735d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), args[0], args[1]); 17464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ZLL") { 17564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef jboolean (fnptr)(JNIEnv*, jclass, jobject, jobject); 176d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 17764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 17864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 17964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 1805d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 18164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 1825d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 18364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 18464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get())); 18564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ZILL") { 18664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef jboolean (fnptr)(JNIEnv*, jclass, jint, jobject, jobject); 187d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 18864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 18964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 19064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 1915d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 19264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg2(soa.Env(), 1935d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[2]))); 19464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1955d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetZ(fn(soa.Env(), klass.get(), args[0], arg1.get(), arg2.get())); 19664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VILII") { 19764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef void (fnptr)(JNIEnv*, jclass, jint, jobject, jint, jint); 198d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 19964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 20064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 20164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 2025d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 20364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2045d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), args[0], arg1.get(), args[2], args[3]); 20564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VLILII") { 20664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef void (fnptr)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint); 207d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 20864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 20964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 21064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 2115d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 21264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg2(soa.Env(), 2135d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[2]))); 21464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2155d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), arg0.get(), args[1], arg2.get(), args[3], args[4]); 21664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 21764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers LOG(FATAL) << "Do something with static native method: " << PrettyMethod(method) 21864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers << " shorty: " << shorty; 21964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 22064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 22164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (shorty == "L") { 22264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef jobject (fnptr)(JNIEnv*, jobject); 223d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 22464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 22564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 226556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 227556d637764b71563030c479bc35364a75188d559Ian Rogers { 228556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 229556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), rcvr.get()); 230556d637764b71563030c479bc35364a75188d559Ian Rogers } 231556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 2323dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao } else if (shorty == "V") { 2333dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao typedef void (fnptr)(JNIEnv*, jobject); 2343dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 2353dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao ScopedLocalRef<jobject> rcvr(soa.Env(), 2363dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao soa.AddLocalReference<jobject>(receiver)); 2373dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao ScopedThreadStateChange tsc(self, kNative); 2383dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao fn(soa.Env(), rcvr.get()); 23964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "LL") { 24064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef jobject (fnptr)(JNIEnv*, jobject, jobject); 241d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 24264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 24364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 24464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 2455d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 246556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 247556d637764b71563030c479bc35364a75188d559Ian Rogers { 248556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 249556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), rcvr.get(), arg0.get()); 250556d637764b71563030c479bc35364a75188d559Ian Rogers } 251556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 25264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 25364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "III") { 25464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers typedef jint (fnptr)(JNIEnv*, jobject, jint, jint); 255d8274bcbc565fff1254574b3cbf46dc4e7b52812Ian Rogers const fnptr* fn = reinterpret_cast<const fnptr*>(method->GetNativeMethod()); 25664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 25764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 25864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2595d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), rcvr.get(), args[0], args[1])); 26064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 26164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers LOG(FATAL) << "Do something with native method: " << PrettyMethod(method) 26264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers << " shorty: " << shorty; 26364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 26464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 26564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers} 26664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 2678ece050d85fc244c72610244e440b0e00aa618faSebastien Hertzenum InterpreterImplKind { 2688ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz kSwitchImpl, // switch-based interpreter implementation. 2698ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz kComputedGotoImplKind // computed-goto-based interpreter implementation. 2708ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz}; 271fa46d3ee8cba2985c5c8bdfe47d15daf0613ebdcIan Rogers 2722c88b38ec22278c325c2917fdc60f0674e8b7976Sebastien Hertzstatic const InterpreterImplKind kInterpreterImplKind = kComputedGotoImplKind; 2732fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 274233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertzstatic JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 275233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz ShadowFrame& shadow_frame, JValue result_register) 276233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 277233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 278233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertzstatic inline JValue Execute(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 279233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz ShadowFrame& shadow_frame, JValue result_register) { 280848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers DCHECK(shadow_frame.GetMethod() == mh.GetMethod() || 281848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers shadow_frame.GetMethod()->GetDeclaringClass()->IsProxyClass()); 282848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers DCHECK(!shadow_frame.GetMethod()->IsAbstract()); 283848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers DCHECK(!shadow_frame.GetMethod()->IsNative()); 2848ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz 2858ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz if (LIKELY(shadow_frame.GetMethod()->IsPreverified())) { 286233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz // Enter the "without access check" interpreter. 2878ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz if (kInterpreterImplKind == kSwitchImpl) { 2888ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz return ExecuteSwitchImpl<false>(self, mh, code_item, shadow_frame, result_register); 2898ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } else { 2908ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz DCHECK_EQ(kInterpreterImplKind, kComputedGotoImplKind); 2918ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz return ExecuteGotoImpl<false>(self, mh, code_item, shadow_frame, result_register); 2928ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } 293233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } else { 294233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz // Enter the "with access check" interpreter. 2958ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz if (kInterpreterImplKind == kSwitchImpl) { 2968ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz return ExecuteSwitchImpl<true>(self, mh, code_item, shadow_frame, result_register); 2978ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } else { 2988ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz DCHECK_EQ(kInterpreterImplKind, kComputedGotoImplKind); 2998ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz return ExecuteGotoImpl<true>(self, mh, code_item, shadow_frame, result_register); 3008ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } 301233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } 302233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz} 303233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 304ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receiver, 3056474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao uint32_t* args, JValue* result) { 30664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers DCHECK_EQ(self, Thread::Current()); 307790ad90ccd2f3e297e2cf0a47adbf4f9ffb10149Jeff Hao if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) { 308d752132c73072084a3def9257cca4fcee76047b6jeffhao ThrowStackOverflowError(self); 309d752132c73072084a3def9257cca4fcee76047b6jeffhao return; 310d752132c73072084a3def9257cca4fcee76047b6jeffhao } 311d752132c73072084a3def9257cca4fcee76047b6jeffhao 312e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier const char* old_cause = self->StartAssertNoThreadSuspension("EnterInterpreterFromInvoke"); 3132fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers MethodHelper mh(method); 3142fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers const DexFile::CodeItem* code_item = mh.GetCodeItem(); 3152fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers uint16_t num_regs; 3162fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers uint16_t num_ins; 3172fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (code_item != NULL) { 3182fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_regs = code_item->registers_size_; 3192fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_ins = code_item->ins_size_; 3200a9bb73c70298922ad33d67c209a4e440b216fa2jeffhao } else if (method->IsAbstract()) { 321e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->EndAssertNoThreadSuspension(old_cause); 32256adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz ThrowAbstractMethodError(method); 3230a9bb73c70298922ad33d67c209a4e440b216fa2jeffhao return; 3242fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 3252fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers DCHECK(method->IsNative()); 326ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom num_regs = num_ins = ArtMethod::NumArgRegisters(mh.GetShorty()); 3272fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (!method->IsStatic()) { 3282fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_regs++; 3292fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_ins++; 3302fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3312fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3322fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers // Set up shadow frame with matching number of reference slots to vregs. 3332fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame(); 3346613519990bdb5616f2858c146f162ef760f03d2Jeff Hao void* memory = alloca(ShadowFrame::ComputeSize(num_regs)); 3356613519990bdb5616f2858c146f162ef760f03d2Jeff Hao ShadowFrame* shadow_frame(ShadowFrame::Create(num_regs, last_shadow_frame, method, 0, memory)); 3366613519990bdb5616f2858c146f162ef760f03d2Jeff Hao self->PushShadowFrame(shadow_frame); 337e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->EndAssertNoThreadSuspension(old_cause); 338e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier 3392fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers size_t cur_reg = num_regs - num_ins; 3402fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (!method->IsStatic()) { 3412fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers CHECK(receiver != NULL); 342ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa shadow_frame->SetVRegReference(cur_reg, receiver); 3432fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ++cur_reg; 344807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz } else if (UNLIKELY(!method->GetDeclaringClass()->IsInitializing())) { 345807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 346e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier if (UNLIKELY(!class_linker->EnsureInitialized(method->GetDeclaringClass(), true, true))) { 347807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz CHECK(self->IsExceptionPending()); 348807a25640d4f4de8143b160b3bb8f552ffbf6f4aSebastien Hertz self->PopShadowFrame(); 34994d6df471a406a03bb1afba8ca3ae9c0fbf366b5jeffhao return; 35094d6df471a406a03bb1afba8ca3ae9c0fbf366b5jeffhao } 3512fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers CHECK(method->GetDeclaringClass()->IsInitializing()); 3522fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 35364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers const char* shorty = mh.GetShorty(); 3545d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) { 3555d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao DCHECK_LT(shorty_pos + 1, mh.GetShortyLength()); 3565d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao switch (shorty[shorty_pos + 1]) { 3572fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers case 'L': { 3585d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* o = reinterpret_cast<Object*>(args[arg_pos]); 359ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa shadow_frame->SetVRegReference(cur_reg, o); 3602fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 3612fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3625d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao case 'J': case 'D': { 3635d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao uint64_t wide_value = (static_cast<uint64_t>(args[arg_pos + 1]) << 32) | args[arg_pos]; 3645d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao shadow_frame->SetVRegLong(cur_reg, wide_value); 3652fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers cur_reg++; 3665d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_pos++; 3672fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 3685d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } 3692fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers default: 3705d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao shadow_frame->SetVReg(cur_reg, args[arg_pos]); 3712fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 3722fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3732fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 37464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (LIKELY(!method->IsNative())) { 3756613519990bdb5616f2858c146f162ef760f03d2Jeff Hao JValue r = Execute(self, mh, code_item, *shadow_frame, JValue()); 3766474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao if (result != NULL) { 3776474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao *result = r; 3782fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3792fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 38064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 38164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // generated stub) except during testing and image writing. 38264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!Runtime::Current()->IsStarted()) { 3836474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao UnstartedRuntimeJni(self, method, receiver, args, result); 3842fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 3856474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao InterpreterJni(self, method, shorty, receiver, args, result); 3862fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3872fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3882fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers self->PopShadowFrame(); 3892fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} 3902fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 39162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid EnterInterpreterFromDeoptimize(Thread* self, ShadowFrame* shadow_frame, JValue* ret_val) 39211ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 39311ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao JValue value; 39462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers value.SetJ(ret_val->GetJ()); // Set value to last known result in case the shadow frame chain is empty. 39562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers MethodHelper mh; 39611ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao while (shadow_frame != NULL) { 39762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->SetTopOfShadowStack(shadow_frame); 39862d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers mh.ChangeMethod(shadow_frame->GetMethod()); 39962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers const DexFile::CodeItem* code_item = mh.GetCodeItem(); 40011ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao value = Execute(self, mh, code_item, *shadow_frame, value); 40111ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao ShadowFrame* old_frame = shadow_frame; 40211ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao shadow_frame = shadow_frame->GetLink(); 40311ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao delete old_frame; 40411ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao } 40511ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao ret_val->SetJ(value.GetJ()); 40611ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao} 40711ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao 4087db619bb2a4e01e8532a04b613745d4926b205d7Ian RogersJValue EnterInterpreterFromStub(Thread* self, MethodHelper& mh, const DexFile::CodeItem* code_item, 409848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers ShadowFrame& shadow_frame) { 410f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers DCHECK_EQ(self, Thread::Current()); 411790ad90ccd2f3e297e2cf0a47adbf4f9ffb10149Jeff Hao if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) { 412f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers ThrowStackOverflowError(self); 413f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers return JValue(); 414f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers } 415f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers 4167db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers return Execute(self, mh, code_item, shadow_frame, JValue()); 4177db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers} 4187db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers 419848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogersextern "C" void artInterpreterToInterpreterBridge(Thread* self, MethodHelper& mh, 420848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers const DexFile::CodeItem* code_item, 421848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers ShadowFrame* shadow_frame, JValue* result) { 422790ad90ccd2f3e297e2cf0a47adbf4f9ffb10149Jeff Hao if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) { 423167436311a08a65dea28dda079a137893821c9c7Jeff Hao ThrowStackOverflowError(self); 4246951067ee14754454e17221fdef0d3d5ed7c4f7eJeff Hao return; 425167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 426167436311a08a65dea28dda079a137893821c9c7Jeff Hao 427e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->PushShadowFrame(shadow_frame); 428ea46f950e7a51585db293cd7f047de190a482414Brian Carlstrom ArtMethod* method = shadow_frame->GetMethod(); 429c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz // Ensure static methods are initialized. 430c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz if (method->IsStatic()) { 431c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz Class* declaringClass = method->GetDeclaringClass(); 432c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz if (UNLIKELY(!declaringClass->IsInitializing())) { 433c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(declaringClass, 434c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz true, true))) { 435c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz DCHECK(Thread::Current()->IsExceptionPending()); 436e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->PopShadowFrame(); 437c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz return; 438c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz } 439c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz CHECK(declaringClass->IsInitializing()); 440167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 441167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 442167436311a08a65dea28dda079a137893821c9c7Jeff Hao 443167436311a08a65dea28dda079a137893821c9c7Jeff Hao if (LIKELY(!method->IsNative())) { 4446951067ee14754454e17221fdef0d3d5ed7c4f7eJeff Hao result->SetJ(Execute(self, mh, code_item, *shadow_frame, JValue()).GetJ()); 445167436311a08a65dea28dda079a137893821c9c7Jeff Hao } else { 446167436311a08a65dea28dda079a137893821c9c7Jeff Hao // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 447167436311a08a65dea28dda079a137893821c9c7Jeff Hao // generated stub) except during testing and image writing. 448167436311a08a65dea28dda079a137893821c9c7Jeff Hao CHECK(!Runtime::Current()->IsStarted()); 449e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier Object* receiver = method->IsStatic() ? nullptr : shadow_frame->GetVRegReference(0); 450167436311a08a65dea28dda079a137893821c9c7Jeff Hao uint32_t* args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1); 4516951067ee14754454e17221fdef0d3d5ed7c4f7eJeff Hao UnstartedRuntimeJni(self, method, receiver, args, result); 452167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 453167436311a08a65dea28dda079a137893821c9c7Jeff Hao 454167436311a08a65dea28dda079a137893821c9c7Jeff Hao self->PopShadowFrame(); 455167436311a08a65dea28dda079a137893821c9c7Jeff Hao} 456167436311a08a65dea28dda079a137893821c9c7Jeff Hao 4572fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} // namespace interpreter 4582fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} // namespace art 459