diff options
| author | 2015-02-20 14:07:27 -0800 | |
|---|---|---|
| committer | 2015-02-22 07:54:17 -0800 | |
| commit | 4de86d0987139153ae0e2d50dbbefde2ce34ee87 (patch) | |
| tree | e9ec46e3972ad197b5d889e80d15fd9a2e4b6d9d | |
| parent | 4ba405483177cf346211d43d97892bae6ff14119 (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.cc | 3 | ||||
| -rw-r--r-- | test/134-reg-promotion/expected.txt | 0 | ||||
| -rw-r--r-- | test/134-reg-promotion/info.txt | 4 | ||||
| -rw-r--r-- | test/134-reg-promotion/smali/Test.smali | 38 | ||||
| -rw-r--r-- | test/134-reg-promotion/src/Main.java | 42 |
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; + } + } +} |