|
1 /* |
|
2 * Copyright (c) 2011, 2015, 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 * @test |
|
26 * @bug 7047069 |
|
27 * @summary Array can dynamically change size when assigned to an object field |
|
28 * @modules java.desktop |
|
29 * |
|
30 * @run main/othervm -Xbatch compiler.c2.Test7047069 |
|
31 */ |
|
32 |
|
33 package compiler.c2; |
|
34 |
|
35 import java.awt.geom.Line2D; |
|
36 |
|
37 public class Test7047069 { |
|
38 static boolean verbose; |
|
39 |
|
40 static final int GROW_SIZE = 24; // Multiple of cubic & quad curve size |
|
41 |
|
42 float squareflat; // Square of the flatness parameter |
|
43 // for testing against squared lengths |
|
44 |
|
45 int limit; // Maximum number of recursion levels |
|
46 |
|
47 float hold[] = new float[14]; // The cache of interpolated coords |
|
48 // Note that this must be long enough |
|
49 // to store a full cubic segment and |
|
50 // a relative cubic segment to avoid |
|
51 // aliasing when copying the coords |
|
52 // of a curve to the end of the array. |
|
53 // This is also serendipitously equal |
|
54 // to the size of a full quad segment |
|
55 // and 2 relative quad segments. |
|
56 |
|
57 int holdEnd; // The index of the last curve segment |
|
58 // being held for interpolation |
|
59 |
|
60 int holdIndex; // The index of the curve segment |
|
61 // that was last interpolated. This |
|
62 // is the curve segment ready to be |
|
63 // returned in the next call to |
|
64 // currentSegment(). |
|
65 |
|
66 int levels[]; // The recursion level at which |
|
67 // each curve being held in storage |
|
68 // was generated. |
|
69 |
|
70 int levelIndex; // The index of the entry in the |
|
71 // levels array of the curve segment |
|
72 // at the holdIndex |
|
73 |
|
74 public static void subdivide(float src[], int srcoff, |
|
75 float left[], int leftoff, |
|
76 float right[], int rightoff) |
|
77 { |
|
78 float x1 = src[srcoff + 0]; |
|
79 float y1 = src[srcoff + 1]; |
|
80 float ctrlx = src[srcoff + 2]; |
|
81 float ctrly = src[srcoff + 3]; |
|
82 float x2 = src[srcoff + 4]; |
|
83 float y2 = src[srcoff + 5]; |
|
84 if (left != null) { |
|
85 left[leftoff + 0] = x1; |
|
86 left[leftoff + 1] = y1; |
|
87 } |
|
88 if (right != null) { |
|
89 right[rightoff + 4] = x2; |
|
90 right[rightoff + 5] = y2; |
|
91 } |
|
92 x1 = (x1 + ctrlx) / 2f; |
|
93 y1 = (y1 + ctrly) / 2f; |
|
94 x2 = (x2 + ctrlx) / 2f; |
|
95 y2 = (y2 + ctrly) / 2f; |
|
96 ctrlx = (x1 + x2) / 2f; |
|
97 ctrly = (y1 + y2) / 2f; |
|
98 if (left != null) { |
|
99 left[leftoff + 2] = x1; |
|
100 left[leftoff + 3] = y1; |
|
101 left[leftoff + 4] = ctrlx; |
|
102 left[leftoff + 5] = ctrly; |
|
103 } |
|
104 if (right != null) { |
|
105 right[rightoff + 0] = ctrlx; |
|
106 right[rightoff + 1] = ctrly; |
|
107 right[rightoff + 2] = x2; |
|
108 right[rightoff + 3] = y2; |
|
109 } |
|
110 } |
|
111 |
|
112 public static double getFlatnessSq(float coords[], int offset) { |
|
113 return Line2D.ptSegDistSq(coords[offset + 0], coords[offset + 1], |
|
114 coords[offset + 4], coords[offset + 5], |
|
115 coords[offset + 2], coords[offset + 3]); |
|
116 } |
|
117 |
|
118 public Test7047069() { |
|
119 this.squareflat = .0001f * .0001f; |
|
120 holdIndex = hold.length - 6; |
|
121 holdEnd = hold.length - 2; |
|
122 hold[holdIndex + 0] = (float) (Math.random() * 100); |
|
123 hold[holdIndex + 1] = (float) (Math.random() * 100); |
|
124 hold[holdIndex + 2] = (float) (Math.random() * 100); |
|
125 hold[holdIndex + 3] = (float) (Math.random() * 100); |
|
126 hold[holdIndex + 4] = (float) (Math.random() * 100); |
|
127 hold[holdIndex + 5] = (float) (Math.random() * 100); |
|
128 levelIndex = 0; |
|
129 this.limit = 10; |
|
130 this.levels = new int[limit + 1]; |
|
131 } |
|
132 |
|
133 /* |
|
134 * Ensures that the hold array can hold up to (want) more values. |
|
135 * It is currently holding (hold.length - holdIndex) values. |
|
136 */ |
|
137 void ensureHoldCapacity(int want) { |
|
138 if (holdIndex - want < 0) { |
|
139 int have = hold.length - holdIndex; |
|
140 int newsize = hold.length + GROW_SIZE; |
|
141 float newhold[] = new float[newsize]; |
|
142 System.arraycopy(hold, holdIndex, |
|
143 newhold, holdIndex + GROW_SIZE, |
|
144 have); |
|
145 if (verbose) System.err.println("old hold = "+hold+"["+hold.length+"]"); |
|
146 if (verbose) System.err.println("replacement hold = "+newhold+"["+newhold.length+"]"); |
|
147 hold = newhold; |
|
148 if (verbose) System.err.println("new hold = "+hold+"["+hold.length+"]"); |
|
149 if (verbose) System.err.println("replacement hold still = "+newhold+"["+newhold.length+"]"); |
|
150 holdIndex += GROW_SIZE; |
|
151 holdEnd += GROW_SIZE; |
|
152 } |
|
153 } |
|
154 |
|
155 private boolean next() { |
|
156 if (holdIndex >= holdEnd) { |
|
157 return false; |
|
158 } |
|
159 |
|
160 int level = levels[levelIndex]; |
|
161 while (level < limit) { |
|
162 if (getFlatnessSq(hold, holdIndex) < squareflat) { |
|
163 break; |
|
164 } |
|
165 |
|
166 ensureHoldCapacity(4); |
|
167 subdivide(hold, holdIndex, |
|
168 hold, holdIndex - 4, |
|
169 hold, holdIndex); |
|
170 holdIndex -= 4; |
|
171 |
|
172 // Now that we have subdivided, we have constructed |
|
173 // two curves of one depth lower than the original |
|
174 // curve. One of those curves is in the place of |
|
175 // the former curve and one of them is in the next |
|
176 // set of held coordinate slots. We now set both |
|
177 // curves level values to the next higher level. |
|
178 level++; |
|
179 levels[levelIndex] = level; |
|
180 levelIndex++; |
|
181 levels[levelIndex] = level; |
|
182 } |
|
183 |
|
184 // This curve segment is flat enough, or it is too deep |
|
185 // in recursion levels to try to flatten any more. The |
|
186 // two coordinates at holdIndex+4 and holdIndex+5 now |
|
187 // contain the endpoint of the curve which can be the |
|
188 // endpoint of an approximating line segment. |
|
189 holdIndex += 4; |
|
190 levelIndex--; |
|
191 return true; |
|
192 } |
|
193 |
|
194 public static void main(String argv[]) { |
|
195 verbose = (argv.length > 0); |
|
196 for (int i = 0; i < 100000; i++) { |
|
197 Test7047069 st = new Test7047069(); |
|
198 while (st.next()) {} |
|
199 } |
|
200 } |
|
201 } |