interpreter.cc revision 6740997e6934bbca27d5830a32352d82aabbd38b
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
2431452bee8f06b9f76a333ddf4760e4beaa82f8099buzbeestatic constexpr InterpreterImplKind kInterpreterImplKind = kMterpImplKind;
24400b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze
24500b53b7f3f9ce5996b767b52c28dd846f47a723cAlexey Frunze#if defined(__clang__)
246fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz// Clang 3.4 fails to build the goto interpreter implementation.
247fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertztemplate<bool do_access_check, bool transaction_active>
248e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl(Thread*, const DexFile::CodeItem*, ShadowFrame&, JValue) {
249fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz  LOG(FATAL) << "UNREACHABLE";
2502c4257be8191c5eefde744e8965fcefc80a0a97dIan Rogers  UNREACHABLE();
251fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz}
252fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz// Explicit definitions of ExecuteGotoImpl.
25390443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartiertemplate<> SHARED_REQUIRES(Locks::mutator_lock_)
254e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<true, false>(Thread* self, const DexFile::CodeItem* code_item,
255fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz                                    ShadowFrame& shadow_frame, JValue result_register);
25690443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartiertemplate<> SHARED_REQUIRES(Locks::mutator_lock_)
257e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<false, false>(Thread* self, const DexFile::CodeItem* code_item,
258fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz                                     ShadowFrame& shadow_frame, JValue result_register);
25990443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartiertemplate<> SHARED_REQUIRES(Locks::mutator_lock_)
260e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<true, true>(Thread* self,  const DexFile::CodeItem* code_item,
261e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers                                   ShadowFrame& shadow_frame, JValue result_register);
26290443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartiertemplate<> SHARED_REQUIRES(Locks::mutator_lock_)
263e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue ExecuteGotoImpl<false, true>(Thread* self, const DexFile::CodeItem* code_item,
264e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers                                    ShadowFrame& shadow_frame, JValue result_register);
265fa888d06fd9ae90565254456e9b2e0cd62fbc91fSebastien Hertz#endif
2662fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers
2670122320f86ae004aa195d76814c52564d84ee632Aart Bikstatic inline JValue Execute(
2680122320f86ae004aa195d76814c52564d84ee632Aart Bik    Thread* self,
2690122320f86ae004aa195d76814c52564d84ee632Aart Bik    const DexFile::CodeItem* code_item,
2700122320f86ae004aa195d76814c52564d84ee632Aart Bik    ShadowFrame& shadow_frame,
2710122320f86ae004aa195d76814c52564d84ee632Aart Bik    JValue result_register,
2720122320f86ae004aa195d76814c52564d84ee632Aart Bik    bool stay_in_interpreter = false) SHARED_REQUIRES(Locks::mutator_lock_) {
2731452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee  DCHECK(!shadow_frame.GetMethod()->IsAbstract());
274848871b4d8481229c32e0d048a9856e5a9a17ef9Ian Rogers  DCHECK(!shadow_frame.GetMethod()->IsNative());
275734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee  if (LIKELY(shadow_frame.GetDexPC() == 0)) {  // Entering the method, but not via deoptimization.
276734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee    if (kIsDebugBuild) {
277734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee      self->AssertNoPendingException();
278734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee    }
279734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee    instrumentation::Instrumentation* instrumentation = Runtime::Current()->GetInstrumentation();
280734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee    ArtMethod *method = shadow_frame.GetMethod();
281734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee
282734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee    if (UNLIKELY(instrumentation->HasMethodEntryListeners())) {
283734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee      instrumentation->MethodEnterEvent(self, shadow_frame.GetThisObject(code_item->ins_size_),
284734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee                                        method, 0);
285734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee    }
286734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee
2870122320f86ae004aa195d76814c52564d84ee632Aart Bik    if (!stay_in_interpreter) {
2880122320f86ae004aa195d76814c52564d84ee632Aart Bik      jit::Jit* jit = Runtime::Current()->GetJit();
2890122320f86ae004aa195d76814c52564d84ee632Aart Bik      if (jit != nullptr) {
2900122320f86ae004aa195d76814c52564d84ee632Aart Bik        jit->MethodEntered(self, shadow_frame.GetMethod());
2910122320f86ae004aa195d76814c52564d84ee632Aart Bik        if (jit->CanInvokeCompiledCode(method)) {
2920122320f86ae004aa195d76814c52564d84ee632Aart Bik          JValue result;
293734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee
2940122320f86ae004aa195d76814c52564d84ee632Aart Bik          // Pop the shadow frame before calling into compiled code.
2950122320f86ae004aa195d76814c52564d84ee632Aart Bik          self->PopShadowFrame();
2960122320f86ae004aa195d76814c52564d84ee632Aart Bik          ArtInterpreterToCompiledCodeBridge(self, nullptr, code_item, &shadow_frame, &result);
2970122320f86ae004aa195d76814c52564d84ee632Aart Bik          // Push the shadow frame back as the caller will expect it.
2980122320f86ae004aa195d76814c52564d84ee632Aart Bik          self->PushShadowFrame(&shadow_frame);
299734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee
3000122320f86ae004aa195d76814c52564d84ee632Aart Bik          return result;
3010122320f86ae004aa195d76814c52564d84ee632Aart Bik        }
302274fe4adcb0610a9920be7814d9beb9cac6417ceNicolas Geoffray      }
303734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee    }
304734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee  }
305734f3aa9f758236b6f1ace6347895af90b0d813dbuzbee
3064e99b3d8955131f3fc71aa113f0fa71f0092cb6fSebastien Hertz  shadow_frame.GetMethod()->GetDeclaringClass()->AssertInitializedOrInitializingInThread(self);
3078ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz
30856fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe  // Lock counting is a special version of accessibility checks, and for simplicity and
30956fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe  // reduction of template parameters, we gate it behind access-checks mode.
31056fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe  ArtMethod* method = shadow_frame.GetMethod();
31156fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe  DCHECK(!method->SkipAccessChecks() || !method->MustCountLocks());
31256fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe
313d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz  bool transaction_active = Runtime::Current()->IsActiveTransaction();
31456fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe  if (LIKELY(method->SkipAccessChecks())) {
315233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz    // Enter the "without access check" interpreter.
3161452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee    if (kInterpreterImplKind == kMterpImplKind) {
317d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz      if (transaction_active) {
3181452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee        // No Mterp variant - just use the switch interpreter.
3191452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee        return ExecuteSwitchImpl<false, true>(self, code_item, shadow_frame, result_register,
3201452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee                                              false);
321fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee      } else if (UNLIKELY(!Runtime::Current()->IsStarted())) {
322fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee        return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register,
323fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee                                               false);
324d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz      } else {
3251452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee        while (true) {
326fd522f9039befff986701ff05054ffdd1be1dd33Bill Buzbee          // Mterp does not support all instrumentation/debugging.
3276740997e6934bbca27d5830a32352d82aabbd38bAndreas Gampe          if (MterpShouldSwitchInterpreters() != 0) {
3281452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee            return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register,
3291452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee                                                   false);
3301452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee          }
3311452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee          bool returned = ExecuteMterpImpl(self, code_item, &shadow_frame, &result_register);
3321452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee          if (returned) {
3331452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee            return result_register;
3341452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee          } else {
3351452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee            // Mterp didn't like that instruction.  Single-step it with the reference interpreter.
336d6b48dbe715fbf1431394d2b6ef75cb19a4012ddbuzbee            result_register = ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame,
3371452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee                                                               result_register, true);
3381452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee            if (shadow_frame.GetDexPC() == DexFile::kDexNoIndex) {
3391452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee              // Single-stepped a return or an exception not handled locally.  Return to caller.
340d6b48dbe715fbf1431394d2b6ef75cb19a4012ddbuzbee              return result_register;
3411452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee            }
3421452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee          }
3431452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee        }
3441452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee      }
3451452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee    } else if (kInterpreterImplKind == kSwitchImplKind) {
3461452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee      if (transaction_active) {
3471452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee        return ExecuteSwitchImpl<false, true>(self, code_item, shadow_frame, result_register,
3481452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee                                              false);
3491452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee      } else {
3501452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee        return ExecuteSwitchImpl<false, false>(self, code_item, shadow_frame, result_register,
3511452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee                                               false);
352d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz      }
3538ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz    } else {
3548ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz      DCHECK_EQ(kInterpreterImplKind, kComputedGotoImplKind);
355d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz      if (transaction_active) {
356e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers        return ExecuteGotoImpl<false, true>(self, code_item, shadow_frame, result_register);
357d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz      } else {
358e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers        return ExecuteGotoImpl<false, false>(self, code_item, shadow_frame, result_register);
359d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz      }
3608ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz    }
361233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz  } else {
362233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz    // Enter the "with access check" interpreter.
3631452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee    if (kInterpreterImplKind == kMterpImplKind) {
3641452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee      // No access check variants for Mterp.  Just use the switch version.
3651452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee      if (transaction_active) {
3661452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee        return ExecuteSwitchImpl<true, true>(self, code_item, shadow_frame, result_register,
3671452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee                                             false);
3681452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee      } else {
3691452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee        return ExecuteSwitchImpl<true, false>(self, code_item, shadow_frame, result_register,
3701452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee                                              false);
3711452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee      }
3721452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee    } else if (kInterpreterImplKind == kSwitchImplKind) {
373d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz      if (transaction_active) {
3741452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee        return ExecuteSwitchImpl<true, true>(self, code_item, shadow_frame, result_register,
3751452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee                                             false);
376d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz      } else {
3771452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee        return ExecuteSwitchImpl<true, false>(self, code_item, shadow_frame, result_register,
3781452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee                                              false);
379d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz      }
3808ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz    } else {
3818ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz      DCHECK_EQ(kInterpreterImplKind, kComputedGotoImplKind);
382d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz      if (transaction_active) {
383e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers        return ExecuteGotoImpl<true, true>(self, code_item, shadow_frame, result_register);
384d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz      } else {
385e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers        return ExecuteGotoImpl<true, false>(self, code_item, shadow_frame, result_register);
386d2fe10a3a34af171bf1631219cd2d6ff6b7778b5Sebastien Hertz      }
3878ece050d85fc244c72610244e440b0e00aa618faSebastien Hertz    }
388233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz  }
389233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz}
390233ea8e084a95ad2a3af746dddbadb155db6a814Sebastien Hertz
391ea46f950e7a51585db293cd7f047de190a482414Brian Carlstromvoid EnterInterpreterFromInvoke(Thread* self, ArtMethod* method, Object* receiver,
3920122320f86ae004aa195d76814c52564d84ee632Aart Bik                                uint32_t* args, JValue* result,
3930122320f86ae004aa195d76814c52564d84ee632Aart Bik                                bool stay_in_interpreter) {
39464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  DCHECK_EQ(self, Thread::Current());
395535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray  bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks();
396535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray  if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) {
397d752132c73072084a3def9257cca4fcee76047b6jeffhao    ThrowStackOverflowError(self);
398d752132c73072084a3def9257cca4fcee76047b6jeffhao    return;
399d752132c73072084a3def9257cca4fcee76047b6jeffhao  }
400d752132c73072084a3def9257cca4fcee76047b6jeffhao
401e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier  const char* old_cause = self->StartAssertNoThreadSuspension("EnterInterpreterFromInvoke");
402bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier  const DexFile::CodeItem* code_item = method->GetCodeItem();
4032fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  uint16_t num_regs;
4042fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  uint16_t num_ins;
4052cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  if (code_item != nullptr) {
4062fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers    num_regs =  code_item->registers_size_;
4072fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers    num_ins = code_item->ins_size_;
4089139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light  } else if (!method->IsInvokable()) {
409e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier    self->EndAssertNoThreadSuspension(old_cause);
4109139e008abe30b7beaf4afd6533228a1dd9b202cAlex Light    method->ThrowInvocationTimeError();
4110a9bb73c70298922ad33d67c209a4e440b216fa2jeffhao    return;
4122fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  } else {
4132fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers    DCHECK(method->IsNative());
414bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier    num_regs = num_ins = ArtMethod::NumArgRegisters(method->GetShorty());
4152fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers    if (!method->IsStatic()) {
4162fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers      num_regs++;
4172fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers      num_ins++;
4182fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers    }
4192fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  }
4202fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  // Set up shadow frame with matching number of reference slots to vregs.
4212fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  ShadowFrame* last_shadow_frame = self->GetManagedStack()->GetTopShadowFrame();
422b30259251b22430fad12f1adeab671e4bf8f88f5Andreas Gampe  ShadowFrameAllocaUniquePtr shadow_frame_unique_ptr =
42303ec930faded5bbfa096533ce60b6893847922dbAndreas Gampe      CREATE_SHADOW_FRAME(num_regs, last_shadow_frame, method, /* dex pc */ 0);
424b30259251b22430fad12f1adeab671e4bf8f88f5Andreas Gampe  ShadowFrame* shadow_frame = shadow_frame_unique_ptr.get();
4256613519990bdb5616f2858c146f162ef760f03d2Jeff Hao  self->PushShadowFrame(shadow_frame);
426e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier
4272fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  size_t cur_reg = num_regs - num_ins;
4282fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  if (!method->IsStatic()) {
4292cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    CHECK(receiver != nullptr);
430ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa    shadow_frame->SetVRegReference(cur_reg, receiver);
4312fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers    ++cur_reg;
4322fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  }
433bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier  uint32_t shorty_len = 0;
434bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier  const char* shorty = method->GetShorty(&shorty_len);
4355d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao  for (size_t shorty_pos = 0, arg_pos = 0; cur_reg < num_regs; ++shorty_pos, ++arg_pos, cur_reg++) {
436bfd9a4378eacaf2dc2bbe05ad48c5164fc93c9feMathieu Chartier    DCHECK_LT(shorty_pos + 1, shorty_len);
4375d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao    switch (shorty[shorty_pos + 1]) {
4382fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers      case 'L': {
439ef7d42fca18c16fbaf103822ad16f23246e2905dIan Rogers        Object* o = reinterpret_cast<StackReference<Object>*>(&args[arg_pos])->AsMirrorPtr();
440ce4cc0d1818e872c1c7f3c3519a82259afd5c288TDYa        shadow_frame->SetVRegReference(cur_reg, o);
4412fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers        break;
4422fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers      }
4435d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao      case 'J': case 'D': {
4445d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao        uint64_t wide_value = (static_cast<uint64_t>(args[arg_pos + 1]) << 32) | args[arg_pos];
4455d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao        shadow_frame->SetVRegLong(cur_reg, wide_value);
4462fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers        cur_reg++;
4475d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao        arg_pos++;
4482fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers        break;
4495d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao      }
4502fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers      default:
4515d9173014c1ca09f7249a6b07629aa37778b5f8fJeff Hao        shadow_frame->SetVReg(cur_reg, args[arg_pos]);
4522fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers        break;
4532fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers    }
4542fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  }
45592246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier  self->EndAssertNoThreadSuspension(old_cause);
45692246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier  // Do this after populating the shadow frame in case EnsureInitialized causes a GC.
4576c5cb212fa7010ae7caf9dc765533aa967c95342Ian Rogers  if (method->IsStatic() && UNLIKELY(!method->GetDeclaringClass()->IsInitialized())) {
45892246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier    ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
459eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    StackHandleScope<1> hs(self);
460eb8167a4f4d27fce0530f6724ab8032610cd146bMathieu Chartier    Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass()));
4617b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers    if (UNLIKELY(!class_linker->EnsureInitialized(self, h_class, true, true))) {
46292246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier      CHECK(self->IsExceptionPending());
46392246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier      self->PopShadowFrame();
46492246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier      return;
46592246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier    }
46692246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier  }
46764b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers  if (LIKELY(!method->IsNative())) {
4680122320f86ae004aa195d76814c52564d84ee632Aart Bik    JValue r = Execute(self, code_item, *shadow_frame, JValue(), stay_in_interpreter);
4692cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier    if (result != nullptr) {
4706474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao      *result = r;
4712fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers    }
4722fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  } else {
47364b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // We don't expect to be asked to interpret native code (which is entered via a JNI compiler
47464b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    // generated stub) except during testing and image writing.
47592246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier    // Update args to be the args in the shadow frame since the input ones could hold stale
47692246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier    // references pointers due to moving GC.
47792246bb5d6caae4fdb09cd3c8c10d78e41932d45Mathieu Chartier    args = shadow_frame->GetVRegArgs(method->IsStatic() ? 0 : 1);
47864b6d145fa53b8dfb07a8fc2426af13f155d5a4dIan Rogers    if (!Runtime::Current()->IsStarted()) {
479799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe      UnstartedRuntime::Jni(self, method, receiver, args, result);
4802fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers    } else {
4816474d190d5604898354ebf767f1944b6e3e9b445Jeff Hao      InterpreterJni(self, method, shorty, receiver, args, result);
4822fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers    }
4832fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  }
4842fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers  self->PopShadowFrame();
4852fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers}
4862fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers
487ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yangstatic bool IsStringInit(const Instruction* instr, ArtMethod* caller)
488ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang    SHARED_REQUIRES(Locks::mutator_lock_) {
489ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang  if (instr->Opcode() == Instruction::INVOKE_DIRECT ||
490ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang      instr->Opcode() == Instruction::INVOKE_DIRECT_RANGE) {
491ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang    // Instead of calling ResolveMethod() which has suspend point and can trigger
492ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang    // GC, look up the callee method symbolically.
493ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang    uint16_t callee_method_idx = (instr->Opcode() == Instruction::INVOKE_DIRECT_RANGE) ?
494ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang        instr->VRegB_3rc() : instr->VRegB_35c();
495ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang    const DexFile* dex_file = caller->GetDexFile();
496ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang    const DexFile::MethodId& method_id = dex_file->GetMethodId(callee_method_idx);
497ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang    const char* class_name = dex_file->StringByTypeIdx(method_id.class_idx_);
498ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang    const char* method_name = dex_file->GetMethodName(method_id);
499ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang    // Compare method's class name and method name against string init.
500ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang    // It's ok since it's not allowed to create your own java/lang/String.
501ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang    // TODO: verify that assumption.
502ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang    if ((strcmp(class_name, "Ljava/lang/String;") == 0) &&
503ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang        (strcmp(method_name, "<init>") == 0)) {
504ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang      return true;
505ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang    }
506ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang  }
507ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang  return false;
508ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang}
509ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang
510ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yangstatic int16_t GetReceiverRegisterForStringInit(const Instruction* instr) {
511ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang  DCHECK(instr->Opcode() == Instruction::INVOKE_DIRECT_RANGE ||
512ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang         instr->Opcode() == Instruction::INVOKE_DIRECT);
513ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang  return (instr->Opcode() == Instruction::INVOKE_DIRECT_RANGE) ?
514ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang      instr->VRegC_3rc() : instr->VRegC_35c();
515ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang}
516ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang
51773be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffrayvoid EnterInterpreterFromDeoptimize(Thread* self,
51873be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray                                    ShadowFrame* shadow_frame,
51973be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray                                    bool from_code,
52073be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray                                    JValue* ret_val)
52190443477f9a0061581c420775ce3b7eeae7468bcMathieu Chartier    SHARED_REQUIRES(Locks::mutator_lock_) {
52211ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao  JValue value;
5232cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  // Set value to last known result in case the shadow frame chain is empty.
5242cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  value.SetJ(ret_val->GetJ());
525520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz  // Are we executing the first shadow frame?
526520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz  bool first = true;
5272cebb24bfc3247d3e9be138a3350106737455918Mathieu Chartier  while (shadow_frame != nullptr) {
52856fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe    // We do not want to recover lock state for lock counting when deoptimizing. Currently,
52956fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe    // the compiler should not have compiled a method that failed structured-locking checks.
53056fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe    DCHECK(!shadow_frame->GetMethod()->MustCountLocks());
53156fdd0e63812764bbeb8cc52e376d3fd1f270052Andreas Gampe
53262d6c772205b8859f0ebf7ad105402ec4c3e2e01Ian Rogers    self->SetTopOfShadowStack(shadow_frame);
533e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers    const DexFile::CodeItem* code_item = shadow_frame->GetMethod()->GetCodeItem();
534270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz    const uint32_t dex_pc = shadow_frame->GetDexPC();
53573be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray    uint32_t new_dex_pc = dex_pc;
536270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz    if (UNLIKELY(self->IsExceptionPending())) {
537520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz      // If we deoptimize from the QuickExceptionHandler, we already reported the exception to
538520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz      // the instrumentation. To prevent from reporting it a second time, we simply pass a
539520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz      // null Instrumentation*.
540270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz      const instrumentation::Instrumentation* const instrumentation =
541520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz          first ? nullptr : Runtime::Current()->GetInstrumentation();
542270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz      uint32_t found_dex_pc = FindNextInstructionFollowingException(self, *shadow_frame, dex_pc,
543270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz                                                                    instrumentation);
544270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz      new_dex_pc = found_dex_pc;  // the dex pc of a matching catch handler
545270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz                                  // or DexFile::kDexNoIndex if there is none.
54673be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray    } else if (!from_code) {
54773be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray      // For the debugger and full deoptimization stack, we must go past the invoke
54873be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray      // instruction, as it already executed.
549d43b3ac88cd46b8815890188c9c2b9a3f1564648Mingyao Yang      // TODO: should be tested more once b/17586779 is fixed.
55073be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray      const Instruction* instr = Instruction::At(&code_item->insns_[dex_pc]);
551504a69081f63818ca332ddaf54e8198448554538Mingyao Yang      if (instr->IsInvoke()) {
552ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang        if (IsStringInit(instr, shadow_frame->GetMethod())) {
553ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang          uint16_t this_obj_vreg = GetReceiverRegisterForStringInit(instr);
554ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang          // Move the StringFactory.newStringFromChars() result into the register representing
555ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang          // "this object" when invoking the string constructor in the original dex instruction.
556ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang          // Also move the result into all aliases.
557ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang          DCHECK(value.GetL()->IsString());
558ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang          SetStringInitValueToAllAliases(shadow_frame, this_obj_vreg, value);
559ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang          // Calling string constructor in the original dex code doesn't generate a result value.
560ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang          value.SetJ(0);
561ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang        }
562504a69081f63818ca332ddaf54e8198448554538Mingyao Yang        new_dex_pc = dex_pc + instr->SizeInCodeUnits();
563504a69081f63818ca332ddaf54e8198448554538Mingyao Yang      } else if (instr->Opcode() == Instruction::NEW_INSTANCE) {
564504a69081f63818ca332ddaf54e8198448554538Mingyao Yang        // It's possible to deoptimize at a NEW_INSTANCE dex instruciton that's for a
565504a69081f63818ca332ddaf54e8198448554538Mingyao Yang        // java string, which is turned into a call into StringFactory.newEmptyString();
566ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang        // Move the StringFactory.newEmptyString() result into the destination register.
567ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang        DCHECK(value.GetL()->IsString());
568ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang        shadow_frame->SetVRegReference(instr->VRegA_21c(), value.GetL());
569ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang        // new-instance doesn't generate a result value.
570ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang        value.SetJ(0);
571ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang        // Skip the dex instruction since we essentially come back from an invocation.
572ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang        new_dex_pc = dex_pc + instr->SizeInCodeUnits();
573504a69081f63818ca332ddaf54e8198448554538Mingyao Yang        if (kIsDebugBuild) {
574504a69081f63818ca332ddaf54e8198448554538Mingyao Yang          ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
575ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang          // This is a suspend point. But it's ok since value has been set into shadow_frame.
576504a69081f63818ca332ddaf54e8198448554538Mingyao Yang          mirror::Class* klass = class_linker->ResolveType(
577504a69081f63818ca332ddaf54e8198448554538Mingyao Yang              instr->VRegB_21c(), shadow_frame->GetMethod());
578504a69081f63818ca332ddaf54e8198448554538Mingyao Yang          DCHECK(klass->IsStringClass());
579504a69081f63818ca332ddaf54e8198448554538Mingyao Yang        }
580504a69081f63818ca332ddaf54e8198448554538Mingyao Yang      } else {
581ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang        CHECK(false) << "Unexpected instruction opcode " << instr->Opcode()
582ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang                     << " at dex_pc " << dex_pc
583ffedec510c07cf0f77d0cce51940838f2e630514Mingyao Yang                     << " of method: " << PrettyMethod(shadow_frame->GetMethod(), false);
584504a69081f63818ca332ddaf54e8198448554538Mingyao Yang      }
58573be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray    } else {
58673be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray      // Nothing to do, the dex_pc is the one at which the code requested
58773be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray      // the deoptimization.
588270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz    }
589270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz    if (new_dex_pc != DexFile::kDexNoIndex) {
590270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz      shadow_frame->SetDexPC(new_dex_pc);
591270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz      value = Execute(self, code_item, *shadow_frame, value);
592270a0e16c3b8e5b95cbfdbd8996ac137c7c6322bSebastien Hertz    }
59311ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao    ShadowFrame* old_frame = shadow_frame;
59411ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao    shadow_frame = shadow_frame->GetLink();
595241a9588c6d7d0fcb4c92da40c7141863930083aChristopher Ferris    ShadowFrame::DeleteDeoptimizedFrame(old_frame);
59673be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray    // Following deoptimizations of shadow frames must pass the invoke instruction.
59773be1e8f8609708f6624bb297c9628de44fd8b6fNicolas Geoffray    from_code = false;
598520633bebd2bf4d70884d30f179dbde9f275aac6Sebastien Hertz    first = false;
59911ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao  }
60011ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao  ret_val->SetJ(value.GetJ());
60111ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao}
60211ffc2d02b7d979f26a8a04013fce3eb4f9a2816Jeff Hao
603e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian RogersJValue EnterInterpreterFromEntryPoint(Thread* self, const DexFile::CodeItem* code_item,
6046f3dbbadf4ce66982eb3d400e0a74cb73eb034f3Ian Rogers                                      ShadowFrame* shadow_frame) {
605f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers  DCHECK_EQ(self, Thread::Current());
606535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray  bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks();
607535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray  if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) {
608f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers    ThrowStackOverflowError(self);
609f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers    return JValue();
610f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers  }
611f3e9855ee2000106b54fd479f7a46da2dc2ad079Ian Rogers
61271cd50fb67fa48667b0ab59aa436a582c04ba43dNicolas Geoffray  jit::Jit* jit = Runtime::Current()->GetJit();
61371cd50fb67fa48667b0ab59aa436a582c04ba43dNicolas Geoffray  if (jit != nullptr) {
61471cd50fb67fa48667b0ab59aa436a582c04ba43dNicolas Geoffray    jit->NotifyCompiledCodeToInterpreterTransition(self, shadow_frame->GetMethod());
61571cd50fb67fa48667b0ab59aa436a582c04ba43dNicolas Geoffray  }
616e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers  return Execute(self, code_item, *shadow_frame, JValue());
6177db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers}
6187db619bb2a4e01e8532a04b613745d4926b205d7Ian Rogers
6193cfa4d05afa76e19ca99ec964b535a15c73683f0Andreas Gampevoid ArtInterpreterToInterpreterBridge(Thread* self, const DexFile::CodeItem* code_item,
6203cfa4d05afa76e19ca99ec964b535a15c73683f0Andreas Gampe                                       ShadowFrame* shadow_frame, JValue* result) {
621535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray  bool implicit_check = !Runtime::Current()->ExplicitStackOverflowChecks();
622535a3fbc08e1577f43aec7402cab80c14ca64c41Nicolas Geoffray  if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEndForInterpreter(implicit_check))) {
623167436311a08a65dea28dda079a137893821c9c7Jeff Hao    ThrowStackOverflowError(self);
6246951067ee14754454e17221fdef0d3d5ed7c4f7eJeff Hao    return;
625167436311a08a65dea28dda079a137893821c9c7Jeff Hao  }
626167436311a08a65dea28dda079a137893821c9c7Jeff Hao
627e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier  self->PushShadowFrame(shadow_frame);
628eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light  ArtMethod* method = shadow_frame->GetMethod();
629c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz  // Ensure static methods are initialized.
630eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light  const bool is_static = method->IsStatic();
631e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers  if (is_static) {
632eb7c144a6aff7da673ba53d501c46f00311d4d7fAlex Light    mirror::Class* declaring_class = method->GetDeclaringClass();
6336c5cb212fa7010ae7caf9dc765533aa967c95342Ian Rogers    if (UNLIKELY(!declaring_class->IsInitialized())) {
6340cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier      StackHandleScope<1> hs(self);
6350cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier      HandleWrapper<Class> h_declaring_class(hs.NewHandleWrapper(&declaring_class));
6360cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier      if (UNLIKELY(!Runtime::Current()->GetClassLinker()->EnsureInitialized(
6377b078e8c04f3e1451dbdd18543c8b9692b5b067eIan Rogers          self, h_declaring_class, true, true))) {
6380cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier        DCHECK(self->IsExceptionPending());
639e861ebd5d9490cc86200f3859f3d36fadad4588cMathieu Chartier        self->PopShadowFrame();
640c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz        return;
641c61124bdeaae94f977ffc36ac69535e792c226f2Sebastien Hertz      }
6420cd81352a7c06e381951cea1b104fd73516f4341Mathieu Chartier      CHECK(h_declaring_class->IsInitializing());
643167436311a08a65dea28dda079a137893821c9c7Jeff Hao    }
644167436311a08a65dea28dda079a137893821c9c7Jeff Hao  }
645167436311a08a65dea28dda079a137893821c9c7Jeff Hao
646e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers  if (LIKELY(!shadow_frame->GetMethod()->IsNative())) {
647e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers    result->SetJ(Execute(self, code_item, *shadow_frame, JValue()).GetJ());
648167436311a08a65dea28dda079a137893821c9c7Jeff Hao  } else {
649167436311a08a65dea28dda079a137893821c9c7Jeff Hao    // We don't expect to be asked to interpret native code (which is entered via a JNI compiler
650167436311a08a65dea28dda079a137893821c9c7Jeff Hao    // generated stub) except during testing and image writing.
651167436311a08a65dea28dda079a137893821c9c7Jeff Hao    CHECK(!Runtime::Current()->IsStarted());
652e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers    Object* receiver = is_static ? nullptr : shadow_frame->GetVRegReference(0);
653e94652f1e321b2c8b71acbe5b07d2ebf69fbdb99Ian Rogers    uint32_t* args = shadow_frame->GetVRegArgs(is_static ? 0 : 1);
654799681b176ad25437ce2849639f54f610dcbf684Andreas Gampe    UnstartedRuntime::Jni(self, shadow_frame->GetMethod(), receiver, args, result);
655167436311a08a65dea28dda079a137893821c9c7Jeff Hao  }
656167436311a08a65dea28dda079a137893821c9c7Jeff Hao
657167436311a08a65dea28dda079a137893821c9c7Jeff Hao  self->PopShadowFrame();
658167436311a08a65dea28dda079a137893821c9c7Jeff Hao}
659167436311a08a65dea28dda079a137893821c9c7Jeff Hao
6601452bee8f06b9f76a333ddf4760e4beaa82f8099buzbeevoid CheckInterpreterAsmConstants() {
6611452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee  CheckMterpAsmConstants();
6621452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee}
6631452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee
6641452bee8f06b9f76a333ddf4760e4beaa82f8099buzbeevoid InitInterpreterTls(Thread* self) {
6651452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee  InitMterpTls(self);
6661452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee}
6671452bee8f06b9f76a333ddf4760e4beaa82f8099buzbee
6682fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers}  // namespace interpreter
6692fa6b2e2fc3d2a2fc27808ce518dc76b80ce369aIan Rogers}  // namespace art
670