interpreter.cc revision ef41db7a3f322a1feb305fdb457410c4cea94d00
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 173cfa4d05afa76e19ca99ec964b535a15c73683f0Andreas Gampe#include "interpreter.h" 18b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 19d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz#include <limits> 202dd0e2cea360bc9206eb88ecc40d259e796c239dIan Rogers 21103992b9171fac9eceb2fe4015ab04f544b9c559Andreas Gampe#include "common_throws.h" 223cfa4d05afa76e19ca99ec964b535a15c73683f0Andreas Gampe#include "interpreter_common.h" 235e26eb1dc8ea89b2ebf4ce4b40cbe18542758fbdAndreas Gampe#include "interpreter_mterp_impl.h" 245e26eb1dc8ea89b2ebf4ce4b40cbe18542758fbdAndreas Gampe#include "interpreter_switch_impl.h" 2528bd2e4f151267b34b8e1eb19c489d8d547bbf5cMathieu Chartier#include "jvalue-inl.h" 26b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers#include "mirror/string-inl.h" 270795f23920ee9aabf28e45c63cd592dcccf00216Mathieu Chartier#include "scoped_thread_state_change-inl.h" 282969bcdcd80624e4a4fef696b54c2c76b44b6853Andreas Gampe#include "ScopedLocalRef.h" 29b30259251b22430fad12f1adeab671e4bf8f88f5Andreas Gampe#include "stack.h" 302969bcdcd80624e4a4fef696b54c2c76b44b6853Andreas Gampe#include "unstarted_runtime.h" 311452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee#include "mterp/mterp.h" 32734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee#include "jit/jit.h" 33dd5e5e975e1965c3e4568143e8e1c7b65b319f58Tamas Berghammer#include "jit/jit_code_cache.h" 34b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 352fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogersnamespace art { 362fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogersnamespace interpreter { 372fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 38ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu ChartierALWAYS_INLINE static ObjPtr<mirror::Object> ObjArg(uint32_t arg) 39ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier REQUIRES_SHARED(Locks::mutator_lock_) { 40ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier return ObjPtr<mirror::Object>(reinterpret_cast<mirror::Object*>(arg)); 41ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier} 42ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier 43ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartierstatic void InterpreterJni(Thread* self, 44ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier ArtMethod* method, 45ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier const StringPiece& shorty, 46ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier ObjPtr<mirror::Object> receiver, 47ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier uint32_t* args, 48ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier JValue* result) 49bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 5064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler, 5164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // it should be removed and JNI compiled stubs used instead. 5264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedObjectAccessUnchecked soa(self); 5364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (method->IsStatic()) { 5464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (shorty == "L") { 55460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (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())); 59556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 60556d637764b71563030c479bc35364a75188d559Ian Rogers { 61556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 62556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), klass.get()); 63556d637764b71563030c479bc35364a75188d559Ian Rogers } 64ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier result->SetL(soa.Decode<mirror::Object>(jresult)); 6564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "V") { 66460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass); 672d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 6864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 6964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 7064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 7164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers fn(soa.Env(), klass.get()); 7264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "Z") { 73460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass); 742d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 7564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 7664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 7764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 7864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetZ(fn(soa.Env(), klass.get())); 7964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "BI") { 80460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jbyte (fntype)(JNIEnv*, jclass, jint); 812d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 8264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 8364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 8464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 855d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetB(fn(soa.Env(), klass.get(), args[0])); 8664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "II") { 87460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jint); 882d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 8964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 9064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 9164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 925d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), args[0])); 9364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "LL") { 94460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jclass, jobject); 952d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 9664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 9764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 9864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 99ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier soa.AddLocalReference<jobject>(ObjArg(args[0]))); 100556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 101556d637764b71563030c479bc35364a75188d559Ian Rogers { 102556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 103556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), klass.get(), arg0.get()); 104556d637764b71563030c479bc35364a75188d559Ian Rogers } 105ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier result->SetL(soa.Decode<mirror::Object>(jresult)); 10664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "IIZ") { 107460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jint, jboolean); 1082d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 10964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 11064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 11164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1125d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), args[0], args[1])); 11364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ILI") { 114460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jobject, jint); 1152d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>( 1162d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier method->GetEntryPointFromJni())); 11764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 11864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 11964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 120ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier soa.AddLocalReference<jobject>(ObjArg(args[0]))); 12164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1225d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1])); 12364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "SIZ") { 124460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jshort (fntype)(JNIEnv*, jclass, jint, jboolean); 1252cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier fntype* const fn = 1262cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<fntype*>(const_cast<void*>(method->GetEntryPointFromJni())); 12764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 12864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 12964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1305d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetS(fn(soa.Env(), klass.get(), args[0], args[1])); 13164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VIZ") { 132460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jint, jboolean); 1332d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 13464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 13564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 13664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1375d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), args[0], args[1]); 13864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ZLL") { 139460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass, jobject, jobject); 1402d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 14164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 14264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 14364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 144ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier soa.AddLocalReference<jobject>(ObjArg(args[0]))); 14564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 146ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier soa.AddLocalReference<jobject>(ObjArg(args[1]))); 14764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 14864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get())); 14964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ZILL") { 150460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass, jint, jobject, jobject); 1512d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 15264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 15364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 15464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 155ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier soa.AddLocalReference<jobject>(ObjArg(args[1]))); 15664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg2(soa.Env(), 157ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier soa.AddLocalReference<jobject>(ObjArg(args[2]))); 15864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1595d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetZ(fn(soa.Env(), klass.get(), args[0], arg1.get(), arg2.get())); 16064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VILII") { 161460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jint, jobject, jint, jint); 1622d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 16364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 16464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 16564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 166ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier soa.AddLocalReference<jobject>(ObjArg(args[1]))); 16764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1685d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), args[0], arg1.get(), args[2], args[3]); 16964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VLILII") { 170460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint); 1712d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 17264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 17364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 17464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 175ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier soa.AddLocalReference<jobject>(ObjArg(args[0]))); 17664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg2(soa.Env(), 177ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier soa.AddLocalReference<jobject>(ObjArg(args[2]))); 17864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1795d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), arg0.get(), args[1], arg2.get(), args[3], args[4]); 18064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 181709b070044354d9f47641f273edacaeeb0240ab7David Sehr LOG(FATAL) << "Do something with static native method: " << method->PrettyMethod() 18264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers << " shorty: " << shorty; 18364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 18464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 18564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (shorty == "L") { 186460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jobject); 1872d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 18864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 18964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 190556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 191556d637764b71563030c479bc35364a75188d559Ian Rogers { 192556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 193556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), rcvr.get()); 194556d637764b71563030c479bc35364a75188d559Ian Rogers } 195ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier result->SetL(soa.Decode<mirror::Object>(jresult)); 1963dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao } else if (shorty == "V") { 197460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jobject); 1982d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 1993dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao ScopedLocalRef<jobject> rcvr(soa.Env(), 2003dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao soa.AddLocalReference<jobject>(receiver)); 2013dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao ScopedThreadStateChange tsc(self, kNative); 2023dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao fn(soa.Env(), rcvr.get()); 20364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "LL") { 204460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jobject, jobject); 2052d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 20664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 20764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 20864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 209ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier soa.AddLocalReference<jobject>(ObjArg(args[0]))); 210556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 211556d637764b71563030c479bc35364a75188d559Ian Rogers { 212556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 213556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), rcvr.get(), arg0.get()); 214556d637764b71563030c479bc35364a75188d559Ian Rogers } 215ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier result->SetL(soa.Decode<mirror::Object>(jresult)); 21664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 21764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "III") { 218460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jobject, jint, jint); 2192d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 22064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 22164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 22264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2235d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), rcvr.get(), args[0], args[1])); 22464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 225709b070044354d9f47641f273edacaeeb0240ab7David Sehr LOG(FATAL) << "Do something with native method: " << method->PrettyMethod() 22664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers << " shorty: " << shorty; 22764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 22864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 22964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers} 23064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 2318ece050d85fc244c72610244e440b0e00aa618faSebastien Hertzenum InterpreterImplKind { 2321452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee kSwitchImplKind, // Switch-based interpreter implementation. 2331452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee kMterpImplKind // Assembly interpreter 2348ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz}; 235277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampestatic std::ostream& operator<<(std::ostream& os, const InterpreterImplKind& rhs) { 2361452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee os << ((rhs == kSwitchImplKind) 2371452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee ? "Switch-based interpreter" 238f61df9b450f8734b84584671ad22fa4f29d386e4buzbee : "Asm interpreter"); 2396a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers return os; 2406a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers} 241fa46d3ee8cba2985c5c8bdfe47d15daf0613ebdcIan Rogers 2421452bee8f06b9f76a333ddf4760e4beaa82f8099buzbeestatic constexpr InterpreterImplKind kInterpreterImplKind = kMterpImplKind; 24300b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze 2440122320f86ae004aa195d76814c52564d84ee632Aart Bikstatic inline JValue Execute( 2450122320f86ae004aa195d76814c52564d84ee632Aart Bik Thread* self, 2460122320f86ae004aa195d76814c52564d84ee632Aart Bik const DexFile::CodeItem* code_item, 2470122320f86ae004aa195d76814c52564d84ee632Aart Bik ShadowFrame& shadow_frame, 2480122320f86ae004aa195d76814c52564d84ee632Aart Bik JValue result_register, 249bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe bool stay_in_interpreter = false) REQUIRES_SHARED(Locks::mutator_lock_) { 2501452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee DCHECK(!shadow_frame.GetMethod()->IsAbstract()); 251848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers DCHECK(!shadow_frame.GetMethod()->IsNative()); 252734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee if (LIKELY(shadow_frame.GetDexPC() == 0)) { // Entering the method, but not via deoptimization. 253734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee if (kIsDebugBuild) { 254734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee self->AssertNoPendingException(); 255734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee } 256734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 257734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee ArtMethod *method = shadow_frame.GetMethod(); 258734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee 259734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee if (UNLIKELY(instrumentation->HasMethodEntryListeners())) { 260734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), 261734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee method, 0); 262734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee } 263734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee 2640122320f86ae004aa195d76814c52564d84ee632Aart Bik if (!stay_in_interpreter) { 2650122320f86ae004aa195d76814c52564d84ee632Aart Bik jit::Jit* jit = Runtime::Current()->GetJit(); 2660122320f86ae004aa195d76814c52564d84ee632Aart Bik if (jit != nullptr) { 2670122320f86ae004aa195d76814c52564d84ee632Aart Bik jit->MethodEntered(self, shadow_frame.GetMethod()); 2680122320f86ae004aa195d76814c52564d84ee632Aart Bik if (jit->CanInvokeCompiledCode(method)) { 2690122320f86ae004aa195d76814c52564d84ee632Aart Bik JValue result; 270734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee 2710122320f86ae004aa195d76814c52564d84ee632Aart Bik // Pop the shadow frame before calling into compiled code. 2720122320f86ae004aa195d76814c52564d84ee632Aart Bik self->PopShadowFrame(); 2730122320f86ae004aa195d76814c52564d84ee632Aart Bik ArtInterpreterToCompiledCodeBridge(self, nullptr, code_item, &shadow_frame, &result); 2740122320f86ae004aa195d76814c52564d84ee632Aart Bik // Push the shadow frame back as the caller will expect it. 2750122320f86ae004aa195d76814c52564d84ee632Aart Bik self->PushShadowFrame(&shadow_frame); 276734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee 2770122320f86ae004aa195d76814c52564d84ee632Aart Bik return result; 2780122320f86ae004aa195d76814c52564d84ee632Aart Bik } 279274fe4adcb0610a9920be7814d9beb9cac6417ceNicolas Geoffray } 280734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee } 281734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee } 282734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee 2834e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz shadow_frame.GetMethod()->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self); 2848ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz 28556fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe // Lock counting is a special version of accessibility checks, and for simplicity and 28656fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe // reduction of template parameters, we gate it behind access-checks mode. 28756fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe ArtMethod* method = shadow_frame.GetMethod(); 28856fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe DCHECK(!method->SkipAccessChecks() || !method->MustCountLocks()); 28956fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe 290d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz bool transaction_active = Runtime::Current()->IsActiveTransaction(); 29156fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe if (LIKELY(method->SkipAccessChecks())) { 292233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz // Enter the "without access check" interpreter. 2931452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee if (kInterpreterImplKind == kMterpImplKind) { 294d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 2951452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee // No Mterp variant - just use the switch interpreter. 2961452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<false, true>(self, code_item, shadow_frame, result_register, 2971452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 298fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee } else if (UNLIKELY(!Runtime::Current()->IsStarted())) { 299fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register, 300fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee false); 301d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 3021452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee while (true) { 303fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee // Mterp does not support all instrumentation/debugging. 3046740997e6934bbca27d5830a32352d82aabbd38bAndreas Gampe if (MterpShouldSwitchInterpreters() != 0) { 3051452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register, 3061452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 3071452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } 3081452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee bool returned = ExecuteMterpImpl(self, code_item, &shadow_frame, &result_register); 3091452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee if (returned) { 3101452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return result_register; 3111452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } else { 3121452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee // Mterp didn't like that instruction. Single-step it with the reference interpreter. 313d6b48dbe715fbf1431394d2b6ef75cb19a4012ddbuzbee result_register = ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, 314ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier result_register, true); 3151452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee if (shadow_frame.GetDexPC() == DexFile::kDexNoIndex) { 3161452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee // Single-stepped a return or an exception not handled locally. Return to caller. 317d6b48dbe715fbf1431394d2b6ef75cb19a4012ddbuzbee return result_register; 3181452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } 3191452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } 3201452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } 3211452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } 322f61df9b450f8734b84584671ad22fa4f29d386e4buzbee } else { 323f61df9b450f8734b84584671ad22fa4f29d386e4buzbee DCHECK_EQ(kInterpreterImplKind, kSwitchImplKind); 3241452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee if (transaction_active) { 3251452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<false, true>(self, code_item, shadow_frame, result_register, 3261452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 3271452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } else { 3281452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register, 3291452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 330d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3318ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } 332233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } else { 333233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz // Enter the "with access check" interpreter. 3341452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee if (kInterpreterImplKind == kMterpImplKind) { 3351452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee // No access check variants for Mterp. Just use the switch version. 3361452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee if (transaction_active) { 3371452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<true, true>(self, code_item, shadow_frame, result_register, 3381452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 3391452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } else { 3401452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<true, false>(self, code_item, shadow_frame, result_register, 3411452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 3421452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } 343f61df9b450f8734b84584671ad22fa4f29d386e4buzbee } else { 344f61df9b450f8734b84584671ad22fa4f29d386e4buzbee DCHECK_EQ(kInterpreterImplKind, kSwitchImplKind); 345d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 3461452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<true, true>(self, code_item, shadow_frame, result_register, 3471452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 348d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 3491452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<true, false>(self, code_item, shadow_frame, result_register, 3501452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 351d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3528ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } 353233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } 354233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz} 355233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 356ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartiervoid EnterInterpreterFromInvoke(Thread* self, 357ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier ArtMethod* method, 358ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier ObjPtr<mirror::Object> receiver, 359ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier uint32_t* args, 360ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier JValue* result, 3610122320f86ae004aa195d76814c52564d84ee632Aart Bik bool stay_in_interpreter) { 36264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers DCHECK_EQ(self, Thread::Current()); 363535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 364535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 365d752132c73072084a3def9257cca4fcee76047b6jeffhao ThrowStackOverflowError(self); 366d752132c73072084a3def9257cca4fcee76047b6jeffhao return; 367d752132c73072084a3def9257cca4fcee76047b6jeffhao } 368d752132c73072084a3def9257cca4fcee76047b6jeffhao 369e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier const char* old_cause = self->StartAssertNoThreadSuspension("EnterInterpreterFromInvoke"); 370bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const DexFile::CodeItem* code_item = method->GetCodeItem(); 3712fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers uint16_t num_regs; 3722fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers uint16_t num_ins; 3732cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (code_item != nullptr) { 3742fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_regs = code_item->registers_size_; 3752fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_ins = code_item->ins_size_; 3769139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light } else if (!method->IsInvokable()) { 377e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->EndAssertNoThreadSuspension(old_cause); 3789139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light method->ThrowInvocationTimeError(); 3790a9bb73c70298922ad33d67c209a4e440b216fa2jeffhao return; 3802fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 3812fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers DCHECK(method->IsNative()); 382bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier num_regs = num_ins = ArtMethod::NumArgRegisters(method->GetShorty()); 3832fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (!method->IsStatic()) { 3842fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_regs++; 3852fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_ins++; 3862fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3872fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 3882fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers // Set up shadow frame with matching number of reference slots to vregs. 3892fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame(); 390b30259251b22430fad12f1adeab671e4bf8f88f5Andreas Gampe ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr = 39103ec930faded5bbfa096533ce60b6893847922dbAndreas Gampe CREATE_SHADOW_FRAME(num_regs, last_shadow_frame, method, /* dex pc */ 0); 392b30259251b22430fad12f1adeab671e4bf8f88f5Andreas Gampe ShadowFrame* shadow_frame = shadow_frame_unique_ptr.get(); 3936613519990bdb5616f2858c146f162ef760f03d2Jeff Hao self->PushShadowFrame(shadow_frame); 394e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier 3952fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers size_t cur_reg = num_regs - num_ins; 3962fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (!method->IsStatic()) { 3972cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(receiver != nullptr); 398ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier shadow_frame->SetVRegReference(cur_reg, receiver.Ptr()); 3992fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ++cur_reg; 4002fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 401bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier uint32_t shorty_len = 0; 402bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const char* shorty = method->GetShorty(&shorty_len); 4035d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) { 404bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier DCHECK_LT(shorty_pos + 1, shorty_len); 4055d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao switch (shorty[shorty_pos + 1]) { 4062fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers case 'L': { 407ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier ObjPtr<mirror::Object> o = 408ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier reinterpret_cast<StackReference<mirror::Object>*>(&args[arg_pos])->AsMirrorPtr(); 409ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier shadow_frame->SetVRegReference(cur_reg, o.Ptr()); 4102fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 4112fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4125d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao case 'J': case 'D': { 4135d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao uint64_t wide_value = (static_cast<uint64_t>(args[arg_pos + 1]) << 32) | args[arg_pos]; 4145d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao shadow_frame->SetVRegLong(cur_reg, wide_value); 4152fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers cur_reg++; 4165d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_pos++; 4172fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 4185d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } 4192fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers default: 4205d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao shadow_frame->SetVReg(cur_reg, args[arg_pos]); 4212fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 4222fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4232fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 42492246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier self->EndAssertNoThreadSuspension(old_cause); 42592246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier // Do this after populating the shadow frame in case EnsureInitialized causes a GC. 4266c5cb212fa7010ae7caf9dc765533aa967c95342Ian Rogers if (method->IsStatic() && UNLIKELY(!method->GetDeclaringClass()->IsInitialized())) { 42792246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 428eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier StackHandleScope<1> hs(self); 429eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass())); 4307b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers if (UNLIKELY(!class_linker->EnsureInitialized(self, h_class, true, true))) { 43192246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier CHECK(self->IsExceptionPending()); 43292246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier self->PopShadowFrame(); 43392246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier return; 43492246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier } 43592246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier } 43664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (LIKELY(!method->IsNative())) { 4370122320f86ae004aa195d76814c52564d84ee632Aart Bik JValue r = Execute(self, code_item, *shadow_frame, JValue(), stay_in_interpreter); 4382cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (result != nullptr) { 4396474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao *result = r; 4402fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4412fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 44264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 44364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // generated stub) except during testing and image writing. 44492246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier // Update args to be the args in the shadow frame since the input ones could hold stale 44592246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier // references pointers due to moving GC. 44692246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1); 44764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!Runtime::Current()->IsStarted()) { 448ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier UnstartedRuntime::Jni(self, method, receiver.Ptr(), args, result); 4492fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 4506474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao InterpreterJni(self, method, shorty, receiver, args, result); 4512fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4522fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4532fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers self->PopShadowFrame(); 4542fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} 4552fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 456ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yangstatic bool IsStringInit(const Instruction* instr, ArtMethod* caller) 457bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 458ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang if (instr->Opcode() == Instruction::INVOKE_DIRECT || 459ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang instr->Opcode() == Instruction::INVOKE_DIRECT_RANGE) { 460ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang // Instead of calling ResolveMethod() which has suspend point and can trigger 461ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang // GC, look up the callee method symbolically. 462ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang uint16_t callee_method_idx = (instr->Opcode() == Instruction::INVOKE_DIRECT_RANGE) ? 463ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang instr->VRegB_3rc() : instr->VRegB_35c(); 464ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang const DexFile* dex_file = caller->GetDexFile(); 465ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang const DexFile::MethodId& method_id = dex_file->GetMethodId(callee_method_idx); 466ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang const char* class_name = dex_file->StringByTypeIdx(method_id.class_idx_); 467ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang const char* method_name = dex_file->GetMethodName(method_id); 468ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang // Compare method's class name and method name against string init. 469ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang // It's ok since it's not allowed to create your own java/lang/String. 470ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang // TODO: verify that assumption. 471ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang if ((strcmp(class_name, "Ljava/lang/String;") == 0) && 472ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang (strcmp(method_name, "<init>") == 0)) { 473ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang return true; 474ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang } 475ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang } 476ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang return false; 477ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang} 478ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang 479ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yangstatic int16_t GetReceiverRegisterForStringInit(const Instruction* instr) { 480ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang DCHECK(instr->Opcode() == Instruction::INVOKE_DIRECT_RANGE || 481ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang instr->Opcode() == Instruction::INVOKE_DIRECT); 482ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang return (instr->Opcode() == Instruction::INVOKE_DIRECT_RANGE) ? 483ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang instr->VRegC_3rc() : instr->VRegC_35c(); 484ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang} 485ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang 48673be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffrayvoid EnterInterpreterFromDeoptimize(Thread* self, 48773be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray ShadowFrame* shadow_frame, 48873be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray bool from_code, 48973be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray JValue* ret_val) 490bdf7f1c3ab65ccb70f62db5ab31dba060632d458Andreas Gampe REQUIRES_SHARED(Locks::mutator_lock_) { 49111ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao JValue value; 4922cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Set value to last known result in case the shadow frame chain is empty. 4932cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier value.SetJ(ret_val->GetJ()); 494520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // Are we executing the first shadow frame? 495520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz bool first = true; 4962cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier while (shadow_frame != nullptr) { 49756fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe // We do not want to recover lock state for lock counting when deoptimizing. Currently, 49856fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe // the compiler should not have compiled a method that failed structured-locking checks. 49956fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe DCHECK(!shadow_frame->GetMethod()->MustCountLocks()); 50056fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe 50162d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->SetTopOfShadowStack(shadow_frame); 502e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers const DexFile::CodeItem* code_item = shadow_frame->GetMethod()->GetCodeItem(); 503270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz const uint32_t dex_pc = shadow_frame->GetDexPC(); 50473be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray uint32_t new_dex_pc = dex_pc; 505270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz if (UNLIKELY(self->IsExceptionPending())) { 506520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // If we deoptimize from the QuickExceptionHandler, we already reported the exception to 507520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // the instrumentation. To prevent from reporting it a second time, we simply pass a 508520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // null Instrumentation*. 509270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz const instrumentation::Instrumentation* const instrumentation = 510520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz first ? nullptr : Runtime::Current()->GetInstrumentation(); 511270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz uint32_t found_dex_pc = FindNextInstructionFollowingException(self, *shadow_frame, dex_pc, 512270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz instrumentation); 513270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz new_dex_pc = found_dex_pc; // the dex pc of a matching catch handler 514270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz // or DexFile::kDexNoIndex if there is none. 51573be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray } else if (!from_code) { 51673be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray // For the debugger and full deoptimization stack, we must go past the invoke 51773be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray // instruction, as it already executed. 518d43b3ac88cd46b8815890188c9c2b9a3f1564648Mingyao Yang // TODO: should be tested more once b/17586779 is fixed. 51973be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray const Instruction* instr = Instruction::At(&code_item->insns_[dex_pc]); 520504a69081f63818ca332ddaf54e8198448554538Mingyao Yang if (instr->IsInvoke()) { 521ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang if (IsStringInit(instr, shadow_frame->GetMethod())) { 522ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang uint16_t this_obj_vreg = GetReceiverRegisterForStringInit(instr); 523ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang // Move the StringFactory.newStringFromChars() result into the register representing 524ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang // "this object" when invoking the string constructor in the original dex instruction. 525ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang // Also move the result into all aliases. 526ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang DCHECK(value.GetL()->IsString()); 527ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang SetStringInitValueToAllAliases(shadow_frame, this_obj_vreg, value); 528ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang // Calling string constructor in the original dex code doesn't generate a result value. 529ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang value.SetJ(0); 530ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang } 531504a69081f63818ca332ddaf54e8198448554538Mingyao Yang new_dex_pc = dex_pc + instr->SizeInCodeUnits(); 532504a69081f63818ca332ddaf54e8198448554538Mingyao Yang } else if (instr->Opcode() == Instruction::NEW_INSTANCE) { 533504a69081f63818ca332ddaf54e8198448554538Mingyao Yang // It's possible to deoptimize at a NEW_INSTANCE dex instruciton that's for a 534504a69081f63818ca332ddaf54e8198448554538Mingyao Yang // java string, which is turned into a call into StringFactory.newEmptyString(); 535ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang // Move the StringFactory.newEmptyString() result into the destination register. 536ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang DCHECK(value.GetL()->IsString()); 537ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang shadow_frame->SetVRegReference(instr->VRegA_21c(), value.GetL()); 538ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang // new-instance doesn't generate a result value. 539ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang value.SetJ(0); 540ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang // Skip the dex instruction since we essentially come back from an invocation. 541ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang new_dex_pc = dex_pc + instr->SizeInCodeUnits(); 542504a69081f63818ca332ddaf54e8198448554538Mingyao Yang if (kIsDebugBuild) { 543504a69081f63818ca332ddaf54e8198448554538Mingyao Yang ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 544ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang // This is a suspend point. But it's ok since value has been set into shadow_frame. 545ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier ObjPtr<mirror::Class> klass = class_linker->ResolveType( 546504a69081f63818ca332ddaf54e8198448554538Mingyao Yang instr->VRegB_21c(), shadow_frame->GetMethod()); 547504a69081f63818ca332ddaf54e8198448554538Mingyao Yang DCHECK(klass->IsStringClass()); 548504a69081f63818ca332ddaf54e8198448554538Mingyao Yang } 549504a69081f63818ca332ddaf54e8198448554538Mingyao Yang } else { 550ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang CHECK(false) << "Unexpected instruction opcode " << instr->Opcode() 551ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang << " at dex_pc " << dex_pc 552709b070044354d9f47641f273edacaeeb0240ab7David Sehr << " of method: " << ArtMethod::PrettyMethod(shadow_frame->GetMethod(), false); 553504a69081f63818ca332ddaf54e8198448554538Mingyao Yang } 55473be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray } else { 55573be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray // Nothing to do, the dex_pc is the one at which the code requested 55673be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray // the deoptimization. 557270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz } 558270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz if (new_dex_pc != DexFile::kDexNoIndex) { 559270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz shadow_frame->SetDexPC(new_dex_pc); 560270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz value = Execute(self, code_item, *shadow_frame, value); 561270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz } 56211ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao ShadowFrame* old_frame = shadow_frame; 56311ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao shadow_frame = shadow_frame->GetLink(); 564241a9588c6d7d0fcb4c92da40c7141863930083aChristopher Ferris ShadowFrame::DeleteDeoptimizedFrame(old_frame); 56573be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray // Following deoptimizations of shadow frames must pass the invoke instruction. 56673be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray from_code = false; 567520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz first = false; 56811ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao } 56911ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao ret_val->SetJ(value.GetJ()); 57011ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao} 57111ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao 572e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue EnterInterpreterFromEntryPoint(Thread* self, const DexFile::CodeItem* code_item, 5736f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers ShadowFrame* shadow_frame) { 574f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers DCHECK_EQ(self, Thread::Current()); 575535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 576535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 577f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers ThrowStackOverflowError(self); 578f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers return JValue(); 579f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers } 580f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers 58171cd50fb67fa48667b0ab59aa436a582c04ba43dNicolas Geoffray jit::Jit* jit = Runtime::Current()->GetJit(); 58271cd50fb67fa48667b0ab59aa436a582c04ba43dNicolas Geoffray if (jit != nullptr) { 58371cd50fb67fa48667b0ab59aa436a582c04ba43dNicolas Geoffray jit->NotifyCompiledCodeToInterpreterTransition(self, shadow_frame->GetMethod()); 58471cd50fb67fa48667b0ab59aa436a582c04ba43dNicolas Geoffray } 585e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return Execute(self, code_item, *shadow_frame, JValue()); 5867db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers} 5877db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers 588ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartiervoid ArtInterpreterToInterpreterBridge(Thread* self, 589ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier const DexFile::CodeItem* code_item, 590ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier ShadowFrame* shadow_frame, 591ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier JValue* result) { 592535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 593535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 594167436311a08a65dea28dda079a137893821c9c7Jeff Hao ThrowStackOverflowError(self); 5956951067ee14754454e17221fdef0d3d5ed7c4f7eJeff Hao return; 596167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 597167436311a08a65dea28dda079a137893821c9c7Jeff Hao 598e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->PushShadowFrame(shadow_frame); 599eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light ArtMethod* method = shadow_frame->GetMethod(); 600c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz // Ensure static methods are initialized. 601eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light const bool is_static = method->IsStatic(); 602e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers if (is_static) { 603ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier ObjPtr<mirror::Class> declaring_class = method->GetDeclaringClass(); 6046c5cb212fa7010ae7caf9dc765533aa967c95342Ian Rogers if (UNLIKELY(!declaring_class->IsInitialized())) { 6050cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier StackHandleScope<1> hs(self); 606ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier HandleWrapperObjPtr<mirror::Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class)); 6070cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized( 6087b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers self, h_declaring_class, true, true))) { 6090cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier DCHECK(self->IsExceptionPending()); 610e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->PopShadowFrame(); 611c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz return; 612c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz } 6130cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier CHECK(h_declaring_class->IsInitializing()); 614167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 615167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 616167436311a08a65dea28dda079a137893821c9c7Jeff Hao 617e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers if (LIKELY(!shadow_frame->GetMethod()->IsNative())) { 618e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers result->SetJ(Execute(self, code_item, *shadow_frame, JValue()).GetJ()); 619167436311a08a65dea28dda079a137893821c9c7Jeff Hao } else { 620167436311a08a65dea28dda079a137893821c9c7Jeff Hao // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 621167436311a08a65dea28dda079a137893821c9c7Jeff Hao // generated stub) except during testing and image writing. 622167436311a08a65dea28dda079a137893821c9c7Jeff Hao CHECK(!Runtime::Current()->IsStarted()); 623ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier ObjPtr<mirror::Object> receiver = is_static ? nullptr : shadow_frame->GetVRegReference(0); 624e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers uint32_t* args = shadow_frame->GetVRegArgs(is_static ? 0 : 1); 625ef41db7a3f322a1feb305fdb457410c4cea94d00Mathieu Chartier UnstartedRuntime::Jni(self, shadow_frame->GetMethod(), receiver.Ptr(), args, result); 626167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 627167436311a08a65dea28dda079a137893821c9c7Jeff Hao 628167436311a08a65dea28dda079a137893821c9c7Jeff Hao self->PopShadowFrame(); 629167436311a08a65dea28dda079a137893821c9c7Jeff Hao} 630167436311a08a65dea28dda079a137893821c9c7Jeff Hao 6311452bee8f06b9f76a333ddf4760e4beaa82f8099buzbeevoid CheckInterpreterAsmConstants() { 6321452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee CheckMterpAsmConstants(); 6331452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee} 6341452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee 6351452bee8f06b9f76a333ddf4760e4beaa82f8099buzbeevoid InitInterpreterTls(Thread* self) { 6361452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee InitMterpTls(self); 6371452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee} 6381452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee 6392fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} // namespace interpreter 6402fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} // namespace art 641