Mercurial > hg > truffle
comparison test/compiler/7047069/Test7047069.java @ 3742:b2cb497dec28
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
author | kvn |
---|---|
date | Fri, 27 May 2011 12:47:48 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
3741:c76c13577460 | 3742:b2cb497dec28 |
---|---|
1 /* | |
2 * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 * | |
23 */ | |
24 | |
25 /** | |
26 * @test | |
27 * @bug 7047069 | |
28 * @summary Array can dynamically change size when assigned to an object field | |
29 * | |
30 * @run main/othervm -Xbatch Test7047069 | |
31 */ | |
32 | |
33 import java.util.*; | |
34 import java.awt.geom.*; | |
35 | |
36 public class Test7047069 { | |
37 static boolean verbose; | |
38 | |
39 static final int GROW_SIZE = 24; // Multiple of cubic & quad curve size | |
40 | |
41 float squareflat; // Square of the flatness parameter | |
42 // for testing against squared lengths | |
43 | |
44 int limit; // Maximum number of recursion levels | |
45 | |
46 float hold[] = new float[14]; // The cache of interpolated coords | |
47 // Note that this must be long enough | |
48 // to store a full cubic segment and | |
49 // a relative cubic segment to avoid | |
50 // aliasing when copying the coords | |
51 // of a curve to the end of the array. | |
52 // This is also serendipitously equal | |
53 // to the size of a full quad segment | |
54 // and 2 relative quad segments. | |
55 | |
56 int holdEnd; // The index of the last curve segment | |
57 // being held for interpolation | |
58 | |
59 int holdIndex; // The index of the curve segment | |
60 // that was last interpolated. This | |
61 // is the curve segment ready to be | |
62 // returned in the next call to | |
63 // currentSegment(). | |
64 | |
65 int levels[]; // The recursion level at which | |
66 // each curve being held in storage | |
67 // was generated. | |
68 | |
69 int levelIndex; // The index of the entry in the | |
70 // levels array of the curve segment | |
71 // at the holdIndex | |
72 | |
73 public static void subdivide(float src[], int srcoff, | |
74 float left[], int leftoff, | |
75 float right[], int rightoff) | |
76 { | |
77 float x1 = src[srcoff + 0]; | |
78 float y1 = src[srcoff + 1]; | |
79 float ctrlx = src[srcoff + 2]; | |
80 float ctrly = src[srcoff + 3]; | |
81 float x2 = src[srcoff + 4]; | |
82 float y2 = src[srcoff + 5]; | |
83 if (left != null) { | |
84 left[leftoff + 0] = x1; | |
85 left[leftoff + 1] = y1; | |
86 } | |
87 if (right != null) { | |
88 right[rightoff + 4] = x2; | |
89 right[rightoff + 5] = y2; | |
90 } | |
91 x1 = (x1 + ctrlx) / 2f; | |
92 y1 = (y1 + ctrly) / 2f; | |
93 x2 = (x2 + ctrlx) / 2f; | |
94 y2 = (y2 + ctrly) / 2f; | |
95 ctrlx = (x1 + x2) / 2f; | |
96 ctrly = (y1 + y2) / 2f; | |
97 if (left != null) { | |
98 left[leftoff + 2] = x1; | |
99 left[leftoff + 3] = y1; | |
100 left[leftoff + 4] = ctrlx; | |
101 left[leftoff + 5] = ctrly; | |
102 } | |
103 if (right != null) { | |
104 right[rightoff + 0] = ctrlx; | |
105 right[rightoff + 1] = ctrly; | |
106 right[rightoff + 2] = x2; | |
107 right[rightoff + 3] = y2; | |
108 } | |
109 } | |
110 | |
111 public static double getFlatnessSq(float coords[], int offset) { | |
112 return Line2D.ptSegDistSq(coords[offset + 0], coords[offset + 1], | |
113 coords[offset + 4], coords[offset + 5], | |
114 coords[offset + 2], coords[offset + 3]); | |
115 } | |
116 | |
117 public Test7047069() { | |
118 this.squareflat = .0001f * .0001f; | |
119 holdIndex = hold.length - 6; | |
120 holdEnd = hold.length - 2; | |
121 hold[holdIndex + 0] = (float) (Math.random() * 100); | |
122 hold[holdIndex + 1] = (float) (Math.random() * 100); | |
123 hold[holdIndex + 2] = (float) (Math.random() * 100); | |
124 hold[holdIndex + 3] = (float) (Math.random() * 100); | |
125 hold[holdIndex + 4] = (float) (Math.random() * 100); | |
126 hold[holdIndex + 5] = (float) (Math.random() * 100); | |
127 levelIndex = 0; | |
128 this.limit = 10; | |
129 this.levels = new int[limit + 1]; | |
130 } | |
131 | |
132 /* | |
133 * Ensures that the hold array can hold up to (want) more values. | |
134 * It is currently holding (hold.length - holdIndex) values. | |
135 */ | |
136 void ensureHoldCapacity(int want) { | |
137 if (holdIndex - want < 0) { | |
138 int have = hold.length - holdIndex; | |
139 int newsize = hold.length + GROW_SIZE; | |
140 float newhold[] = new float[newsize]; | |
141 System.arraycopy(hold, holdIndex, | |
142 newhold, holdIndex + GROW_SIZE, | |
143 have); | |
144 if (verbose) System.err.println("old hold = "+hold+"["+hold.length+"]"); | |
145 if (verbose) System.err.println("replacement hold = "+newhold+"["+newhold.length+"]"); | |
146 hold = newhold; | |
147 if (verbose) System.err.println("new hold = "+hold+"["+hold.length+"]"); | |
148 if (verbose) System.err.println("replacement hold still = "+newhold+"["+newhold.length+"]"); | |
149 holdIndex += GROW_SIZE; | |
150 holdEnd += GROW_SIZE; | |
151 } | |
152 } | |
153 | |
154 private boolean next() { | |
155 if (holdIndex >= holdEnd) { | |
156 return false; | |
157 } | |
158 | |
159 int level = levels[levelIndex]; | |
160 while (level < limit) { | |
161 if (getFlatnessSq(hold, holdIndex) < squareflat) { | |
162 break; | |
163 } | |
164 | |
165 ensureHoldCapacity(4); | |
166 subdivide(hold, holdIndex, | |
167 hold, holdIndex - 4, | |
168 hold, holdIndex); | |
169 holdIndex -= 4; | |
170 | |
171 // Now that we have subdivided, we have constructed | |
172 // two curves of one depth lower than the original | |
173 // curve. One of those curves is in the place of | |
174 // the former curve and one of them is in the next | |
175 // set of held coordinate slots. We now set both | |
176 // curves level values to the next higher level. | |
177 level++; | |
178 levels[levelIndex] = level; | |
179 levelIndex++; | |
180 levels[levelIndex] = level; | |
181 } | |
182 | |
183 // This curve segment is flat enough, or it is too deep | |
184 // in recursion levels to try to flatten any more. The | |
185 // two coordinates at holdIndex+4 and holdIndex+5 now | |
186 // contain the endpoint of the curve which can be the | |
187 // endpoint of an approximating line segment. | |
188 holdIndex += 4; | |
189 levelIndex--; | |
190 return true; | |
191 } | |
192 | |
193 public static void main(String argv[]) { | |
194 verbose = (argv.length > 0); | |
195 for (int i = 0; i < 100000; i++) { | |
196 Test7047069 st = new Test7047069(); | |
197 while (st.next()) {} | |
198 } | |
199 } | |
200 } |