summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author buzbee <buzbee@google.com> 2015-02-20 14:07:27 -0800
committer buzbee <buzbee@google.com> 2015-02-22 07:54:17 -0800
commit4de86d0987139153ae0e2d50dbbefde2ce34ee87 (patch)
treee9ec46e3972ad197b5d889e80d15fd9a2e4b6d9d
parent4ba405483177cf346211d43d97892bae6ff14119 (diff)
Handle another untyped dex CONST issue
The lack of typing for dex byte code instructions causes problems for the Quick compiler's register allocation scheme. In Quick, Dalvik virtual registers can have multiple "home locations" depending on type. Because CONST operators are untyped and their result can be used in multiple type contexts, the code generator must ensure that any CONST #0 definitions of potential floating point uses are also flushed to the associated reference view for the vreg (if it exists) to support GC. Previously, this issue was believed to have been fixed by c/255389 (see internal b/7250540). However, the earlier fix failed to account for const definitions propogating to other vregs via MOVE. This CL addresses that case by applying the earlier workaround to MOVE operators. Note that there are a few other places where we attempt to deal with this general problem. First, the verifier will disable compilation for dex code sequences which have type mismatches on non-const operations. Second, during vreg analysis we detect type mismatches on Phi insertion, and disable register promotion if there is a mismatch. b.android.com/147187 Change-Id: I70f27a59e6f84a89777db91ceacaa94a42f5e952
-rw-r--r--compiler/dex/quick/mir_to_lir.cc3
-rw-r--r--test/134-reg-promotion/expected.txt0
-rw-r--r--test/134-reg-promotion/info.txt4
-rw-r--r--test/134-reg-promotion/smali/Test.smali38
-rw-r--r--test/134-reg-promotion/src/Main.java42
5 files changed, 87 insertions, 0 deletions
diff --git a/compiler/dex/quick/mir_to_lir.cc b/compiler/dex/quick/mir_to_lir.cc
index 34e5e25efe..bd4936b290 100644
--- a/compiler/dex/quick/mir_to_lir.cc
+++ b/compiler/dex/quick/mir_to_lir.cc
@@ -586,6 +586,9 @@ void Mir2Lir::CompileDalvikInstruction(MIR* mir, BasicBlock* bb, LIR* label_list
case Instruction::MOVE_FROM16:
case Instruction::MOVE_OBJECT_FROM16:
StoreValue(rl_dest, rl_src[0]);
+ if (rl_src[0].is_const && (mir_graph_->ConstantValue(rl_src[0]) == 0)) {
+ Workaround7250540(rl_dest, RegStorage::InvalidReg());
+ }
break;
case Instruction::MOVE_WIDE:
diff --git a/test/134-reg-promotion/expected.txt b/test/134-reg-promotion/expected.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/test/134-reg-promotion/expected.txt
diff --git a/test/134-reg-promotion/info.txt b/test/134-reg-promotion/info.txt
new file mode 100644
index 0000000000..6eff7eb832
--- /dev/null
+++ b/test/134-reg-promotion/info.txt
@@ -0,0 +1,4 @@
+Test that a vreg value that was defined by a const 0 and is used is both ref
+and float operations is flushed to all home location.
+
+See: b/19417710, b/7250540 & b.android.com/147187
diff --git a/test/134-reg-promotion/smali/Test.smali b/test/134-reg-promotion/smali/Test.smali
new file mode 100644
index 0000000000..6a35c45cd7
--- /dev/null
+++ b/test/134-reg-promotion/smali/Test.smali
@@ -0,0 +1,38 @@
+#
+# Copyright (C) 2015 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+.class public LTest;
+
+.super Ljava/lang/Object;
+
+.method public static run()V
+ .registers 3
+ new-instance v2, Ljava/lang/String;
+ invoke-direct {v2}, Ljava/lang/String;-><init>()V
+ const/4 v0, 0
+ move v1, v0
+ :start
+ invoke-static {}, LMain;->blowup()V
+ if-ne v1, v0, :end
+ const/4 v2, 1
+ invoke-static {v2}, Ljava/lang/Integer;->toString(I)Ljava/lang/String;
+ move v2, v0
+ # The call makes v2 float type.
+ invoke-static {v2}, Ljava/lang/Float;->isNaN(F)Z
+ const/4 v1, 1
+ goto :start
+ :end
+ return-void
+.end method
diff --git a/test/134-reg-promotion/src/Main.java b/test/134-reg-promotion/src/Main.java
new file mode 100644
index 0000000000..d45ec661d3
--- /dev/null
+++ b/test/134-reg-promotion/src/Main.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.lang.reflect.Method;
+
+public class Main {
+ static char [][] holder;
+ static boolean sawOome;
+
+ static void blowup() {
+ try {
+ for (int i = 0; i < holder.length; ++i) {
+ holder[i] = new char[1024 * 1024];
+ }
+ } catch (OutOfMemoryError oome) {
+ sawOome = true;
+ }
+ }
+
+ public static void main(String args[]) throws Exception {
+ Class<?> c = Class.forName("Test");
+ Method m = c.getMethod("run", (Class[]) null);
+ for (int i = 0; i < 10; i++) {
+ holder = new char[128 * 1024][];
+ m.invoke(null, (Object[]) null);
+ holder = null;
+ }
+ }
+}