changeset 2511:3f7a95be91ef

Merge
author iveresov
date Wed, 01 Jun 2011 12:15:10 -0700
parents ea0da5474c23 (diff) 442ef93966a9 (current diff)
children 7c907a50c1bb
files
diffstat 4 files changed, 278 insertions(+), 69 deletions(-) [+]
line wrap: on
line diff
--- a/src/cpu/x86/vm/x86_64.ad	Thu May 26 13:15:01 2011 -0700
+++ b/src/cpu/x86/vm/x86_64.ad	Wed Jun 01 12:15:10 2011 -0700
@@ -3179,50 +3179,6 @@
     emit_rm(cbuf, 0x3, 0x0, dstenc);
   %}
 
-  enc_class enc_cmpLTP(no_rcx_RegI p, no_rcx_RegI q, no_rcx_RegI y,
-                       rcx_RegI tmp)
-  %{
-    // cadd_cmpLT
-
-    int tmpReg = $tmp$$reg;
-
-    int penc = $p$$reg;
-    int qenc = $q$$reg;
-    int yenc = $y$$reg;
-
-    // subl $p,$q
-    if (penc < 8) {
-      if (qenc >= 8) {
-        emit_opcode(cbuf, Assembler::REX_B);
-      }
-    } else {
-      if (qenc < 8) {
-        emit_opcode(cbuf, Assembler::REX_R);
-      } else {
-        emit_opcode(cbuf, Assembler::REX_RB);
-      }
-    }
-    emit_opcode(cbuf, 0x2B);
-    emit_rm(cbuf, 0x3, penc & 7, qenc & 7);
-
-    // sbbl $tmp, $tmp
-    emit_opcode(cbuf, 0x1B);
-    emit_rm(cbuf, 0x3, tmpReg, tmpReg);
-
-    // andl $tmp, $y
-    if (yenc >= 8) {
-      emit_opcode(cbuf, Assembler::REX_B);
-    }
-    emit_opcode(cbuf, 0x23);
-    emit_rm(cbuf, 0x3, tmpReg, yenc & 7);
-
-    // addl $p,$tmp
-    if (penc >= 8) {
-        emit_opcode(cbuf, Assembler::REX_R);
-    }
-    emit_opcode(cbuf, 0x03);
-    emit_rm(cbuf, 0x3, penc & 7, tmpReg);
-  %}
 
   // Compare the lonogs and set -1, 0, or 1 into dst
   enc_class cmpl3_flag(rRegL src1, rRegL src2, rRegI dst)
@@ -10206,9 +10162,7 @@
 %}
 
 
-instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y,
-                         rRegI tmp,
-                         rFlagsReg cr)
+instruct cadd_cmpLTMask(rRegI p, rRegI q, rRegI y, rRegI tmp, rFlagsReg cr)
 %{
   match(Set p (AddI (AndI (CmpLTMask p q) y) (SubI p q)));
   effect(TEMP tmp, KILL cr);
@@ -10218,25 +10172,19 @@
             "sbbl    $tmp, $tmp\n\t"
             "andl    $tmp, $y\n\t"
             "addl    $p, $tmp" %}
-  ins_encode(enc_cmpLTP(p, q, y, tmp));
+  ins_encode %{
+    Register Rp = $p$$Register;
+    Register Rq = $q$$Register;
+    Register Ry = $y$$Register;
+    Register Rt = $tmp$$Register;
+    __ subl(Rp, Rq);
+    __ sbbl(Rt, Rt);
+    __ andl(Rt, Ry);
+    __ addl(Rp, Rt);
+  %}
   ins_pipe(pipe_cmplt);
 %}
 
-/* If I enable this, I encourage spilling in the inner loop of compress.
-instruct cadd_cmpLTMask_mem( rRegI p, rRegI q, memory y, rRegI tmp, rFlagsReg cr )
-%{
-  match(Set p (AddI (AndI (CmpLTMask p q) (LoadI y)) (SubI p q)));
-  effect( TEMP tmp, KILL cr );
-  ins_cost(400);
-
-  format %{ "SUB    $p,$q\n\t"
-            "SBB    RCX,RCX\n\t"
-            "AND    RCX,$y\n\t"
-            "ADD    $p,RCX" %}
-  ins_encode( enc_cmpLTP_mem(p,q,y,tmp) );
-%}
-*/
-
 //---------- FP Instructions------------------------------------------------
 
 instruct cmpF_cc_reg(rFlagsRegU cr, regF src1, regF src2)
