summaryrefslogtreecommitdiffstats
path: root/runtime/quick
diff options
context:
space:
mode:
authorVladimir Marko <vmarko@google.com>2014-04-02 15:24:05 +0100
committerVladimir Marko <vmarko@google.com>2014-04-07 17:14:39 +0100
commitc8f60a69a9f2420fc1ecafec612a667be8dcd547 (patch)
treedff78a37faedcbe9964ba30ed69f8175365e9d7b /runtime/quick
parente1fced1d1805caec04b6e97d2b01a4977c6785c6 (diff)
downloadart-c8f60a69a9f2420fc1ecafec612a667be8dcd547.tar.gz
art-c8f60a69a9f2420fc1ecafec612a667be8dcd547.tar.bz2
art-c8f60a69a9f2420fc1ecafec612a667be8dcd547.zip
Inlining synthetic accessors.
Bug: 11549140 Change-Id: I0d6a38c51887f55563414c240ac42ee64bdb5426
Diffstat (limited to 'runtime/quick')
-rw-r--r--runtime/quick/inline_method_analyser.cc28
-rw-r--r--runtime/quick/inline_method_analyser.h4
2 files changed, 24 insertions, 8 deletions
diff --git a/runtime/quick/inline_method_analyser.cc b/runtime/quick/inline_method_analyser.cc
index 0a1b72e6b4..8bd8dbab73 100644
--- a/runtime/quick/inline_method_analyser.cc
+++ b/runtime/quick/inline_method_analyser.cc
@@ -135,6 +135,12 @@ bool InlineMethodAnalyser::AnalyseMethodCode(verifier::MethodVerifier* verifier,
}
}
+bool InlineMethodAnalyser::IsSyntheticAccessor(MethodReference ref) {
+ const DexFile::MethodId& method_id = ref.dex_file->GetMethodId(ref.dex_method_index);
+ const char* method_name = ref.dex_file->GetMethodName(method_id);
+ return strncmp(method_name, "access$", strlen("access$")) == 0;
+}
+
bool InlineMethodAnalyser::AnalyseReturnMethod(const DexFile::CodeItem* code_item,
InlineMethod* result) {
const Instruction* return_instruction = Instruction::At(code_item->insns_);
@@ -226,8 +232,11 @@ bool InlineMethodAnalyser::AnalyseIGetMethod(verifier::MethodVerifier* verifier,
}
if ((verifier->GetAccessFlags() & kAccStatic) != 0u || object_arg != 0u) {
- // TODO: Support inlining IGET on other register than "this".
- return false;
+ // TODO: Implement inlining of IGET on non-"this" registers (needs correct stack trace for NPE).
+ // Allow synthetic accessors. We don't care about losing their stack frame in NPE.
+ if (!IsSyntheticAccessor(verifier->GetMethodReference())) {
+ return false;
+ }
}
// InlineIGetIPutData::object_arg is only 4 bits wide.
@@ -244,9 +253,9 @@ bool InlineMethodAnalyser::AnalyseIGetMethod(verifier::MethodVerifier* verifier,
result->opcode = kInlineOpIGet;
result->flags = kInlineSpecial;
data->op_variant = IGetVariant(opcode);
- data->method_is_static = (verifier->GetAccessFlags() & kAccStatic) != 0 ? 1u : 0u;
+ data->method_is_static = (verifier->GetAccessFlags() & kAccStatic) != 0u ? 1u : 0u;
data->object_arg = object_arg; // Allow IGET on any register, not just "this".
- data->src_arg = 0;
+ data->src_arg = 0u;
data->return_arg_plus1 = 0u;
}
return true;
@@ -287,9 +296,12 @@ bool InlineMethodAnalyser::AnalyseIPutMethod(verifier::MethodVerifier* verifier,
uint32_t object_arg = object_reg - arg_start;
uint32_t src_arg = src_reg - arg_start;
- if ((verifier->GetAccessFlags() & kAccStatic) != 0 || object_arg != 0) {
- // TODO: Support inlining IPUT on other register than "this".
- return false;
+ if ((verifier->GetAccessFlags() & kAccStatic) != 0u || object_arg != 0u) {
+ // TODO: Implement inlining of IPUT on non-"this" registers (needs correct stack trace for NPE).
+ // Allow synthetic accessors. We don't care about losing their stack frame in NPE.
+ if (!IsSyntheticAccessor(verifier->GetMethodReference())) {
+ return false;
+ }
}
// InlineIGetIPutData::object_arg/src_arg/return_arg_plus1 are each only 4 bits wide.
@@ -308,7 +320,7 @@ bool InlineMethodAnalyser::AnalyseIPutMethod(verifier::MethodVerifier* verifier,
result->opcode = kInlineOpIPut;
result->flags = kInlineSpecial;
data->op_variant = IPutVariant(opcode);
- data->method_is_static = (verifier->GetAccessFlags() & kAccStatic) != 0 ? 1u : 0u;
+ data->method_is_static = (verifier->GetAccessFlags() & kAccStatic) != 0u ? 1u : 0u;
data->object_arg = object_arg; // Allow IPUT on any register, not just "this".
data->src_arg = src_arg;
data->return_arg_plus1 = return_arg_plus1;
diff --git a/runtime/quick/inline_method_analyser.h b/runtime/quick/inline_method_analyser.h
index 277a01e502..ddee89b7bf 100644
--- a/runtime/quick/inline_method_analyser.h
+++ b/runtime/quick/inline_method_analyser.h
@@ -21,6 +21,7 @@
#include "base/mutex.h"
#include "dex_file.h"
#include "dex_instruction.h"
+#include "method_reference.h"
/*
* NOTE: This code is part of the quick compiler. It lives in the runtime
@@ -156,6 +157,9 @@ class InlineMethodAnalyser {
return opcode - Instruction::IPUT;
}
+ // Determines whether the method is a synthetic accessor (method name starts with "access$").
+ static bool IsSyntheticAccessor(MethodReference ref);
+
private:
static bool AnalyseReturnMethod(const DexFile::CodeItem* code_item, InlineMethod* result);
static bool AnalyseConstMethod(const DexFile::CodeItem* code_item, InlineMethod* result);