OSDN Git Service

ART: LoadConstWide should clobber temp reg
authorAlexei Zavjalov <alexei.zavjalov@intel.com>
Wed, 30 Jul 2014 12:31:04 +0000 (19:31 +0700)
committerAlexei Zavjalov <alexei.zavjalov@intel.com>
Wed, 30 Jul 2014 19:35:49 +0000 (02:35 +0700)
If we have 2+ LoadConstWide(FP) calls in one method it is possible
that LoadConstWide will load the method poiner only once. In some
cases, for example, if we have branches, initialization might not be
done and it may lead to a segmentation fault.

Change-Id: If45fc2d1109d7ce9bd272f5c56446b2a6884daac
Signed-off-by: Alexei Zavjalov <alexei.zavjalov@intel.com>
compiler/dex/quick/x86/utility_x86.cc
test/083-compiler-regressions/expected.txt
test/083-compiler-regressions/src/Main.java

index ccffe5b..a77d79e 100644 (file)
@@ -591,6 +591,7 @@ LIR* X86Mir2Lir::LoadConstantWide(RegStorage r_dest, int64_t value) {
                            kDouble, kNotVolatile);
         res->target = data_target;
         res->flags.fixup = kFixupLoad;
+        Clobber(rl_method.reg);
         store_method_addr_used_ = true;
       } else {
         if (val_lo == 0) {
index 9f57dbd..f8d92cc 100644 (file)
@@ -37,3 +37,4 @@ ManyFloatArgs passes
 atomicLong passes
 LiveFlags passes trip 3
 LiveFlags passes trip 1
+minDoubleWith3ConstsTest passes
index 748b0de..c089c52 100644 (file)
@@ -58,6 +58,21 @@ public class Main {
         ManyFloatArgs();
         atomicLong();
         LiveFlags.test();
+        minDoubleWith3ConstsTest();
+    }
+
+    public static double minDouble(double a, double b, double c) {
+        return Math.min(Math.min(a, b), c);
+    }
+
+    public static void minDoubleWith3ConstsTest() {
+        double result = minDouble(1.2, 2.5, Double.NaN);
+        if (Double.isNaN(result)) {
+            System.out.println("minDoubleWith3ConstsTest passes");
+        } else {
+            System.out.println("minDoubleWith3ConstsTest fails: " + result +
+                               " (expecting NaN)");
+        }
     }
 
     public static void atomicLong() {