Improve interpreter to interpreter invokes.
The interpreter constructs a shadow frame instead of arg array to make
interpreter to interpreter transitions faster. This adds a pointer to
an entry for the interpreter to each method.
Change-Id: If48911d3aa3470847b8548a9e92090b829f4f254
diff --git a/src/class_linker.cc b/src/class_linker.cc
index e55fe78..759bc0c 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -74,6 +74,8 @@
namespace art {
+extern "C" JValue artInterpreterToQuickEntry(Thread* self, ShadowFrame* shadow_frame);
+
static void ThrowNoClassDefFoundError(const char* fmt, ...)
__attribute__((__format__(__printf__, 1, 2)))
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
@@ -1037,6 +1039,12 @@
// Check if object is a method without its code set and point it to the resolution trampoline.
if (obj->IsMethod()) {
mirror::AbstractMethod* method = obj->AsMethod();
+ // Install entry point from interpreter.
+ if (method->GetCode() == NULL && !method->IsNative() && !method->IsProxyMethod()) {
+ method->SetEntryPointFromInterpreter(interpreter::EnterInterpreterFromInterpreter);
+ } else {
+ method->SetEntryPointFromInterpreter(artInterpreterToQuickEntry);
+ }
if (method->GetCode() == NULL) {
method->SetCode(GetResolutionTrampoline());
}
@@ -1598,6 +1606,13 @@
const OatFile::OatMethod oat_method = oat_class->GetOatMethod(method_index);
oat_method.LinkMethod(method.get());
+ // Install entry point from interpreter.
+ if (method->GetCode() == NULL && !method->IsNative() && !method->IsProxyMethod()) {
+ method->SetEntryPointFromInterpreter(interpreter::EnterInterpreterFromInterpreter);
+ } else {
+ method->SetEntryPointFromInterpreter(artInterpreterToQuickEntry);
+ }
+
Runtime* runtime = Runtime::Current();
if (method->IsAbstract()) {
method->SetCode(GetAbstractMethodErrorStub());
@@ -2551,6 +2566,7 @@
#else
method->SetCode(reinterpret_cast<void*>(art_portable_proxy_invoke_handler));
#endif
+ method->SetEntryPointFromInterpreter(artInterpreterToQuickEntry);
return method;
}