interpreter.cc revision 270a0e16c3b8e5b95cbfdbd8996ac137c7c6322b
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" 18b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 19d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz#include <limits> 202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 21b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers#include "mirror/string-inl.h" 22b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 232fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogersnamespace art { 242fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogersnamespace interpreter { 252fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 2664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers// Hand select a number of methods to be run in a not yet started runtime without using JNI. 27ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromstatic void UnstartedRuntimeJni(Thread* self, ArtMethod* method, 285d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* receiver, uint32_t* args, JValue* result) 2964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 3064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers std::string name(PrettyMethod(method)); 31a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogers if (name == "java.lang.Object dalvik.system.VMRuntime.newUnpaddedArray(java.lang.Class, int)") { 32a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogers int32_t length = args[1]; 33a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogers DCHECK_GE(length, 0); 34a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogers mirror::Class* element_class = reinterpret_cast<Object*>(args[0])->AsClass(); 35a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogers Runtime* runtime = Runtime::Current(); 36b74cd29802f364b4cec88f4913fa38ade26b8fabMathieu Chartier mirror::Class* array_class = runtime->GetClassLinker()->FindArrayClass(self, &element_class); 37a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogers DCHECK(array_class != nullptr); 38a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogers gc::AllocatorType allocator = runtime->GetHeap()->GetCurrentAllocator(); 39f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi result->SetL(mirror::Array::Alloc<true, true>(self, array_class, length, 40f0edfc355893d53d1104b05501c99ad5ccf305c4Hiroshi Yamauchi array_class->GetComponentSizeShift(), allocator)); 41a4e7413aa3420d54e41f37f286866a8025caa373Ian Rogers } else if (name == "java.lang.ClassLoader dalvik.system.VMStack.getCallingClassLoader()") { 4264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(NULL); 4364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.Class dalvik.system.VMStack.getStackClass2()") { 447a22fa657b972e8323692368975bc5a7be1cc0f5Ian Rogers NthCallerVisitor visitor(self, 3); 4564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers visitor.WalkStack(); 4664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(visitor.caller->GetDeclaringClass()); 4764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "double java.lang.Math.log(double)") { 485d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao JValue value; 495d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]); 505d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetD(log(value.GetD())); 5164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.String java.lang.Class.getNameNative()") { 52f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier StackHandleScope<1> hs(self); 53f832284dd847ff077577bb5712225430bbbb3b67Mathieu Chartier result->SetL(mirror::Class::ComputeName(hs.NewHandle(receiver->AsClass()))); 5464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "int java.lang.Float.floatToRawIntBits(float)") { 555d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(args[0]); 5664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "float java.lang.Float.intBitsToFloat(int)") { 575d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(args[0]); 5864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "double java.lang.Math.exp(double)") { 595d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao JValue value; 605d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao value.SetJ((static_cast<uint64_t>(args[1]) << 32) | args[0]); 615d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetD(exp(value.GetD())); 6264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.Object java.lang.Object.internalClone()") { 6364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(receiver->Clone(self)); 6464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "void java.lang.Object.notifyAll()") { 6505f3057d6a4d23d712092ccd36a531590bff323bIan Rogers receiver->NotifyAll(self); 6664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "int java.lang.String.compareTo(java.lang.String)") { 675d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao String* rhs = reinterpret_cast<Object*>(args[0])->AsString(); 6864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers CHECK(rhs != NULL); 6964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetI(receiver->AsString()->CompareTo(rhs)); 7064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.String java.lang.String.intern()") { 7164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetL(receiver->AsString()->Intern()); 7264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "int java.lang.String.fastIndexOf(int, int)") { 735d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(receiver->AsString()->FastIndexOf(args[0], args[1])); 7464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.Object java.lang.reflect.Array.createMultiArray(java.lang.Class, int[])") { 75eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier StackHandleScope<2> hs(self); 76eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier auto h_class(hs.NewHandle(reinterpret_cast<mirror::Class*>(args[0])->AsClass())); 77eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier auto h_dimensions(hs.NewHandle(reinterpret_cast<mirror::IntArray*>(args[1])->AsIntArray())); 78eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier result->SetL(Array::CreateMultiArray(self, h_class, h_dimensions)); 7964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "java.lang.Object java.lang.Throwable.nativeFillInStackTrace()") { 8064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedObjectAccessUnchecked soa(self); 815d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers if (Runtime::Current()->IsActiveTransaction()) { 825d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers result->SetL(soa.Decode<Object*>(self->CreateInternalStackTrace<true>(soa))); 835d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers } else { 845d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers result->SetL(soa.Decode<Object*>(self->CreateInternalStackTrace<false>(soa))); 855d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers } 86f48644b6cfd35fd029fc85dc7c837ad19b4a5ba3Sebastien Hertz } else if (name == "int java.lang.System.identityHashCode(java.lang.Object)") { 87f48644b6cfd35fd029fc85dc7c837ad19b4a5ba3Sebastien Hertz mirror::Object* obj = reinterpret_cast<Object*>(args[0]); 88f48644b6cfd35fd029fc85dc7c837ad19b4a5ba3Sebastien Hertz result->SetI((obj != nullptr) ? obj->IdentityHashCode() : 0); 8964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "boolean java.nio.ByteOrder.isLittleEndian()") { 90f48644b6cfd35fd029fc85dc7c837ad19b4a5ba3Sebastien Hertz result->SetZ(JNI_TRUE); 9164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "boolean sun.misc.Unsafe.compareAndSwapInt(java.lang.Object, long, int, int)") { 925d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* obj = reinterpret_cast<Object*>(args[0]); 935d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1]; 945d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao jint expectedValue = args[3]; 955d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao jint newValue = args[4]; 965d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers bool success; 975d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers if (Runtime::Current()->IsActiveTransaction()) { 98d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm success = obj->CasFieldStrongSequentiallyConsistent32<true>(MemberOffset(offset), 99d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm expectedValue, newValue); 1005d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers } else { 101d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm success = obj->CasFieldStrongSequentiallyConsistent32<false>(MemberOffset(offset), 102d8434439dc64add41cdfa69ddf96b960af9050deHans Boehm expectedValue, newValue); 1035d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers } 104f48644b6cfd35fd029fc85dc7c837ad19b4a5ba3Sebastien Hertz result->SetZ(success ? JNI_TRUE : JNI_FALSE); 10564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (name == "void sun.misc.Unsafe.putObject(java.lang.Object, long, java.lang.Object)") { 1065d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* obj = reinterpret_cast<Object*>(args[0]); 107f48644b6cfd35fd029fc85dc7c837ad19b4a5ba3Sebastien Hertz jlong offset = (static_cast<uint64_t>(args[2]) << 32) | args[1]; 1085d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* newValue = reinterpret_cast<Object*>(args[3]); 1095d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers if (Runtime::Current()->IsActiveTransaction()) { 1105d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers obj->SetFieldObject<true>(MemberOffset(offset), newValue); 1115d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers } else { 1125d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers obj->SetFieldObject<false>(MemberOffset(offset), newValue); 1135d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers } 1144d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi } else if (name == "int sun.misc.Unsafe.getArrayBaseOffsetForComponentType(java.lang.Class)") { 1154d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi mirror::Class* component = reinterpret_cast<Object*>(args[0])->AsClass(); 1164d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi Primitive::Type primitive_type = component->GetPrimitiveType(); 1174d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi result->SetI(mirror::Array::DataOffset(Primitive::ComponentSize(primitive_type)).Int32Value()); 1184d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi } else if (name == "int sun.misc.Unsafe.getArrayIndexScaleForComponentType(java.lang.Class)") { 1194d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi mirror::Class* component = reinterpret_cast<Object*>(args[0])->AsClass(); 1204d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi Primitive::Type primitive_type = component->GetPrimitiveType(); 1214d2efce8bf1947880b90efc44448b4940c8016fbHiroshi Yamauchi result->SetI(Primitive::ComponentSize(primitive_type)); 1225d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers } else if (Runtime::Current()->IsActiveTransaction()) { 123b2c7ead6bb5c98282cdfbc89db8984a004bea030Mathieu Chartier AbortTransaction(self, "Attempt to invoke native method in non-started runtime: %s", 124b2c7ead6bb5c98282cdfbc89db8984a004bea030Mathieu Chartier name.c_str()); 1255d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers 1265d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers } else { 1275d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers LOG(FATAL) << "Calling native method " << PrettyMethod(method) << " in an unstarted " 1285d27fafdf03f259e92eaee9f6319b9349cc8d62eIan Rogers "non-transactional runtime"; 12964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 13064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers} 13164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 132fc0e94bed3f88ed7e50854fd8dfaf5dcb345250fIan Rogersstatic void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& shorty, 1335d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* receiver, uint32_t* args, JValue* result) 13464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 13564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler, 13664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // it should be removed and JNI compiled stubs used instead. 13764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedObjectAccessUnchecked soa(self); 13864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (method->IsStatic()) { 13964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (shorty == "L") { 140460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jclass); 1412d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 14264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 14364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 144556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 145556d637764b71563030c479bc35364a75188d559Ian Rogers { 146556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 147556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), klass.get()); 148556d637764b71563030c479bc35364a75188d559Ian Rogers } 149556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 15064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "V") { 151460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass); 1522d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 15364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 15464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 15564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 15664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers fn(soa.Env(), klass.get()); 15764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "Z") { 158460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass); 1592d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 16064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 16164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 16264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 16364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetZ(fn(soa.Env(), klass.get())); 16464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "BI") { 165460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jbyte (fntype)(JNIEnv*, jclass, jint); 1662d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 16764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 16864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 16964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1705d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetB(fn(soa.Env(), klass.get(), args[0])); 17164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "II") { 172460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jint); 1732d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 17464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 17564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 17664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1775d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), args[0])); 17864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "LL") { 179460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jclass, jobject); 1802d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 18164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 18264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 18364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 1845d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 185556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 186556d637764b71563030c479bc35364a75188d559Ian Rogers { 187556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 188556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), klass.get(), arg0.get()); 189556d637764b71563030c479bc35364a75188d559Ian Rogers } 190556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 19164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "IIZ") { 192460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jint, jboolean); 1932d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 19464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 19564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 19664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1975d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), args[0], args[1])); 19864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ILI") { 199460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jobject, jint); 2002d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>( 2012d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier method->GetEntryPointFromJni())); 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 ScopedThreadStateChange tsc(self, kNative); 2075d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1])); 20864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "SIZ") { 209460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jshort (fntype)(JNIEnv*, jclass, jint, jboolean); 2102d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>(method->GetEntryPointFromJni())); 21164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 21264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 21364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2145d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetS(fn(soa.Env(), klass.get(), args[0], args[1])); 21564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VIZ") { 216460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jint, jboolean); 2172d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 21864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 21964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 22064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2215d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), args[0], args[1]); 22264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ZLL") { 223460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass, jobject, jobject); 2242d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 22564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 22664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 22764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 2285d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 22964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 2305d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 23164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 23264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get())); 23364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ZILL") { 234460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass, jint, jobject, jobject); 2352d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 23664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 23764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 23864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 2395d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 24064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg2(soa.Env(), 2415d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[2]))); 24264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2435d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetZ(fn(soa.Env(), klass.get(), args[0], arg1.get(), arg2.get())); 24464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VILII") { 245460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jint, jobject, jint, jint); 2462d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 24764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 24864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 24964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 2505d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[1]))); 25164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2525d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), args[0], arg1.get(), args[2], args[3]); 25364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VLILII") { 254460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint); 2552d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 25664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 25764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 25864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 2595d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 26064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg2(soa.Env(), 2615d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[2]))); 26264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2635d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), arg0.get(), args[1], arg2.get(), args[3], args[4]); 26464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 26564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers LOG(FATAL) << "Do something with static native method: " << PrettyMethod(method) 26664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers << " shorty: " << shorty; 26764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 26864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 26964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (shorty == "L") { 270460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jobject); 2712d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 27264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 27364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 274556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 275556d637764b71563030c479bc35364a75188d559Ian Rogers { 276556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 277556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), rcvr.get()); 278556d637764b71563030c479bc35364a75188d559Ian Rogers } 279556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 2803dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao } else if (shorty == "V") { 281460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jobject); 2822d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 2833dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao ScopedLocalRef<jobject> rcvr(soa.Env(), 2843dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao soa.AddLocalReference<jobject>(receiver)); 2853dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao ScopedThreadStateChange tsc(self, kNative); 2863dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao fn(soa.Env(), rcvr.get()); 28764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "LL") { 288460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jobject, jobject); 2892d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 29064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 29164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 29264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 2935d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao soa.AddLocalReference<jobject>(reinterpret_cast<Object*>(args[0]))); 294556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 295556d637764b71563030c479bc35364a75188d559Ian Rogers { 296556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 297556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), rcvr.get(), arg0.get()); 298556d637764b71563030c479bc35364a75188d559Ian Rogers } 299556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 30064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 30164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "III") { 302460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jobject, jint, jint); 3032d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 30464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 30564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 30664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 3075d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), rcvr.get(), args[0], args[1])); 30864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 30964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers LOG(FATAL) << "Do something with native method: " << PrettyMethod(method) 31064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers << " shorty: " << shorty; 31164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 31264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 31364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers} 31464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 3158ece050d85fc244c72610244e440b0e00aa618faSebastien Hertzenum InterpreterImplKind { 316b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers kSwitchImpl, // Switch-based interpreter implementation. 317b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers kComputedGotoImplKind // Computed-goto-based interpreter implementation. 3188ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz}; 319277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampestatic std::ostream& operator<<(std::ostream& os, const InterpreterImplKind& rhs) { 3206a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers os << ((rhs == kSwitchImpl) ? "Switch-based interpreter" : "Computed-goto-based interpreter"); 3216a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers return os; 3226a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers} 323fa46d3ee8cba2985c5c8bdfe47d15daf0613ebdcIan Rogers 324fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz#if !defined(__clang__) 325b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogersstatic constexpr InterpreterImplKind kInterpreterImplKind = kComputedGotoImplKind; 326fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz#else 327fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz// Clang 3.4 fails to build the goto interpreter implementation. 328fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertzstatic constexpr InterpreterImplKind kInterpreterImplKind = kSwitchImpl; 329fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertztemplate<bool do_access_check, bool transaction_active> 330e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl(Thread*, const DexFile::CodeItem*, ShadowFrame&, JValue) { 331fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz LOG(FATAL) << "UNREACHABLE"; 3322c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 333fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz} 334fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz// Explicit definitions of ExecuteGotoImpl. 335fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertztemplate<> SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 336e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item, 337fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz ShadowFrame& shadow_frame, JValue result_register); 338fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertztemplate<> SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 339e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item, 340fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz ShadowFrame& shadow_frame, JValue result_register); 341fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertztemplate<> SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 342e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item, 343e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers ShadowFrame& shadow_frame, JValue result_register); 344fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertztemplate<> SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) 345e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item, 346e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers ShadowFrame& shadow_frame, JValue result_register); 347fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz#endif 3482fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 349e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogersstatic JValue Execute(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame, 350e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers JValue result_register) 351233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz SHARED_LOCKS_REQUIRED(Locks::mutator_lock_); 352233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 353e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogersstatic inline JValue Execute(Thread* self, const DexFile::CodeItem* code_item, 354233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz ShadowFrame& shadow_frame, JValue result_register) { 355848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers DCHECK(!shadow_frame.GetMethod()->IsAbstract()); 356848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers DCHECK(!shadow_frame.GetMethod()->IsNative()); 3574e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz shadow_frame.GetMethod()->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self); 3588ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz 359d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz bool transaction_active = Runtime::Current()->IsActiveTransaction(); 3608ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz if (LIKELY(shadow_frame.GetMethod()->IsPreverified())) { 361233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz // Enter the "without access check" interpreter. 3628ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz if (kInterpreterImplKind == kSwitchImpl) { 363d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 364e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteSwitchImpl<false, true>(self, code_item, shadow_frame, result_register); 365d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 366e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register); 367d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3688ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } else { 3698ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz DCHECK_EQ(kInterpreterImplKind, kComputedGotoImplKind); 370d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 371e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteGotoImpl<false, true>(self, code_item, shadow_frame, result_register); 372d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 373e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteGotoImpl<false, false>(self, code_item, shadow_frame, result_register); 374d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3758ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } 376233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } else { 377233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz // Enter the "with access check" interpreter. 3788ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz if (kInterpreterImplKind == kSwitchImpl) { 379d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 380e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteSwitchImpl<true, true>(self, code_item, shadow_frame, result_register); 381d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 382e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteSwitchImpl<true, false>(self, code_item, shadow_frame, result_register); 383d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3848ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } else { 3858ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz DCHECK_EQ(kInterpreterImplKind, kComputedGotoImplKind); 386d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 387e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteGotoImpl<true, true>(self, code_item, shadow_frame, result_register); 388d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 389e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteGotoImpl<true, false>(self, code_item, shadow_frame, result_register); 390d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3918ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } 392233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } 393233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz} 394233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 395ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receiver, 3966474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao uint32_t* args, JValue* result) { 39764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers DCHECK_EQ(self, Thread::Current()); 398535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 399535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 400d752132c73072084a3def9257cca4fcee76047b6jeffhao ThrowStackOverflowError(self); 401d752132c73072084a3def9257cca4fcee76047b6jeffhao return; 402d752132c73072084a3def9257cca4fcee76047b6jeffhao } 403d752132c73072084a3def9257cca4fcee76047b6jeffhao 404e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier const char* old_cause = self->StartAssertNoThreadSuspension("EnterInterpreterFromInvoke"); 405bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const DexFile::CodeItem* code_item = method->GetCodeItem(); 4062fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers uint16_t num_regs; 4072fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers uint16_t num_ins; 4082fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (code_item != NULL) { 4092fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_regs = code_item->registers_size_; 4102fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_ins = code_item->ins_size_; 4110a9bb73c70298922ad33d67c209a4e440b216fa2jeffhao } else if (method->IsAbstract()) { 412e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->EndAssertNoThreadSuspension(old_cause); 41356adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz ThrowAbstractMethodError(method); 4140a9bb73c70298922ad33d67c209a4e440b216fa2jeffhao return; 4152fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 4162fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers DCHECK(method->IsNative()); 417bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier num_regs = num_ins = ArtMethod::NumArgRegisters(method->GetShorty()); 4182fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (!method->IsStatic()) { 4192fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_regs++; 4202fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_ins++; 4212fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4222fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4232fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers // Set up shadow frame with matching number of reference slots to vregs. 4242fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame(); 4256613519990bdb5616f2858c146f162ef760f03d2Jeff Hao void* memory = alloca(ShadowFrame::ComputeSize(num_regs)); 4266613519990bdb5616f2858c146f162ef760f03d2Jeff Hao ShadowFrame* shadow_frame(ShadowFrame::Create(num_regs, last_shadow_frame, method, 0, memory)); 4276613519990bdb5616f2858c146f162ef760f03d2Jeff Hao self->PushShadowFrame(shadow_frame); 428e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier 4292fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers size_t cur_reg = num_regs - num_ins; 4302fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (!method->IsStatic()) { 4312fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers CHECK(receiver != NULL); 432ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa shadow_frame->SetVRegReference(cur_reg, receiver); 4332fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ++cur_reg; 4342fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 435bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier uint32_t shorty_len = 0; 436bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const char* shorty = method->GetShorty(&shorty_len); 4375d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) { 438bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier DCHECK_LT(shorty_pos + 1, shorty_len); 4395d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao switch (shorty[shorty_pos + 1]) { 4402fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers case 'L': { 441ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Object* o = reinterpret_cast<StackReference<Object>*>(&args[arg_pos])->AsMirrorPtr(); 442ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa shadow_frame->SetVRegReference(cur_reg, o); 4432fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 4442fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4455d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao case 'J': case 'D': { 4465d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao uint64_t wide_value = (static_cast<uint64_t>(args[arg_pos + 1]) << 32) | args[arg_pos]; 4475d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao shadow_frame->SetVRegLong(cur_reg, wide_value); 4482fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers cur_reg++; 4495d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_pos++; 4502fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 4515d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } 4522fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers default: 4535d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao shadow_frame->SetVReg(cur_reg, args[arg_pos]); 4542fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 4552fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4562fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 45792246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier self->EndAssertNoThreadSuspension(old_cause); 45892246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier // Do this after populating the shadow frame in case EnsureInitialized causes a GC. 4596c5cb212fa7010ae7caf9dc765533aa967c95342Ian Rogers if (method->IsStatic() && UNLIKELY(!method->GetDeclaringClass()->IsInitialized())) { 46092246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 461eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier StackHandleScope<1> hs(self); 462eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass())); 4637b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers if (UNLIKELY(!class_linker->EnsureInitialized(self, h_class, true, true))) { 46492246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier CHECK(self->IsExceptionPending()); 46592246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier self->PopShadowFrame(); 46692246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier return; 46792246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier } 46892246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier } 46964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (LIKELY(!method->IsNative())) { 470e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers JValue r = Execute(self, code_item, *shadow_frame, JValue()); 4716474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao if (result != NULL) { 4726474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao *result = r; 4732fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4742fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 47564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 47664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // generated stub) except during testing and image writing. 47792246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier // Update args to be the args in the shadow frame since the input ones could hold stale 47892246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier // references pointers due to moving GC. 47992246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1); 48064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!Runtime::Current()->IsStarted()) { 4816474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao UnstartedRuntimeJni(self, method, receiver, args, result); 4822fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 4836474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao InterpreterJni(self, method, shorty, receiver, args, result); 4842fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4852fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4862fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers self->PopShadowFrame(); 4872fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} 4882fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 48962d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid EnterInterpreterFromDeoptimize(Thread* self, ShadowFrame* shadow_frame, JValue* ret_val) 49011ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) { 49111ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao JValue value; 49262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers value.SetJ(ret_val->GetJ()); // Set value to last known result in case the shadow frame chain is empty. 49311ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao while (shadow_frame != NULL) { 49462d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->SetTopOfShadowStack(shadow_frame); 495e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers const DexFile::CodeItem* code_item = shadow_frame->GetMethod()->GetCodeItem(); 496270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz const uint32_t dex_pc = shadow_frame->GetDexPC(); 497270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz uint32_t new_dex_pc; 498270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz if (UNLIKELY(self->IsExceptionPending())) { 499270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz const instrumentation::Instrumentation* const instrumentation = 500270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz Runtime::Current()->GetInstrumentation(); 501270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz uint32_t found_dex_pc = FindNextInstructionFollowingException(self, *shadow_frame, dex_pc, 502270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz instrumentation); 503270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz new_dex_pc = found_dex_pc; // the dex pc of a matching catch handler 504270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz // or DexFile::kDexNoIndex if there is none. 505270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz } else { 506270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz const Instruction* instr = Instruction::At(&code_item->insns_[dex_pc]); 507270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz new_dex_pc = dex_pc + instr->SizeInCodeUnits(); // the dex pc of the next instruction. 508270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz } 509270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz if (new_dex_pc != DexFile::kDexNoIndex) { 510270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz shadow_frame->SetDexPC(new_dex_pc); 511270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz value = Execute(self, code_item, *shadow_frame, value); 512270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz } 51311ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao ShadowFrame* old_frame = shadow_frame; 51411ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao shadow_frame = shadow_frame->GetLink(); 51511ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao delete old_frame; 51611ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao } 51711ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao ret_val->SetJ(value.GetJ()); 51811ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao} 51911ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao 520e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue EnterInterpreterFromEntryPoint(Thread* self, const DexFile::CodeItem* code_item, 5216f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers ShadowFrame* shadow_frame) { 522f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers DCHECK_EQ(self, Thread::Current()); 523535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 524535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 525f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers ThrowStackOverflowError(self); 526f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers return JValue(); 527f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers } 528f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers 529e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return Execute(self, code_item, *shadow_frame, JValue()); 5307db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers} 5317db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers 532e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogersextern "C" void artInterpreterToInterpreterBridge(Thread* self, const DexFile::CodeItem* code_item, 533848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers ShadowFrame* shadow_frame, JValue* result) { 534535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 535535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 536167436311a08a65dea28dda079a137893821c9c7Jeff Hao ThrowStackOverflowError(self); 5376951067ee14754454e17221fdef0d3d5ed7c4f7eJeff Hao return; 538167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 539167436311a08a65dea28dda079a137893821c9c7Jeff Hao 540e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->PushShadowFrame(shadow_frame); 541c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz // Ensure static methods are initialized. 542e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers const bool is_static = shadow_frame->GetMethod()->IsStatic(); 543e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers if (is_static) { 544e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers mirror::Class* declaring_class = shadow_frame->GetMethod()->GetDeclaringClass(); 5456c5cb212fa7010ae7caf9dc765533aa967c95342Ian Rogers if (UNLIKELY(!declaring_class->IsInitialized())) { 5460cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier StackHandleScope<1> hs(self); 5470cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier HandleWrapper<Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class)); 5480cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized( 5497b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers self, h_declaring_class, true, true))) { 5500cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier DCHECK(self->IsExceptionPending()); 551e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->PopShadowFrame(); 552c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz return; 553c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz } 5540cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier CHECK(h_declaring_class->IsInitializing()); 555167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 556167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 557167436311a08a65dea28dda079a137893821c9c7Jeff Hao 558e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers if (LIKELY(!shadow_frame->GetMethod()->IsNative())) { 559e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers result->SetJ(Execute(self, code_item, *shadow_frame, JValue()).GetJ()); 560167436311a08a65dea28dda079a137893821c9c7Jeff Hao } else { 561167436311a08a65dea28dda079a137893821c9c7Jeff Hao // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 562167436311a08a65dea28dda079a137893821c9c7Jeff Hao // generated stub) except during testing and image writing. 563167436311a08a65dea28dda079a137893821c9c7Jeff Hao CHECK(!Runtime::Current()->IsStarted()); 564e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers Object* receiver = is_static ? nullptr : shadow_frame->GetVRegReference(0); 565e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers uint32_t* args = shadow_frame->GetVRegArgs(is_static ? 0 : 1); 566e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers UnstartedRuntimeJni(self, shadow_frame->GetMethod(), receiver, args, result); 567167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 568167436311a08a65dea28dda079a137893821c9c7Jeff Hao 569167436311a08a65dea28dda079a137893821c9c7Jeff Hao self->PopShadowFrame(); 570167436311a08a65dea28dda079a137893821c9c7Jeff Hao} 571167436311a08a65dea28dda079a137893821c9c7Jeff Hao 5722fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} // namespace interpreter 5732fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} // namespace art 574