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