summaryrefslogtreecommitdiffstats
path: root/compiler
diff options
context:
space:
mode:
authorbuzbee <buzbee@google.com>2014-09-07 11:37:51 -0700
committerbuzbee <buzbee@google.com>2014-09-07 21:21:24 -0700
commit90a21f8e76028b9f89e91c436fc6fe9e9a354694 (patch)
tree6772cee165531f6f6d09f8f14e54243694f5c877 /compiler
parent9b868cbfa6d74387a80ce52a426f9a5bc3ddbbaf (diff)
downloadart-90a21f8e76028b9f89e91c436fc6fe9e9a354694.zip
art-90a21f8e76028b9f89e91c436fc6fe9e9a354694.tar.gz
art-90a21f8e76028b9f89e91c436fc6fe9e9a354694.tar.bz2
Quick compiler: Fix handling of unused returns
As part of the inlining process, the quick compiler will attempt to eliminate MOVE_RESULT instructions and deliver the result of the inlined function directly to the eventual use. The type of the returned value is determined by the subsequent use (which had already been typed via the size and type inference pass). However, if a method result is never used the code just defaulted to assigning dummy core sink register[s]. This caused a DCHECK failure on some 64-bit systems for methods returning an unused reference (although the generated code was correct). This CL selects sink registers for the unused return case based on the type of the inlined method, and adds another DCHECK to verify that the result of the size & type inference pass matches with the inlined method's type. Internal b/17328561 Change-Id: I9803ad604fe1bdcf9ff9a1d310cf022a7b6deae2
Diffstat (limited to 'compiler')
-rwxr-xr-xcompiler/dex/quick/gen_invoke.cc10
1 files changed, 8 insertions, 2 deletions
diff --git a/compiler/dex/quick/gen_invoke.cc b/compiler/dex/quick/gen_invoke.cc
index e1d3241..78f5c73 100755
--- a/compiler/dex/quick/gen_invoke.cc
+++ b/compiler/dex/quick/gen_invoke.cc
@@ -1107,9 +1107,12 @@ int Mir2Lir::GenDalvikArgsRange(CallInfo* info, int call_state,
RegLocation Mir2Lir::InlineTarget(CallInfo* info) {
RegLocation res;
if (info->result.location == kLocInvalid) {
- res = GetReturn(LocToRegClass(info->result));
+ // If result is unused, return a sink target based on type of invoke target.
+ res = GetReturn(ShortyToRegClass(mir_graph_->GetShortyFromTargetIdx(info->index)[0]));
} else {
res = info->result;
+ DCHECK_EQ(LocToRegClass(res),
+ ShortyToRegClass(mir_graph_->GetShortyFromTargetIdx(info->index)[0]));
}
return res;
}
@@ -1117,9 +1120,12 @@ RegLocation Mir2Lir::InlineTarget(CallInfo* info) {
RegLocation Mir2Lir::InlineTargetWide(CallInfo* info) {
RegLocation res;
if (info->result.location == kLocInvalid) {
- res = GetReturnWide(kCoreReg);
+ // If result is unused, return a sink target based on type of invoke target.
+ res = GetReturnWide(ShortyToRegClass(mir_graph_->GetShortyFromTargetIdx(info->index)[0]));
} else {
res = info->result;
+ DCHECK_EQ(LocToRegClass(res),
+ ShortyToRegClass(mir_graph_->GetShortyFromTargetIdx(info->index)[0]));
}
return res;
}