summaryrefslogtreecommitdiff
path: root/compiler/optimizing/ssa_builder.cc
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2016-02-15 15:56:11 +0000
committer Nicolas Geoffray <ngeoffray@google.com> 2016-02-15 16:17:11 +0000
commit5e08e3643230ff89f3d7e9b5d7660db6fd94bec9 (patch)
treee19e6ce62b9350e52544c37dffadc4e1b8615417 /compiler/optimizing/ssa_builder.cc
parent88f4bc504c1be353e95e9d215d68c7d58eb0717f (diff)
Expect less in the presence of a string init call.
The compiler currently relies on the dex cache being populated for doing proper type propagation. If it hasn't, we may end up in the situation where the DexMethodInliner has recognized a String.<init> call (because DexMethodInliner only looks at signatures, and does not resolve types), but the graph builder doesn't see a type and assume it needs to do access checks and clinit checks on it. Change-Id: Id79313b0610b127909e3e057305b6632b0b172f7
Diffstat (limited to 'compiler/optimizing/ssa_builder.cc')
-rw-r--r--compiler/optimizing/ssa_builder.cc22
1 files changed, 18 insertions, 4 deletions
diff --git a/compiler/optimizing/ssa_builder.cc b/compiler/optimizing/ssa_builder.cc
index 2d0a399290..a7dc76d7c1 100644
--- a/compiler/optimizing/ssa_builder.cc
+++ b/compiler/optimizing/ssa_builder.cc
@@ -430,8 +430,6 @@ void SsaBuilder::RemoveRedundantUninitializedStrings() {
}
for (HNewInstance* new_instance : uninitialized_strings_) {
- DCHECK(new_instance->IsStringAlloc());
-
// Replace NewInstance of String with NullConstant if not used prior to
// calling StringFactory. In case of deoptimization, the interpreter is
// expected to skip null check on the `this` argument of the StringFactory call.
@@ -440,10 +438,26 @@ void SsaBuilder::RemoveRedundantUninitializedStrings() {
new_instance->GetBlock()->RemoveInstruction(new_instance);
// Remove LoadClass if not needed any more.
- HLoadClass* load_class = new_instance->InputAt(0)->AsLoadClass();
+ HInstruction* input = new_instance->InputAt(0);
+ HLoadClass* load_class = nullptr;
+
+ // If the class was not present in the dex cache at the point of building
+ // the graph, the builder inserted a HClinitCheck in between. Since the String
+ // class is always initialized at the point of running Java code, we can remove
+ // that check.
+ if (input->IsClinitCheck()) {
+ load_class = input->InputAt(0)->AsLoadClass();
+ input->ReplaceWith(load_class);
+ input->GetBlock()->RemoveInstruction(input);
+ } else {
+ load_class = input->AsLoadClass();
+ DCHECK(new_instance->IsStringAlloc());
+ DCHECK(!load_class->NeedsAccessCheck()) << "String class is always accessible";
+ }
DCHECK(load_class != nullptr);
- DCHECK(!load_class->NeedsAccessCheck()) << "String class is always accessible";
if (!load_class->HasUses()) {
+ // Even if the HLoadClass needs access check, we can remove it, as we know the
+ // String class does not need it.
load_class->GetBlock()->RemoveInstruction(load_class);
}
}