summaryrefslogtreecommitdiffstats
path: root/compiler/optimizing
diff options
context:
space:
mode:
authorNicolas Geoffray <ngeoffray@google.com>2015-03-26 10:05:54 +0000
committerNicolas Geoffray <ngeoffray@google.com>2015-03-26 10:05:54 +0000
commit790412959a6413a585f45fc5f77fe7106311a00c (patch)
tree94d7d6016c5a58d6c5f31d8350330c8025baa014 /compiler/optimizing
parent9ed05c4cf76aaeee48a1eb5bbae659b0acbabe67 (diff)
downloadart-790412959a6413a585f45fc5f77fe7106311a00c.tar.gz
art-790412959a6413a585f45fc5f77fe7106311a00c.tar.bz2
art-790412959a6413a585f45fc5f77fe7106311a00c.zip
Use the original invoke type when inlining.
When resolving a method through the compiler driver, the code makes sure the call in the DEX bytecode matches the kind of method found, to check for IncompatibleClassChangeError. Because when we sharpen an invoke virtual, we transform the invoke kind to direct, we must not use the new kind, but the one in DEX. Change-Id: Iaf77b27b529c659ea48ffb19f46427552c9e3654
Diffstat (limited to 'compiler/optimizing')
-rw-r--r--compiler/optimizing/builder.cc2
-rw-r--r--compiler/optimizing/inliner.cc4
-rw-r--r--compiler/optimizing/nodes.h4
3 files changed, 8 insertions, 2 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index 8786ed419..f81935a7c 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -620,7 +620,7 @@ bool HGraphBuilder::BuildInvoke(const Instruction& instruction,
DCHECK(!is_recursive || (target_method.dex_file == dex_compilation_unit_->GetDexFile()));
invoke = new (arena_) HInvokeStaticOrDirect(
arena_, number_of_arguments, return_type, dex_pc, target_method.dex_method_index,
- is_recursive, optimized_invoke_type);
+ is_recursive, invoke_type, optimized_invoke_type);
}
size_t start_index = 0;
diff --git a/compiler/optimizing/inliner.cc b/compiler/optimizing/inliner.cc
index 256e85b6c..4b990f1dd 100644
--- a/compiler/optimizing/inliner.cc
+++ b/compiler/optimizing/inliner.cc
@@ -50,7 +50,9 @@ void HInliner::Run() {
HInstruction* next = instruction->GetNext();
HInvokeStaticOrDirect* call = instruction->AsInvokeStaticOrDirect();
if (call != nullptr) {
- if (!TryInline(call, call->GetDexMethodIndex(), call->GetInvokeType())) {
+ // We use the original invoke type to ensure the resolution of the called method
+ // works properly.
+ if (!TryInline(call, call->GetDexMethodIndex(), call->GetOriginalInvokeType())) {
if (kIsDebugBuild) {
std::string callee_name =
PrettyMethod(call->GetDexMethodIndex(), *outer_compilation_unit_.GetDexFile());
diff --git a/compiler/optimizing/nodes.h b/compiler/optimizing/nodes.h
index 08b16d99b..9c751fb9c 100644
--- a/compiler/optimizing/nodes.h
+++ b/compiler/optimizing/nodes.h
@@ -2131,8 +2131,10 @@ class HInvokeStaticOrDirect : public HInvoke {
uint32_t dex_pc,
uint32_t dex_method_index,
bool is_recursive,
+ InvokeType original_invoke_type,
InvokeType invoke_type)
: HInvoke(arena, number_of_arguments, return_type, dex_pc, dex_method_index),
+ original_invoke_type_(original_invoke_type),
invoke_type_(invoke_type),
is_recursive_(is_recursive) {}
@@ -2142,6 +2144,7 @@ class HInvokeStaticOrDirect : public HInvoke {
return false;
}
+ InvokeType GetOriginalInvokeType() const { return original_invoke_type_; }
InvokeType GetInvokeType() const { return invoke_type_; }
bool IsRecursive() const { return is_recursive_; }
bool NeedsDexCache() const OVERRIDE { return !IsRecursive(); }
@@ -2149,6 +2152,7 @@ class HInvokeStaticOrDirect : public HInvoke {
DECLARE_INSTRUCTION(InvokeStaticOrDirect);
private:
+ const InvokeType original_invoke_type_;
const InvokeType invoke_type_;
const bool is_recursive_;