interpreter.cc revision 520633bebd2bf4d70884d30f179dbde9f275aac6
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" 222969bcdcd80624e4a4fef696b54c2c76b44b6853Andreas Gampe#include "scoped_thread_state_change.h" 232969bcdcd80624e4a4fef696b54c2c76b44b6853Andreas Gampe#include "ScopedLocalRef.h" 242969bcdcd80624e4a4fef696b54c2c76b44b6853Andreas Gampe#include "unstarted_runtime.h" 25b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 262fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogersnamespace art { 272fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogersnamespace interpreter { 282fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 29fc0e94bed3f88ed7e50854fd8dfaf5dcb345250fIan Rogersstatic void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& shorty, 305d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* receiver, uint32_t* args, JValue* result) 3190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 3264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler, 3364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // it should be removed and JNI compiled stubs used instead. 3464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedObjectAccessUnchecked soa(self); 3564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (method->IsStatic()) { 3664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (shorty == "L") { 37460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jclass); 382d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 3964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 4064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 41556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 42556d637764b71563030c479bc35364a75188d559Ian Rogers { 43556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 44556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), klass.get()); 45556d637764b71563030c479bc35364a75188d559Ian Rogers } 46556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 4764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "V") { 48460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass); 492d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 5064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 5164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 5264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 5364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers fn(soa.Env(), klass.get()); 5464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "Z") { 55460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass); 562d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 5764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 5864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 5964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 6064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetZ(fn(soa.Env(), klass.get())); 6164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "BI") { 62460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jbyte (fntype)(JNIEnv*, jclass, jint); 632d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 6464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 6564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 6664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 675d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetB(fn(soa.Env(), klass.get(), args[0])); 6864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "II") { 69460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jint); 702d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 7164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 7264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 7364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 745d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), args[0])); 7564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "LL") { 76460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jclass, jobject); 772d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 7864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 7964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 8064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 812cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 822cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[0]))); 83556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 84556d637764b71563030c479bc35364a75188d559Ian Rogers { 85556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 86556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), klass.get(), arg0.get()); 87556d637764b71563030c479bc35364a75188d559Ian Rogers } 88556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 8964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "IIZ") { 90460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jint, jboolean); 912d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 9264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 9364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 9464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 955d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), args[0], args[1])); 9664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ILI") { 97460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jobject, jint); 982d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>( 992d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier method->GetEntryPointFromJni())); 10064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 10164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 10264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 1032cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1042cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[0]))); 10564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1065d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1])); 10764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "SIZ") { 108460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jshort (fntype)(JNIEnv*, jclass, jint, jboolean); 1092cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier fntype* const fn = 1102cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<fntype*>(const_cast<void*>(method->GetEntryPointFromJni())); 11164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 11264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 11364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1145d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetS(fn(soa.Env(), klass.get(), args[0], args[1])); 11564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VIZ") { 116460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jint, jboolean); 1172d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 11864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 11964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 12064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1215d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), args[0], args[1]); 12264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ZLL") { 123460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass, jobject, jobject); 1242d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 12564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 12664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 12764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 1282cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1292cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[0]))); 13064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 1312cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1322cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[1]))); 13364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 13464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get())); 13564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ZILL") { 136460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass, jint, jobject, jobject); 1372d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 13864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 13964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 14064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 1412cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1422cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[1]))); 14364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg2(soa.Env(), 1442cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1452cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[2]))); 14664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1475d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetZ(fn(soa.Env(), klass.get(), args[0], arg1.get(), arg2.get())); 14864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VILII") { 149460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jint, jobject, jint, jint); 1502d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 15164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 15264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 15364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 1542cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1552cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[1]))); 15664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1575d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), args[0], arg1.get(), args[2], args[3]); 15864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VLILII") { 159460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint); 1602d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 16164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 16264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 16364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 1642cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1652cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[0]))); 16664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg2(soa.Env(), 1672cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1682cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[2]))); 16964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1705d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), arg0.get(), args[1], arg2.get(), args[3], args[4]); 17164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 17264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers LOG(FATAL) << "Do something with static native method: " << PrettyMethod(method) 17364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers << " shorty: " << shorty; 17464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 17564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 17664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (shorty == "L") { 177460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jobject); 1782d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 17964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 18064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 181556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 182556d637764b71563030c479bc35364a75188d559Ian Rogers { 183556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 184556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), rcvr.get()); 185556d637764b71563030c479bc35364a75188d559Ian Rogers } 186556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 1873dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao } else if (shorty == "V") { 188460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jobject); 1892d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 1903dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao ScopedLocalRef<jobject> rcvr(soa.Env(), 1913dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao soa.AddLocalReference<jobject>(receiver)); 1923dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao ScopedThreadStateChange tsc(self, kNative); 1933dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao fn(soa.Env(), rcvr.get()); 19464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "LL") { 195460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jobject, jobject); 1962d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 19764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 19864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 19964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 2002cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 2012cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[0]))); 202556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 203556d637764b71563030c479bc35364a75188d559Ian Rogers { 204556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 205556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), rcvr.get(), arg0.get()); 206556d637764b71563030c479bc35364a75188d559Ian Rogers } 207556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 20864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 20964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "III") { 210460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jobject, jint, jint); 2112d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 21264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 21364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 21464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2155d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), rcvr.get(), args[0], args[1])); 21664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 21764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers LOG(FATAL) << "Do something with native method: " << PrettyMethod(method) 21864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers << " shorty: " << shorty; 21964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 22064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 22164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers} 22264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 2238ece050d85fc244c72610244e440b0e00aa618faSebastien Hertzenum InterpreterImplKind { 224b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers kSwitchImpl, // Switch-based interpreter implementation. 225b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogers kComputedGotoImplKind // Computed-goto-based interpreter implementation. 2268ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz}; 227277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampestatic std::ostream& operator<<(std::ostream& os, const InterpreterImplKind& rhs) { 2286a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers os << ((rhs == kSwitchImpl) ? "Switch-based interpreter" : "Computed-goto-based interpreter"); 2296a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers return os; 2306a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers} 231fa46d3ee8cba2985c5c8bdfe47d15daf0613ebdcIan Rogers 232fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz#if !defined(__clang__) 233b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogersstatic constexpr InterpreterImplKind kInterpreterImplKind = kComputedGotoImplKind; 234fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz#else 235fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz// Clang 3.4 fails to build the goto interpreter implementation. 236fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertzstatic constexpr InterpreterImplKind kInterpreterImplKind = kSwitchImpl; 237fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertztemplate<bool do_access_check, bool transaction_active> 238e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl(Thread*, const DexFile::CodeItem*, ShadowFrame&, JValue) { 239fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz LOG(FATAL) << "UNREACHABLE"; 2402c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 241fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz} 242fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz// Explicit definitions of ExecuteGotoImpl. 24390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartiertemplate<> SHARED_REQUIRES(Locks::mutator_lock_) 244e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item, 245fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz ShadowFrame& shadow_frame, JValue result_register); 24690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartiertemplate<> SHARED_REQUIRES(Locks::mutator_lock_) 247e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item, 248fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz ShadowFrame& shadow_frame, JValue result_register); 24990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartiertemplate<> SHARED_REQUIRES(Locks::mutator_lock_) 250e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item, 251e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers ShadowFrame& shadow_frame, JValue result_register); 25290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartiertemplate<> SHARED_REQUIRES(Locks::mutator_lock_) 253e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item, 254e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers ShadowFrame& shadow_frame, JValue result_register); 255fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz#endif 2562fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 257e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogersstatic JValue Execute(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame, 258e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers JValue result_register) 25990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 260233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 261e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogersstatic inline JValue Execute(Thread* self, const DexFile::CodeItem* code_item, 262233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz ShadowFrame& shadow_frame, JValue result_register) { 263848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers DCHECK(!shadow_frame.GetMethod()->IsAbstract()); 264848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers DCHECK(!shadow_frame.GetMethod()->IsNative()); 2654e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz shadow_frame.GetMethod()->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self); 2668ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz 267d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz bool transaction_active = Runtime::Current()->IsActiveTransaction(); 2688ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz if (LIKELY(shadow_frame.GetMethod()->IsPreverified())) { 269233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz // Enter the "without access check" interpreter. 2708ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz if (kInterpreterImplKind == kSwitchImpl) { 271d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 272e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteSwitchImpl<false, true>(self, code_item, shadow_frame, result_register); 273d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 274e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register); 275d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 2768ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } else { 2778ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz DCHECK_EQ(kInterpreterImplKind, kComputedGotoImplKind); 278d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 279e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteGotoImpl<false, true>(self, code_item, shadow_frame, result_register); 280d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 281e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteGotoImpl<false, false>(self, code_item, shadow_frame, result_register); 282d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 2838ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } 284233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } else { 285233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz // Enter the "with access check" interpreter. 2868ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz if (kInterpreterImplKind == kSwitchImpl) { 287d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 288e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteSwitchImpl<true, true>(self, code_item, shadow_frame, result_register); 289d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 290e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteSwitchImpl<true, false>(self, code_item, shadow_frame, result_register); 291d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 2928ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } else { 2938ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz DCHECK_EQ(kInterpreterImplKind, kComputedGotoImplKind); 294d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 295e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteGotoImpl<true, true>(self, code_item, shadow_frame, result_register); 296d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 297e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteGotoImpl<true, false>(self, code_item, shadow_frame, result_register); 298d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 2998ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } 300233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } 301233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz} 302233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 303ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receiver, 3046474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao uint32_t* args, JValue* result) { 30564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers DCHECK_EQ(self, Thread::Current()); 306535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 307535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 308d752132c73072084a3def9257cca4fcee76047b6jeffhao ThrowStackOverflowError(self); 309d752132c73072084a3def9257cca4fcee76047b6jeffhao return; 310d752132c73072084a3def9257cca4fcee76047b6jeffhao } 311d752132c73072084a3def9257cca4fcee76047b6jeffhao 312e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier const char* old_cause = self->StartAssertNoThreadSuspension("EnterInterpreterFromInvoke"); 313bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const DexFile::CodeItem* code_item = method->GetCodeItem(); 3142fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers uint16_t num_regs; 3152fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers uint16_t num_ins; 3162cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (code_item != nullptr) { 3172fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_regs = code_item->registers_size_; 3182fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_ins = code_item->ins_size_; 3190a9bb73c70298922ad33d67c209a4e440b216fa2jeffhao } else if (method->IsAbstract()) { 320e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->EndAssertNoThreadSuspension(old_cause); 32156adf601ed9d1d11a2c462caa262e7de66a9e172Sebastien Hertz ThrowAbstractMethodError(method); 3220a9bb73c70298922ad33d67c209a4e440b216fa2jeffhao return; 3232fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 3242fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers DCHECK(method->IsNative()); 325bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier num_regs = num_ins = ArtMethod::NumArgRegisters(method->GetShorty()); 3262fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (!method->IsStatic()) { 3272fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_regs++; 3282fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_ins++; 3292fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3302fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3312fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers // Set up shadow frame with matching number of reference slots to vregs. 3322fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame(); 3336613519990bdb5616f2858c146f162ef760f03d2Jeff Hao void* memory = alloca(ShadowFrame::ComputeSize(num_regs)); 3346613519990bdb5616f2858c146f162ef760f03d2Jeff Hao ShadowFrame* shadow_frame(ShadowFrame::Create(num_regs, last_shadow_frame, method, 0, memory)); 3356613519990bdb5616f2858c146f162ef760f03d2Jeff Hao self->PushShadowFrame(shadow_frame); 336e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier 3372fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers size_t cur_reg = num_regs - num_ins; 3382fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (!method->IsStatic()) { 3392cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(receiver != nullptr); 340ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa shadow_frame->SetVRegReference(cur_reg, receiver); 3412fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ++cur_reg; 3422fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 343bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier uint32_t shorty_len = 0; 344bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const char* shorty = method->GetShorty(&shorty_len); 3455d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) { 346bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier DCHECK_LT(shorty_pos + 1, shorty_len); 3475d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao switch (shorty[shorty_pos + 1]) { 3482fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers case 'L': { 349ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Object* o = reinterpret_cast<StackReference<Object>*>(&args[arg_pos])->AsMirrorPtr(); 350ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa shadow_frame->SetVRegReference(cur_reg, o); 3512fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 3522fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3535d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao case 'J': case 'D': { 3545d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao uint64_t wide_value = (static_cast<uint64_t>(args[arg_pos + 1]) << 32) | args[arg_pos]; 3555d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao shadow_frame->SetVRegLong(cur_reg, wide_value); 3562fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers cur_reg++; 3575d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_pos++; 3582fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 3595d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } 3602fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers default: 3615d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao shadow_frame->SetVReg(cur_reg, args[arg_pos]); 3622fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 3632fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3642fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 36592246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier self->EndAssertNoThreadSuspension(old_cause); 36692246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier // Do this after populating the shadow frame in case EnsureInitialized causes a GC. 3676c5cb212fa7010ae7caf9dc765533aa967c95342Ian Rogers if (method->IsStatic() && UNLIKELY(!method->GetDeclaringClass()->IsInitialized())) { 36892246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 369eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier StackHandleScope<1> hs(self); 370eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass())); 3717b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers if (UNLIKELY(!class_linker->EnsureInitialized(self, h_class, true, true))) { 37292246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier CHECK(self->IsExceptionPending()); 37392246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier self->PopShadowFrame(); 37492246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier return; 37592246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier } 37692246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier } 37764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (LIKELY(!method->IsNative())) { 378e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers JValue r = Execute(self, code_item, *shadow_frame, JValue()); 3792cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (result != nullptr) { 3806474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao *result = r; 3812fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3822fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 38364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 38464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // generated stub) except during testing and image writing. 38592246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier // Update args to be the args in the shadow frame since the input ones could hold stale 38692246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier // references pointers due to moving GC. 38792246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1); 38864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!Runtime::Current()->IsStarted()) { 389799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedRuntime::Jni(self, method, receiver, args, result); 3902fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 3916474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao InterpreterJni(self, method, shorty, receiver, args, result); 3922fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3932fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3942fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers self->PopShadowFrame(); 3952fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} 3962fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 39762d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogersvoid EnterInterpreterFromDeoptimize(Thread* self, ShadowFrame* shadow_frame, JValue* ret_val) 39890443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 39911ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao JValue value; 4002cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Set value to last known result in case the shadow frame chain is empty. 4012cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier value.SetJ(ret_val->GetJ()); 402520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // Are we executing the first shadow frame? 403520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz bool first = true; 4042cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier while (shadow_frame != nullptr) { 40562d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->SetTopOfShadowStack(shadow_frame); 406e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers const DexFile::CodeItem* code_item = shadow_frame->GetMethod()->GetCodeItem(); 407270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz const uint32_t dex_pc = shadow_frame->GetDexPC(); 408270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz uint32_t new_dex_pc; 409270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz if (UNLIKELY(self->IsExceptionPending())) { 410520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // If we deoptimize from the QuickExceptionHandler, we already reported the exception to 411520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // the instrumentation. To prevent from reporting it a second time, we simply pass a 412520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // null Instrumentation*. 413270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz const instrumentation::Instrumentation* const instrumentation = 414520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz first ? nullptr : Runtime::Current()->GetInstrumentation(); 415270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz uint32_t found_dex_pc = FindNextInstructionFollowingException(self, *shadow_frame, dex_pc, 416270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz instrumentation); 417270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz new_dex_pc = found_dex_pc; // the dex pc of a matching catch handler 418270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz // or DexFile::kDexNoIndex if there is none. 419270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz } else { 420270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz const Instruction* instr = Instruction::At(&code_item->insns_[dex_pc]); 421d43b3ac88cd46b8815890188c9c2b9a3f1564648Mingyao Yang // For an invoke, use the dex pc of the next instruction. 422d43b3ac88cd46b8815890188c9c2b9a3f1564648Mingyao Yang // TODO: should be tested more once b/17586779 is fixed. 423d43b3ac88cd46b8815890188c9c2b9a3f1564648Mingyao Yang new_dex_pc = dex_pc + (instr->IsInvoke() ? instr->SizeInCodeUnits() : 0); 424270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz } 425270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz if (new_dex_pc != DexFile::kDexNoIndex) { 426270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz shadow_frame->SetDexPC(new_dex_pc); 427270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz value = Execute(self, code_item, *shadow_frame, value); 428270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz } 42911ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao ShadowFrame* old_frame = shadow_frame; 43011ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao shadow_frame = shadow_frame->GetLink(); 431241a9588c6d7d0fcb4c92da40c7141863930083aChristopher Ferris ShadowFrame::DeleteDeoptimizedFrame(old_frame); 432520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz first = false; 43311ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao } 43411ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao ret_val->SetJ(value.GetJ()); 43511ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao} 43611ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao 437e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue EnterInterpreterFromEntryPoint(Thread* self, const DexFile::CodeItem* code_item, 4386f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers ShadowFrame* shadow_frame) { 439f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers DCHECK_EQ(self, Thread::Current()); 440535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 441535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 442f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers ThrowStackOverflowError(self); 443f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers return JValue(); 444f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers } 445f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers 446e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return Execute(self, code_item, *shadow_frame, JValue()); 4477db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers} 4487db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers 449e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogersextern "C" void artInterpreterToInterpreterBridge(Thread* self, const DexFile::CodeItem* code_item, 450848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers ShadowFrame* shadow_frame, JValue* result) { 451535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 452535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 453167436311a08a65dea28dda079a137893821c9c7Jeff Hao ThrowStackOverflowError(self); 4546951067ee14754454e17221fdef0d3d5ed7c4f7eJeff Hao return; 455167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 456167436311a08a65dea28dda079a137893821c9c7Jeff Hao 457e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->PushShadowFrame(shadow_frame); 458c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz // Ensure static methods are initialized. 459e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers const bool is_static = shadow_frame->GetMethod()->IsStatic(); 460e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers if (is_static) { 461e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers mirror::Class* declaring_class = shadow_frame->GetMethod()->GetDeclaringClass(); 4626c5cb212fa7010ae7caf9dc765533aa967c95342Ian Rogers if (UNLIKELY(!declaring_class->IsInitialized())) { 4630cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier StackHandleScope<1> hs(self); 4640cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier HandleWrapper<Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class)); 4650cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized( 4667b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers self, h_declaring_class, true, true))) { 4670cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier DCHECK(self->IsExceptionPending()); 468e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->PopShadowFrame(); 469c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz return; 470c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz } 4710cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier CHECK(h_declaring_class->IsInitializing()); 472167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 473167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 474167436311a08a65dea28dda079a137893821c9c7Jeff Hao 475e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers if (LIKELY(!shadow_frame->GetMethod()->IsNative())) { 476e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers result->SetJ(Execute(self, code_item, *shadow_frame, JValue()).GetJ()); 477167436311a08a65dea28dda079a137893821c9c7Jeff Hao } else { 478167436311a08a65dea28dda079a137893821c9c7Jeff Hao // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 479167436311a08a65dea28dda079a137893821c9c7Jeff Hao // generated stub) except during testing and image writing. 480167436311a08a65dea28dda079a137893821c9c7Jeff Hao CHECK(!Runtime::Current()->IsStarted()); 481e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers Object* receiver = is_static ? nullptr : shadow_frame->GetVRegReference(0); 482e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers uint32_t* args = shadow_frame->GetVRegArgs(is_static ? 0 : 1); 483799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedRuntime::Jni(self, shadow_frame->GetMethod(), receiver, args, result); 484167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 485167436311a08a65dea28dda079a137893821c9c7Jeff Hao 486167436311a08a65dea28dda079a137893821c9c7Jeff Hao self->PopShadowFrame(); 487167436311a08a65dea28dda079a137893821c9c7Jeff Hao} 488167436311a08a65dea28dda079a137893821c9c7Jeff Hao 4892fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} // namespace interpreter 4902fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} // namespace art 491