--- a/src/share/vm/opto/library_call.cpp	Thu May 26 13:15:01 2011 -0700
+++ b/src/share/vm/opto/library_call.cpp	Wed Jun 01 12:15:10 2011 -0700
@@ -5225,15 +5225,16 @@
 
   // Look at the alignment of the starting offsets.
   int abase = arrayOopDesc::base_offset_in_bytes(basic_elem_type);
-  const intptr_t BIG_NEG = -128;
-  assert(BIG_NEG + 2*abase < 0, "neg enough");
-
-  intptr_t src_off  = abase + ((intptr_t) find_int_con(src_offset, -1)  << scale);
-  intptr_t dest_off = abase + ((intptr_t) find_int_con(dest_offset, -1) << scale);
-  if (src_off < 0 || dest_off < 0)
+
+  intptr_t src_off_con  = (intptr_t) find_int_con(src_offset, -1);
+  intptr_t dest_off_con = (intptr_t) find_int_con(dest_offset, -1);
+  if (src_off_con < 0 || dest_off_con < 0)
     // At present, we can only understand constants.
     return false;
 
+  intptr_t src_off  = abase + (src_off_con  << scale);
+  intptr_t dest_off = abase + (dest_off_con << scale);
+
   if (((src_off | dest_off) & (BytesPerLong-1)) != 0) {
     // Non-aligned; too bad.
     // One more chance:  Pick off an initial 32-bit word.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/7047069/Test7047069.java	Wed Jun 01 12:15:10 2011 -0700
@@ -0,0 +1,200 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 7047069
+ * @summary Array can dynamically change size when assigned to an object field
+ *
+ * @run main/othervm -Xbatch Test7047069
+ */
+
+import java.util.*;
+import java.awt.geom.*;
+
+public class Test7047069 {
+    static boolean verbose;
+
+    static final int GROW_SIZE = 24;    // Multiple of cubic & quad curve size
+
+    float squareflat;           // Square of the flatness parameter
+                    // for testing against squared lengths
+
+    int limit;              // Maximum number of recursion levels
+
+    float hold[] = new float[14];   // The cache of interpolated coords
+                    // Note that this must be long enough
+                    // to store a full cubic segment and
+                    // a relative cubic segment to avoid
+                    // aliasing when copying the coords
+                    // of a curve to the end of the array.
+                    // This is also serendipitously equal
+                    // to the size of a full quad segment
+                    // and 2 relative quad segments.
+
+    int holdEnd;            // The index of the last curve segment
+                    // being held for interpolation
+
+    int holdIndex;          // The index of the curve segment
+                    // that was last interpolated.  This
+                    // is the curve segment ready to be
+                    // returned in the next call to
+                    // currentSegment().
+
+    int levels[];           // The recursion level at which
+                    // each curve being held in storage
+                    // was generated.
+
+    int levelIndex;         // The index of the entry in the
+                    // levels array of the curve segment
+                    // at the holdIndex
+
+    public static void subdivide(float src[], int srcoff,
+                                 float left[], int leftoff,
+                                 float right[], int rightoff)
+    {
+        float x1 = src[srcoff + 0];
+        float y1 = src[srcoff + 1];
+        float ctrlx = src[srcoff + 2];
+        float ctrly = src[srcoff + 3];
+        float x2 = src[srcoff + 4];
+        float y2 = src[srcoff + 5];
+        if (left != null) {
+            left[leftoff + 0] = x1;
+            left[leftoff + 1] = y1;
+        }
+        if (right != null) {
+            right[rightoff + 4] = x2;
+            right[rightoff + 5] = y2;
+        }
+        x1 = (x1 + ctrlx) / 2f;
+        y1 = (y1 + ctrly) / 2f;
+        x2 = (x2 + ctrlx) / 2f;
+        y2 = (y2 + ctrly) / 2f;
+        ctrlx = (x1 + x2) / 2f;
+        ctrly = (y1 + y2) / 2f;
+        if (left != null) {
+            left[leftoff + 2] = x1;
+            left[leftoff + 3] = y1;
+            left[leftoff + 4] = ctrlx;
+            left[leftoff + 5] = ctrly;
+        }
+        if (right != null) {
+            right[rightoff + 0] = ctrlx;
+            right[rightoff + 1] = ctrly;
+            right[rightoff + 2] = x2;
+            right[rightoff + 3] = y2;
+        }
+    }
+
+    public static double getFlatnessSq(float coords[], int offset) {
+        return Line2D.ptSegDistSq(coords[offset + 0], coords[offset + 1],
+                                  coords[offset + 4], coords[offset + 5],
+                                  coords[offset + 2], coords[offset + 3]);
+    }
+
+    public Test7047069() {
+        this.squareflat = .0001f * .0001f;
+        holdIndex = hold.length - 6;
+        holdEnd = hold.length - 2;
+        hold[holdIndex + 0] = (float) (Math.random() * 100);
+        hold[holdIndex + 1] = (float) (Math.random() * 100);
+        hold[holdIndex + 2] = (float) (Math.random() * 100);
+        hold[holdIndex + 3] = (float) (Math.random() * 100);
+        hold[holdIndex + 4] = (float) (Math.random() * 100);
+        hold[holdIndex + 5] = (float) (Math.random() * 100);
+        levelIndex = 0;
+        this.limit = 10;
+        this.levels = new int[limit + 1];
+    }
+
+    /*
+     * Ensures that the hold array can hold up to (want) more values.
+     * It is currently holding (hold.length - holdIndex) values.
+     */
+    void ensureHoldCapacity(int want) {
+        if (holdIndex - want < 0) {
+            int have = hold.length - holdIndex;
+            int newsize = hold.length + GROW_SIZE;
+            float newhold[] = new float[newsize];
+            System.arraycopy(hold, holdIndex,
+                     newhold, holdIndex + GROW_SIZE,
+                     have);
+            if (verbose) System.err.println("old hold = "+hold+"["+hold.length+"]");
+            if (verbose) System.err.println("replacement hold = "+newhold+"["+newhold.length+"]");
+            hold = newhold;
+            if (verbose) System.err.println("new hold = "+hold+"["+hold.length+"]");
+            if (verbose) System.err.println("replacement hold still = "+newhold+"["+newhold.length+"]");
+            holdIndex += GROW_SIZE;
+            holdEnd += GROW_SIZE;
+        }
+    }
+
+    private boolean next() {
+        if (holdIndex >= holdEnd) {
+            return false;
+        }
+
+        int level = levels[levelIndex];
+        while (level < limit) {
+            if (getFlatnessSq(hold, holdIndex) < squareflat) {
+                break;
+            }
+
+            ensureHoldCapacity(4);
+            subdivide(hold, holdIndex,
+                      hold, holdIndex - 4,
+                      hold, holdIndex);
+            holdIndex -= 4;
+
+            // Now that we have subdivided, we have constructed
+            // two curves of one depth lower than the original
+            // curve.  One of those curves is in the place of
+            // the former curve and one of them is in the next
+            // set of held coordinate slots.  We now set both
+            // curves level values to the next higher level.
+            level++;
+            levels[levelIndex] = level;
+            levelIndex++;
+            levels[levelIndex] = level;
+        }
+
+        // This curve segment is flat enough, or it is too deep
+        // in recursion levels to try to flatten any more.  The
+        // two coordinates at holdIndex+4 and holdIndex+5 now
+        // contain the endpoint of the curve which can be the
+        // endpoint of an approximating line segment.
+        holdIndex += 4;
+        levelIndex--;
+        return true;
+    }
+
+    public static void main(String argv[]) {
+        verbose = (argv.length > 0);
+        for (int i = 0; i < 100000; i++) {
+            Test7047069 st = new Test7047069();
+            while (st.next()) {}
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/7048332/Test7048332.java	Wed Jun 01 12:15:10 2011 -0700
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+/**
+ * @test
+ * @bug 7048332
+ * @summary Cadd_cmpLTMask doesn't handle 64-bit tmp register properly
+ *
+ * @run main/othervm -Xbatch Test7048332
+ */
+
+
+public class Test7048332 {
+
+  static int capacity = 2;
+  static int first = 1;
+  static int last = 2;
+
+  static int test(int i1, int i2, int i3, int i4, int i5, int i6) {
+    final int result;
+    if (last >= first) {
+      result = last - first;
+    } else {
+      result = last - first + capacity;
+    }
+    return result;
+  }
+
+  public static void main(String [] args) {
+    for (int i = 0; i < 11000; i++) {
+      last = (i & 1) << 1; // 0 or 2
+      int k = test(1, 2, 3, 4, 5, 6);
+      if (k != 1) {
+        System.out.println("FAILED: " + k + " != 1");
+        System.exit(97);
+      }
+    }
+  }
+}