interpreter.cc revision dd5e5e975e1965c3e4568143e8e1c7b65b319f58
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" 23b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers#include "mirror/string-inl.h" 242969bcdcd80624e4a4fef696b54c2c76b44b6853Andreas Gampe#include "scoped_thread_state_change.h" 252969bcdcd80624e4a4fef696b54c2c76b44b6853Andreas Gampe#include "ScopedLocalRef.h" 26b30259251b22430fad12f1adeab671e4bf8f88f5Andreas Gampe#include "stack.h" 272969bcdcd80624e4a4fef696b54c2c76b44b6853Andreas Gampe#include "unstarted_runtime.h" 281452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee#include "mterp/mterp.h" 29734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee#include "jit/jit.h" 30dd5e5e975e1965c3e4568143e8e1c7b65b319f58Tamas Berghammer#include "jit/jit_code_cache.h" 31b0fa5dc7769c1e054032f39de0a3f6d6dd06f8cfIan Rogers 322fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogersnamespace art { 332fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogersnamespace interpreter { 342fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 35fc0e94bed3f88ed7e50854fd8dfaf5dcb345250fIan Rogersstatic void InterpreterJni(Thread* self, ArtMethod* method, const StringPiece& shorty, 365d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao Object* receiver, uint32_t* args, JValue* result) 3790443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 3864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // TODO: The following enters JNI code using a typedef-ed function rather than the JNI compiler, 3964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // it should be removed and JNI compiled stubs used instead. 4064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedObjectAccessUnchecked soa(self); 4164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (method->IsStatic()) { 4264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (shorty == "L") { 43460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jclass); 442d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 4564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 4664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 47556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 48556d637764b71563030c479bc35364a75188d559Ian Rogers { 49556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 50556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), klass.get()); 51556d637764b71563030c479bc35364a75188d559Ian Rogers } 52556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 5364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "V") { 54460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass); 552d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 5664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 5764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 5864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 5964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers fn(soa.Env(), klass.get()); 6064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "Z") { 61460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass); 622d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 6364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 6464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 6564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 6664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetZ(fn(soa.Env(), klass.get())); 6764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "BI") { 68460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jbyte (fntype)(JNIEnv*, jclass, jint); 692d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 7064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 7164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 7264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 735d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetB(fn(soa.Env(), klass.get(), args[0])); 7464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "II") { 75460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jint); 762d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 7764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 7864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 7964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 805d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), args[0])); 8164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "LL") { 82460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jclass, jobject); 832d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 8464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 8564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 8664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 872cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 882cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[0]))); 89556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 90556d637764b71563030c479bc35364a75188d559Ian Rogers { 91556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 92556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), klass.get(), arg0.get()); 93556d637764b71563030c479bc35364a75188d559Ian Rogers } 94556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 9564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "IIZ") { 96460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jint, jboolean); 972d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 9864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 9964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 10064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1015d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), args[0], args[1])); 10264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ILI") { 103460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jclass, jobject, jint); 1042d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(const_cast<void*>( 1052d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier method->GetEntryPointFromJni())); 10664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 10764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 10864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 1092cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1102cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[0]))); 11164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1125d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), klass.get(), arg0.get(), args[1])); 11364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "SIZ") { 114460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jshort (fntype)(JNIEnv*, jclass, jint, jboolean); 1152cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier fntype* const fn = 1162cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<fntype*>(const_cast<void*>(method->GetEntryPointFromJni())); 11764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 11864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 11964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1205d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetS(fn(soa.Env(), klass.get(), args[0], args[1])); 12164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VIZ") { 122460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jint, jboolean); 1232d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 12464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 12564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 12664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1275d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), args[0], args[1]); 12864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ZLL") { 129460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass, jobject, jobject); 1302d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 13164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 13264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 13364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 1342cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1352cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[0]))); 13664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 1372cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1382cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[1]))); 13964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 14064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers result->SetZ(fn(soa.Env(), klass.get(), arg0.get(), arg1.get())); 14164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "ZILL") { 142460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jboolean (fntype)(JNIEnv*, jclass, jint, jobject, jobject); 1432d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 14464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 14564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 14664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 1472cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1482cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[1]))); 14964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg2(soa.Env(), 1502cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1512cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[2]))); 15264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1535d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetZ(fn(soa.Env(), klass.get(), args[0], arg1.get(), arg2.get())); 15464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VILII") { 155460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jint, jobject, jint, jint); 1562d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 15764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 15864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 15964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg1(soa.Env(), 1602cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1612cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[1]))); 16264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1635d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), args[0], arg1.get(), args[2], args[3]); 16464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "VLILII") { 165460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jclass, jobject, jint, jobject, jint, jint); 1662d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 16764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jclass> klass(soa.Env(), 16864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jclass>(method->GetDeclaringClass())); 16964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 1702cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1712cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[0]))); 17264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg2(soa.Env(), 1732cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 1742cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[2]))); 17564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 1765d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao fn(soa.Env(), klass.get(), arg0.get(), args[1], arg2.get(), args[3], args[4]); 17764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 17864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers LOG(FATAL) << "Do something with static native method: " << PrettyMethod(method) 17964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers << " shorty: " << shorty; 18064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 18164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 18264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (shorty == "L") { 183460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jobject); 1842d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 18564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 18664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 187556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 188556d637764b71563030c479bc35364a75188d559Ian Rogers { 189556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 190556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), rcvr.get()); 191556d637764b71563030c479bc35364a75188d559Ian Rogers } 192556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 1933dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao } else if (shorty == "V") { 194460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef void (fntype)(JNIEnv*, jobject); 1952d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 1963dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao ScopedLocalRef<jobject> rcvr(soa.Env(), 1973dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao soa.AddLocalReference<jobject>(receiver)); 1983dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao ScopedThreadStateChange tsc(self, kNative); 1993dd9f76ff8fa99be9ff6b18354528c5def7b26f7Jeff Hao fn(soa.Env(), rcvr.get()); 20064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "LL") { 201460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jobject (fntype)(JNIEnv*, jobject, jobject); 2022d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 20364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 20464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 20564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> arg0(soa.Env(), 2062cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier soa.AddLocalReference<jobject>( 2072cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier reinterpret_cast<Object*>(args[0]))); 208556d637764b71563030c479bc35364a75188d559Ian Rogers jobject jresult; 209556d637764b71563030c479bc35364a75188d559Ian Rogers { 210556d637764b71563030c479bc35364a75188d559Ian Rogers ScopedThreadStateChange tsc(self, kNative); 211556d637764b71563030c479bc35364a75188d559Ian Rogers jresult = fn(soa.Env(), rcvr.get(), arg0.get()); 212556d637764b71563030c479bc35364a75188d559Ian Rogers } 213556d637764b71563030c479bc35364a75188d559Ian Rogers result->SetL(soa.Decode<Object*>(jresult)); 21464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 21564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else if (shorty == "III") { 216460536209b741bc469f1b0857775449abb2102fbBernhard Rosenkränzer typedef jint (fntype)(JNIEnv*, jobject, jint, jint); 2172d7210188805292e463be4bcf7a133b654d7e0eaMathieu Chartier fntype* const fn = reinterpret_cast<fntype*>(method->GetEntryPointFromJni()); 21864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedLocalRef<jobject> rcvr(soa.Env(), 21964b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers soa.AddLocalReference<jobject>(receiver)); 22064b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers ScopedThreadStateChange tsc(self, kNative); 2215d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao result->SetI(fn(soa.Env(), rcvr.get(), args[0], args[1])); 22264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } else { 22364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers LOG(FATAL) << "Do something with native method: " << PrettyMethod(method) 22464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers << " shorty: " << shorty; 22564b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 22664b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers } 22764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers} 22864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers 2298ece050d85fc244c72610244e440b0e00aa618faSebastien Hertzenum InterpreterImplKind { 2301452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee kSwitchImplKind, // Switch-based interpreter implementation. 2311452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee kComputedGotoImplKind, // Computed-goto-based interpreter implementation. 2321452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee kMterpImplKind // Assembly interpreter 2338ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz}; 234277ccbd200ea43590dfc06a93ae184a765327ad0Andreas Gampestatic std::ostream& operator<<(std::ostream& os, const InterpreterImplKind& rhs) { 2351452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee os << ((rhs == kSwitchImplKind) 2361452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee ? "Switch-based interpreter" 2371452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee : (rhs == kComputedGotoImplKind) 2381452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee ? "Computed-goto-based interpreter" 2391452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee : "Asm interpreter"); 2406a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers return os; 2416a3c1fcb4ba42ad4d5d142c17a3712a6ddd3866fIan Rogers} 242fa46d3ee8cba2985c5c8bdfe47d15daf0613ebdcIan Rogers 243fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz#if !defined(__clang__) 2443b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#if (defined(__arm__) || defined(__i386__) || defined(__aarch64__)) 2451452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee// TODO: remove when all targets implemented. 2461452bee8f06b9f76a333ddf4760e4beaa82f8099buzbeestatic constexpr InterpreterImplKind kInterpreterImplKind = kMterpImplKind; 2471452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee#else 248b48b9eb6d181a1f52e2e605cf26a21505f1d46edIan Rogersstatic constexpr InterpreterImplKind kInterpreterImplKind = kComputedGotoImplKind; 2491452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee#endif 250fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz#else 251fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz// Clang 3.4 fails to build the goto interpreter implementation. 2523b0b4b9d09baae7234fc26b7970b3ec55560735eBill Buzbee#if (defined(__arm__) || defined(__i386__) || defined(__aarch64__)) 2531452bee8f06b9f76a333ddf4760e4beaa82f8099buzbeestatic constexpr InterpreterImplKind kInterpreterImplKind = kMterpImplKind; 2541452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee#else 2551452bee8f06b9f76a333ddf4760e4beaa82f8099buzbeestatic constexpr InterpreterImplKind kInterpreterImplKind = kSwitchImplKind; 2561452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee#endif 257fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertztemplate<bool do_access_check, bool transaction_active> 258e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl(Thread*, const DexFile::CodeItem*, ShadowFrame&, JValue) { 259fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz LOG(FATAL) << "UNREACHABLE"; 2602c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers UNREACHABLE(); 261fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz} 262fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz// Explicit definitions of ExecuteGotoImpl. 26390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartiertemplate<> SHARED_REQUIRES(Locks::mutator_lock_) 264e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item, 265fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz ShadowFrame& shadow_frame, JValue result_register); 26690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartiertemplate<> SHARED_REQUIRES(Locks::mutator_lock_) 267e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item, 268fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz ShadowFrame& shadow_frame, JValue result_register); 26990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartiertemplate<> SHARED_REQUIRES(Locks::mutator_lock_) 270e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<true, true>(Thread* self, const DexFile::CodeItem* code_item, 271e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers ShadowFrame& shadow_frame, JValue result_register); 27290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartiertemplate<> SHARED_REQUIRES(Locks::mutator_lock_) 273e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item, 274e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers ShadowFrame& shadow_frame, JValue result_register); 275fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz#endif 2762fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 277e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogersstatic JValue Execute(Thread* self, const DexFile::CodeItem* code_item, ShadowFrame& shadow_frame, 278e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers JValue result_register) 27990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_); 280233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 281e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogersstatic inline JValue Execute(Thread* self, const DexFile::CodeItem* code_item, 282233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz ShadowFrame& shadow_frame, JValue result_register) { 2831452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee DCHECK(!shadow_frame.GetMethod()->IsAbstract()); 284848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers DCHECK(!shadow_frame.GetMethod()->IsNative()); 285734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee if (LIKELY(shadow_frame.GetDexPC() == 0)) { // Entering the method, but not via deoptimization. 286734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee if (kIsDebugBuild) { 287734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee self->AssertNoPendingException(); 288734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee } 289734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation(); 290734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee ArtMethod *method = shadow_frame.GetMethod(); 291734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee 292734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee if (UNLIKELY(instrumentation->HasMethodEntryListeners())) { 293734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_), 294734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee method, 0); 295734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee } 296734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee 297dd5e5e975e1965c3e4568143e8e1c7b65b319f58Tamas Berghammer jit::Jit* jit = Runtime::Current()->GetJit(); 298dd5e5e975e1965c3e4568143e8e1c7b65b319f58Tamas Berghammer if (UNLIKELY(jit != nullptr && 299dd5e5e975e1965c3e4568143e8e1c7b65b319f58Tamas Berghammer jit->JitAtFirstUse() && 300dd5e5e975e1965c3e4568143e8e1c7b65b319f58Tamas Berghammer jit->GetCodeCache()->ContainsMethod(method))) { 301734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee JValue result; 302734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee 303734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee // Pop the shadow frame before calling into compiled code. 304734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee self->PopShadowFrame(); 305734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee ArtInterpreterToCompiledCodeBridge(self, code_item, &shadow_frame, &result); 306734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee // Push the shadow frame back as the caller will expect it. 307734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee self->PushShadowFrame(&shadow_frame); 308734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee 309734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee return result; 310734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee } 311734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee } 312734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee 3134e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz shadow_frame.GetMethod()->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self); 3148ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz 315d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz bool transaction_active = Runtime::Current()->IsActiveTransaction(); 316df707e406877e9c0426dd051c00933ebb331673eIgor Murashkin if (LIKELY(shadow_frame.GetMethod()->SkipAccessChecks())) { 317233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz // Enter the "without access check" interpreter. 3181452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee if (kInterpreterImplKind == kMterpImplKind) { 319d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 3201452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee // No Mterp variant - just use the switch interpreter. 3211452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<false, true>(self, code_item, shadow_frame, result_register, 3221452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 323d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 3241452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee const instrumentation::Instrumentation* const instrumentation = 3251452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee Runtime::Current()->GetInstrumentation(); 3261452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee while (true) { 3275d03317a834efdf3b5240c401f1bc2ceac7a2f25Nicolas Geoffray if (instrumentation->IsActive() || !Runtime::Current()->IsStarted()) { 3285d03317a834efdf3b5240c401f1bc2ceac7a2f25Nicolas Geoffray // TODO: allow JIT profiling instrumentation. Now, just punt on all instrumentation. 3291452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee#if !defined(__clang__) 3301452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteGotoImpl<false, false>(self, code_item, shadow_frame, result_register); 3311452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee#else 3321452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register, 3331452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 3341452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee#endif 3351452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } 3361452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee bool returned = ExecuteMterpImpl(self, code_item, &shadow_frame, &result_register); 3371452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee if (returned) { 3381452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return result_register; 3391452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } else { 3401452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee // Mterp didn't like that instruction. Single-step it with the reference interpreter. 341d6b48dbe715fbf1431394d2b6ef75cb19a4012ddbuzbee result_register = ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, 3421452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee result_register, true); 3431452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee if (shadow_frame.GetDexPC() == DexFile::kDexNoIndex) { 3441452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee // Single-stepped a return or an exception not handled locally. Return to caller. 345d6b48dbe715fbf1431394d2b6ef75cb19a4012ddbuzbee return result_register; 3461452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } 3471452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } 3481452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } 3491452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } 3501452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } else if (kInterpreterImplKind == kSwitchImplKind) { 3511452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee if (transaction_active) { 3521452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<false, true>(self, code_item, shadow_frame, result_register, 3531452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 3541452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } else { 3551452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register, 3561452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 357d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3588ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } else { 3598ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz DCHECK_EQ(kInterpreterImplKind, kComputedGotoImplKind); 360d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 361e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteGotoImpl<false, true>(self, code_item, shadow_frame, result_register); 362d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 363e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteGotoImpl<false, false>(self, code_item, shadow_frame, result_register); 364d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3658ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } 366233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } else { 367233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz // Enter the "with access check" interpreter. 3681452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee if (kInterpreterImplKind == kMterpImplKind) { 3691452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee // No access check variants for Mterp. Just use the switch version. 3701452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee if (transaction_active) { 3711452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<true, true>(self, code_item, shadow_frame, result_register, 3721452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 3731452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } else { 3741452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<true, false>(self, code_item, shadow_frame, result_register, 3751452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 3761452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } 3771452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee } else if (kInterpreterImplKind == kSwitchImplKind) { 378d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 3791452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<true, true>(self, code_item, shadow_frame, result_register, 3801452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 381d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 3821452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee return ExecuteSwitchImpl<true, false>(self, code_item, shadow_frame, result_register, 3831452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee false); 384d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3858ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } else { 3868ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz DCHECK_EQ(kInterpreterImplKind, kComputedGotoImplKind); 387d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz if (transaction_active) { 388e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteGotoImpl<true, true>(self, code_item, shadow_frame, result_register); 389d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } else { 390e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return ExecuteGotoImpl<true, false>(self, code_item, shadow_frame, result_register); 391d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz } 3928ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz } 393233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz } 394233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz} 395233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz 396ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receiver, 3976474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao uint32_t* args, JValue* result) { 39864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers DCHECK_EQ(self, Thread::Current()); 399535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 400535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 401d752132c73072084a3def9257cca4fcee76047b6jeffhao ThrowStackOverflowError(self); 402d752132c73072084a3def9257cca4fcee76047b6jeffhao return; 403d752132c73072084a3def9257cca4fcee76047b6jeffhao } 404d752132c73072084a3def9257cca4fcee76047b6jeffhao 405e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier const char* old_cause = self->StartAssertNoThreadSuspension("EnterInterpreterFromInvoke"); 406bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const DexFile::CodeItem* code_item = method->GetCodeItem(); 4072fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers uint16_t num_regs; 4082fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers uint16_t num_ins; 4092cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (code_item != nullptr) { 4102fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_regs = code_item->registers_size_; 4112fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_ins = code_item->ins_size_; 4129139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light } else if (!method->IsInvokable()) { 413e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->EndAssertNoThreadSuspension(old_cause); 4149139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light method->ThrowInvocationTimeError(); 4150a9bb73c70298922ad33d67c209a4e440b216fa2jeffhao return; 4162fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 4172fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers DCHECK(method->IsNative()); 418bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier num_regs = num_ins = ArtMethod::NumArgRegisters(method->GetShorty()); 4192fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (!method->IsStatic()) { 4202fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_regs++; 4212fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers num_ins++; 4222fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4232fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4242fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers // Set up shadow frame with matching number of reference slots to vregs. 4252fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame(); 426b30259251b22430fad12f1adeab671e4bf8f88f5Andreas Gampe ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr = 42703ec930faded5bbfa096533ce60b6893847922dbAndreas Gampe CREATE_SHADOW_FRAME(num_regs, last_shadow_frame, method, /* dex pc */ 0); 428b30259251b22430fad12f1adeab671e4bf8f88f5Andreas Gampe ShadowFrame* shadow_frame = shadow_frame_unique_ptr.get(); 4296613519990bdb5616f2858c146f162ef760f03d2Jeff Hao self->PushShadowFrame(shadow_frame); 430e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier 4312fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers size_t cur_reg = num_regs - num_ins; 4322fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers if (!method->IsStatic()) { 4332cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier CHECK(receiver != nullptr); 434ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa shadow_frame->SetVRegReference(cur_reg, receiver); 4352fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers ++cur_reg; 4362fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 437bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier uint32_t shorty_len = 0; 438bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier const char* shorty = method->GetShorty(&shorty_len); 4395d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) { 440bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier DCHECK_LT(shorty_pos + 1, shorty_len); 4415d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao switch (shorty[shorty_pos + 1]) { 4422fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers case 'L': { 443ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers Object* o = reinterpret_cast<StackReference<Object>*>(&args[arg_pos])->AsMirrorPtr(); 444ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa shadow_frame->SetVRegReference(cur_reg, o); 4452fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 4462fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4475d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao case 'J': case 'D': { 4485d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao uint64_t wide_value = (static_cast<uint64_t>(args[arg_pos + 1]) << 32) | args[arg_pos]; 4495d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao shadow_frame->SetVRegLong(cur_reg, wide_value); 4502fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers cur_reg++; 4515d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao arg_pos++; 4522fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 4535d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao } 4542fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers default: 4555d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao shadow_frame->SetVReg(cur_reg, args[arg_pos]); 4562fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers break; 4572fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4582fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 45992246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier self->EndAssertNoThreadSuspension(old_cause); 46092246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier // Do this after populating the shadow frame in case EnsureInitialized causes a GC. 4616c5cb212fa7010ae7caf9dc765533aa967c95342Ian Rogers if (method->IsStatic() && UNLIKELY(!method->GetDeclaringClass()->IsInitialized())) { 46292246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier ClassLinker* class_linker = Runtime::Current()->GetClassLinker(); 463eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier StackHandleScope<1> hs(self); 464eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass())); 4657b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers if (UNLIKELY(!class_linker->EnsureInitialized(self, h_class, true, true))) { 46692246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier CHECK(self->IsExceptionPending()); 46792246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier self->PopShadowFrame(); 46892246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier return; 46992246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier } 47092246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier } 47164b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (LIKELY(!method->IsNative())) { 472e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers JValue r = Execute(self, code_item, *shadow_frame, JValue()); 4732cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier if (result != nullptr) { 4746474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao *result = r; 4752fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4762fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 47764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 47864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers // generated stub) except during testing and image writing. 47992246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier // Update args to be the args in the shadow frame since the input ones could hold stale 48092246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier // references pointers due to moving GC. 48192246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1); 48264b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers if (!Runtime::Current()->IsStarted()) { 483799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedRuntime::Jni(self, method, receiver, args, result); 4842fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } else { 4856474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao InterpreterJni(self, method, shorty, receiver, args, result); 4862fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4872fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers } 4882fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers self->PopShadowFrame(); 4892fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} 4902fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers 49173be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffrayvoid EnterInterpreterFromDeoptimize(Thread* self, 49273be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray ShadowFrame* shadow_frame, 49373be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray bool from_code, 49473be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray JValue* ret_val) 49590443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier SHARED_REQUIRES(Locks::mutator_lock_) { 49611ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao JValue value; 4972cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier // Set value to last known result in case the shadow frame chain is empty. 4982cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier value.SetJ(ret_val->GetJ()); 499520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // Are we executing the first shadow frame? 500520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz bool first = true; 5012cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier while (shadow_frame != nullptr) { 50262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers self->SetTopOfShadowStack(shadow_frame); 503e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers const DexFile::CodeItem* code_item = shadow_frame->GetMethod()->GetCodeItem(); 504270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz const uint32_t dex_pc = shadow_frame->GetDexPC(); 50573be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray uint32_t new_dex_pc = dex_pc; 506270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz if (UNLIKELY(self->IsExceptionPending())) { 507520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // If we deoptimize from the QuickExceptionHandler, we already reported the exception to 508520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // the instrumentation. To prevent from reporting it a second time, we simply pass a 509520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz // null Instrumentation*. 510270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz const instrumentation::Instrumentation* const instrumentation = 511520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz first ? nullptr : Runtime::Current()->GetInstrumentation(); 512270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz uint32_t found_dex_pc = FindNextInstructionFollowingException(self, *shadow_frame, dex_pc, 513270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz instrumentation); 514270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz new_dex_pc = found_dex_pc; // the dex pc of a matching catch handler 515270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz // or DexFile::kDexNoIndex if there is none. 51673be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray } else if (!from_code) { 51773be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray // For the debugger and full deoptimization stack, we must go past the invoke 51873be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray // instruction, as it already executed. 519d43b3ac88cd46b8815890188c9c2b9a3f1564648Mingyao Yang // TODO: should be tested more once b/17586779 is fixed. 52073be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray const Instruction* instr = Instruction::At(&code_item->insns_[dex_pc]); 52173be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray DCHECK(instr->IsInvoke()); 52273be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray new_dex_pc = dex_pc + instr->SizeInCodeUnits(); 52373be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray } else { 52473be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray // Nothing to do, the dex_pc is the one at which the code requested 52573be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray // the deoptimization. 526270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz } 527270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz if (new_dex_pc != DexFile::kDexNoIndex) { 528270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz shadow_frame->SetDexPC(new_dex_pc); 529270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz value = Execute(self, code_item, *shadow_frame, value); 530270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz } 53111ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao ShadowFrame* old_frame = shadow_frame; 53211ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao shadow_frame = shadow_frame->GetLink(); 533241a9588c6d7d0fcb4c92da40c7141863930083aChristopher Ferris ShadowFrame::DeleteDeoptimizedFrame(old_frame); 53473be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray // Following deoptimizations of shadow frames must pass the invoke instruction. 53573be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray from_code = false; 536520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz first = false; 53711ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao } 53811ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao ret_val->SetJ(value.GetJ()); 53911ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao} 54011ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao 541e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue EnterInterpreterFromEntryPoint(Thread* self, const DexFile::CodeItem* code_item, 5426f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers ShadowFrame* shadow_frame) { 543f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers DCHECK_EQ(self, Thread::Current()); 544535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 545535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 546f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers ThrowStackOverflowError(self); 547f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers return JValue(); 548f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers } 549f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers 550e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers return Execute(self, code_item, *shadow_frame, JValue()); 5517db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers} 5527db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers 5533cfa4d05afa76e19ca99ec964b535a15c73683f0Andreas Gampevoid ArtInterpreterToInterpreterBridge(Thread* self, const DexFile::CodeItem* code_item, 5543cfa4d05afa76e19ca99ec964b535a15c73683f0Andreas Gampe ShadowFrame* shadow_frame, JValue* result) { 555535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks(); 556535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) { 557167436311a08a65dea28dda079a137893821c9c7Jeff Hao ThrowStackOverflowError(self); 5586951067ee14754454e17221fdef0d3d5ed7c4f7eJeff Hao return; 559167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 560167436311a08a65dea28dda079a137893821c9c7Jeff Hao 561e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->PushShadowFrame(shadow_frame); 562eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light ArtMethod* method = shadow_frame->GetMethod(); 563c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz // Ensure static methods are initialized. 564eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light const bool is_static = method->IsStatic(); 565e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers if (is_static) { 566eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light mirror::Class* declaring_class = method->GetDeclaringClass(); 5676c5cb212fa7010ae7caf9dc765533aa967c95342Ian Rogers if (UNLIKELY(!declaring_class->IsInitialized())) { 5680cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier StackHandleScope<1> hs(self); 5690cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier HandleWrapper<Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class)); 5700cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized( 5717b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers self, h_declaring_class, true, true))) { 5720cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier DCHECK(self->IsExceptionPending()); 573e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier self->PopShadowFrame(); 574c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz return; 575c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz } 5760cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier CHECK(h_declaring_class->IsInitializing()); 577167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 578167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 579167436311a08a65dea28dda079a137893821c9c7Jeff Hao 580e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers if (LIKELY(!shadow_frame->GetMethod()->IsNative())) { 581e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers result->SetJ(Execute(self, code_item, *shadow_frame, JValue()).GetJ()); 582167436311a08a65dea28dda079a137893821c9c7Jeff Hao } else { 583167436311a08a65dea28dda079a137893821c9c7Jeff Hao // We don't expect to be asked to interpret native code (which is entered via a JNI compiler 584167436311a08a65dea28dda079a137893821c9c7Jeff Hao // generated stub) except during testing and image writing. 585167436311a08a65dea28dda079a137893821c9c7Jeff Hao CHECK(!Runtime::Current()->IsStarted()); 586e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers Object* receiver = is_static ? nullptr : shadow_frame->GetVRegReference(0); 587e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers uint32_t* args = shadow_frame->GetVRegArgs(is_static ? 0 : 1); 588799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe UnstartedRuntime::Jni(self, shadow_frame->GetMethod(), receiver, args, result); 589167436311a08a65dea28dda079a137893821c9c7Jeff Hao } 590167436311a08a65dea28dda079a137893821c9c7Jeff Hao 591167436311a08a65dea28dda079a137893821c9c7Jeff Hao self->PopShadowFrame(); 592167436311a08a65dea28dda079a137893821c9c7Jeff Hao} 593167436311a08a65dea28dda079a137893821c9c7Jeff Hao 5941452bee8f06b9f76a333ddf4760e4beaa82f8099buzbeevoid CheckInterpreterAsmConstants() { 5951452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee CheckMterpAsmConstants(); 5961452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee} 5971452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee 5981452bee8f06b9f76a333ddf4760e4beaa82f8099buzbeevoid InitInterpreterTls(Thread* self) { 5991452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee InitMterpTls(self); 6001452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee} 6011452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee 6022fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} // namespace interpreter 6032fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers} // namespace art 604