changeset 2625:3c66636f2c6f

S7047069: Array can dynamically change size when assigned to an object field
author ptisnovs
date Wed, 29 Jun 2011 10:26:39 +0200
parents 93fe1e8a9277
children 70ed85d57999
files ChangeLog Makefile.am NEWS patches/openjdk/7047069-Array_can_dynamically_change_size.patch
diffstat 4 files changed, 249 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Jun 28 17:21:18 2011 +0100
+++ b/ChangeLog	Wed Jun 29 10:26:39 2011 +0200
@@ -1,3 +1,10 @@
+2011-06-29  Pavel Tisnovsky  <ptisnovs@redhat.com>
+
+	* Makefile.am: added new patches
+	* NEWS: updated with backports
+	* patches/openjdk/7047069-Array_can_dynamically_change_size.patch:
+	Backport of 7047069 fix.
+
 2011-06-28  Pavel Tisnovsky  <ptisnovs@redhat.com>
 
 	* Makefile.am: added new patch
--- a/Makefile.am	Tue Jun 28 17:21:18 2011 +0100
+++ b/Makefile.am	Wed Jun 29 10:26:39 2011 +0200
@@ -370,7 +370,8 @@
 	patches/openjdk/6623219-Font_canDisplayUpTo_does_not_work.patch \
 	patches/support_linux_3.patch \
 	patches/openjdk/6783910-java_awt_Color_brighter_darker_fix.patch \
-	patches/openjdk/6785424-SecurityException_locating_physical_fonts.patch
+	patches/openjdk/6785424-SecurityException_locating_physical_fonts.patch \
+	patches/openjdk/7047069-Array_can_dynamically_change_size.patch
 
 if WITH_ALT_HSBUILD
 ICEDTEA_PATCHES += \
--- a/NEWS	Tue Jun 28 17:21:18 2011 +0100
+++ b/NEWS	Wed Jun 29 10:26:39 2011 +0200
@@ -41,6 +41,7 @@
   - S6623219: Font.canDisplayUpTo does not work with supplementary characters
   - S6783910: java.awt.Color.brighter()/darker() methods make color opaque
   - S6785424: SecurityException locating physical fonts on Windows Terminal Server
+  - S7047069: Array can dynamically change size when assigned to an object field
 * Bug fixes
   - PR637: make check should exit with an error code if any regression test failed.
   - G356743: Support libpng 1.5.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/7047069-Array_can_dynamically_change_size.patch	Wed Jun 29 10:26:39 2011 +0200
@@ -0,0 +1,239 @@
+# HG changeset patch
+# User kvn
+# Date 1306525668 25200
+# Node ID ea0da5474c23f6d810cd9de8769e58e6e5ebbef5
+# Parent  9340a27154cb431ee287bfc8c1204f5cb483b66c
+7047069: Array can dynamically change size when assigned to an object field
+Summary: Fix initialization of a newly-allocated array with arraycopy
+Reviewed-by: never
+
+diff -r 9340a27154cb -r ea0da5474c23 src/share/vm/opto/library_call.cpp
+--- openjdk.orig/hotspot/src/share/vm/opto/library_call.cpp	Wed May 25 21:17:07 2011 -0700
++++ openjdk/hotspot/src/share/vm/opto/library_call.cpp	Fri May 27 12:47:48 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.
+diff -r 9340a27154cb -r ea0da5474c23 test/compiler/7047069/Test7047069.java
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/hotspot/test/compiler/7047069/Test7047069.java	Fri May 27 12:47:48 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()) {}
++        }
++    }
++}