summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
author Andreas Gampe <agampe@google.com> 2015-06-05 20:22:12 -0700
committer Andreas Gampe <agampe@google.com> 2015-06-09 11:25:42 -0700
commitda9badb9edea5e0d18cd9f97eff0d0937ad48310 (patch)
treeed2f0b85561daa715988f644482fbdd99995656d /compiler
parentccd6337f31d13706c602f3d9436e9b4025075b63 (diff)
ART: Check long and double register pairs in invokes
For invokes, ensure that long and double parameters are actually in registers pairs. We were testing the pair, but skipping the actual high parameter register. Bug: 17410612 Change-Id: I8f4c3335ea8b7dc3cf252bee52a5a706ae8905f8
Diffstat (limited to 'compiler')
-rw-r--r--compiler/optimizing/builder.cc12
-rw-r--r--compiler/optimizing/optimizing_compiler_stats.h15
2 files changed, 14 insertions, 13 deletions
diff --git a/compiler/optimizing/builder.cc b/compiler/optimizing/builder.cc
index f98029da03..e5fe6c38b3 100644
--- a/compiler/optimizing/builder.cc
+++ b/compiler/optimizing/builder.cc
@@ -748,13 +748,11 @@ bool HGraphBuilder::BuildInvoke(const Instruction& instruction,
for (size_t i = start_index; i < number_of_vreg_arguments; i++, argument_index++) {
Primitive::Type type = Primitive::GetType(descriptor[descriptor_index++]);
bool is_wide = (type == Primitive::kPrimLong) || (type == Primitive::kPrimDouble);
- if (!is_range && is_wide && args[i] + 1 != args[i + 1]) {
- LOG(WARNING) << "Non sequential register pair in " << dex_compilation_unit_->GetSymbol()
- << " at " << dex_pc;
- // We do not implement non sequential register pair.
- MaybeRecordStat(MethodCompilationStat::kNotCompiledNonSequentialRegPair);
- return false;
- }
+ // Longs and doubles should be in pairs, that is, sequential registers. The verifier should
+ // reject any class where this is violated.
+ DCHECK(is_range || !is_wide || (args[i] + 1 == args[i + 1]))
+ << "Non sequential register pair in " << dex_compilation_unit_->GetSymbol()
+ << " at " << dex_pc;
HInstruction* arg = LoadLocal(is_range ? register_index + i : args[i], type);
invoke->SetArgumentAt(argument_index, arg);
if (is_wide) {
diff --git a/compiler/optimizing/optimizing_compiler_stats.h b/compiler/optimizing/optimizing_compiler_stats.h
index b6b1bb1cad..b988813f75 100644
--- a/compiler/optimizing/optimizing_compiler_stats.h
+++ b/compiler/optimizing/optimizing_compiler_stats.h
@@ -19,6 +19,7 @@
#include <sstream>
#include <string>
+#include <type_traits>
#include "atomic.h"
@@ -38,7 +39,6 @@ enum MethodCompilationStat {
kNotCompiledHugeMethod,
kNotCompiledLargeMethodNoBranches,
kNotCompiledNoCodegen,
- kNotCompiledNonSequentialRegPair,
kNotCompiledPathological,
kNotCompiledSpaceFilter,
kNotCompiledUnhandledInstruction,
@@ -84,14 +84,15 @@ class OptimizingCompilerStats {
for (int i = 0; i < kLastStat; i++) {
if (compile_stats_[i] != 0) {
- LOG(INFO) << PrintMethodCompilationStat(i) << ": " << compile_stats_[i];
+ LOG(INFO) << PrintMethodCompilationStat(static_cast<MethodCompilationStat>(i)) << ": "
+ << compile_stats_[i];
}
}
}
}
private:
- std::string PrintMethodCompilationStat(int stat) const {
+ std::string PrintMethodCompilationStat(MethodCompilationStat stat) const {
switch (stat) {
case kAttemptCompilation : return "kAttemptCompilation";
case kCompiledBaseline : return "kCompiledBaseline";
@@ -106,7 +107,6 @@ class OptimizingCompilerStats {
case kNotCompiledHugeMethod : return "kNotCompiledHugeMethod";
case kNotCompiledLargeMethodNoBranches : return "kNotCompiledLargeMethodNoBranches";
case kNotCompiledNoCodegen : return "kNotCompiledNoCodegen";
- case kNotCompiledNonSequentialRegPair : return "kNotCompiledNonSequentialRegPair";
case kNotCompiledPathological : return "kNotCompiledPathological";
case kNotCompiledSpaceFilter : return "kNotCompiledSpaceFilter";
case kNotCompiledUnhandledInstruction : return "kNotCompiledUnhandledInstruction";
@@ -120,9 +120,12 @@ class OptimizingCompilerStats {
case kRemovedCheckedCast: return "kRemovedCheckedCast";
case kRemovedDeadInstruction: return "kRemovedDeadInstruction";
case kRemovedNullCheck: return "kRemovedNullCheck";
- default: LOG(FATAL) << "invalid stat";
+
+ case kLastStat: break; // Invalid to print out.
}
- return "";
+ LOG(FATAL) << "invalid stat "
+ << static_cast<std::underlying_type<MethodCompilationStat>::type>(stat);
+ UNREACHABLE();
}
AtomicInteger compile_stats_[kLastStat];