/hg/icedtea6: Fix problem where NaNs could appear in stroked qua...
dlila at icedtea.classpath.org
dlila at icedtea.classpath.org
Wed May 4 07:22:19 PDT 2011
changeset b71a752b9762 in /hg/icedtea6
details: http://icedtea.classpath.org/hg/icedtea6?cmd=changeset;node=b71a752b9762
author: Denis Lila <dlila at redhat.com>
date: Wed May 04 10:09:47 2011 -0400
Fix problem where NaNs could appear in stroked quad paths. Improve
performance of quad stroking.
diffstat:
ChangeLog | 7 +
Makefile.am | 3 +-
NEWS | 1 +
patches/openjdk/7036754-stroker-nan.patch | 488 ++++++++++++++++++++++++++++++
4 files changed, 498 insertions(+), 1 deletions(-)
diffs (truncated from 532 to 500 lines):
diff -r 74bcdece2162 -r b71a752b9762 ChangeLog
--- a/ChangeLog Wed May 04 15:06:24 2011 +0200
+++ b/ChangeLog Wed May 04 10:09:47 2011 -0400
@@ -1,3 +1,10 @@
+2011-05-04 Denis Lila <dlila at redhat.com>
+
+ * Makefile.am: Apply patch.
+ * NEWS: Update with backport.
+ * patches/openjdk/7036754-stroker-nan.patch: New patch. Fix NaN
+ quad stroking problem.
+
2011-05-04 Xerxes RÃ¥nby <xerxes at zafena.se>
* .hgtags Update.
diff -r 74bcdece2162 -r b71a752b9762 Makefile.am
--- a/Makefile.am Wed May 04 15:06:24 2011 +0200
+++ b/Makefile.am Wed May 04 10:09:47 2011 -0400
@@ -338,7 +338,8 @@
patches/hotspot/$(HSBUILD)/7032388-work_without_cmov_instruction.patch \
patches/openjdk/7031385-gcc-register-allocation-fix.patch \
patches/shark-llvm-2.9.patch \
- patches/openjdk/6986968-crash_on_xim_restart.patch
+ patches/openjdk/6986968-crash_on_xim_restart.patch \
+ patches/openjdk/7036754-stroker-nan.patch
if WITH_ALT_HSBUILD
ICEDTEA_PATCHES += \
diff -r 74bcdece2162 -r b71a752b9762 NEWS
--- a/NEWS Wed May 04 15:06:24 2011 +0200
+++ b/NEWS Wed May 04 10:09:47 2011 -0400
@@ -23,6 +23,7 @@
- S7029905: demo applets missing some html files
- S6986968: Crash on XIM server restart
- S7018387: Xrender pipeline may leak GC's
+ - S7036754: Stroked quads sometimes contain NaN
* Bug fixes
- PR637: make check should exit with an error code if any regression test failed.
- G356743: Support libpng 1.5.
diff -r 74bcdece2162 -r b71a752b9762 patches/openjdk/7036754-stroker-nan.patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/openjdk/7036754-stroker-nan.patch Wed May 04 10:09:47 2011 -0400
@@ -0,0 +1,490 @@
+# HG changeset patch
+# User dlila
+# Date 1303995319 14400
+# Node ID 24f474ad17038b0bef4686c79c8b8de25ab23723
+# Parent a07c9e09b4caa5690209af460e8c9371b8384cb0
+7036754: NaNs in stroked quadratics.
+Summary: Check for them and remove them.
+Reviewed-by: flar
+
+diff -r a07c9e09b4ca -r 24f474ad1703 src/share/classes/sun/java2d/pisces/Stroker.java
+--- openjdk.orig/jdk/src/share/classes/sun/java2d/pisces/Stroker.java Wed Apr 27 12:15:34 2011 +0400
++++ openjdk/jdk/src/share/classes/sun/java2d/pisces/Stroker.java Thu Apr 28 08:55:19 2011 -0400
+@@ -27,6 +27,8 @@
+
+ import java.util.Arrays;
+ import java.util.Iterator;
++import static java.lang.Math.ulp;
++import static java.lang.Math.sqrt;
+
+ import sun.awt.geom.PathConsumer2D;
+
+@@ -130,7 +132,7 @@
+ private static void computeOffset(final float lx, final float ly,
+ final float w, final float[] m)
+ {
+- final float len = (float)Math.sqrt(lx*lx + ly*ly);
++ final float len = (float) sqrt(lx*lx + ly*ly);
+ if (len == 0) {
+ m[0] = m[1] = 0;
+ } else {
+@@ -217,7 +219,7 @@
+ // this normal's length is at least 0.5 and at most sqrt(2)/2 (because
+ // we know the angle of the arc is > 90 degrees).
+ float nx = my - omy, ny = omx - mx;
+- float nlen = (float)Math.sqrt(nx*nx + ny*ny);
++ float nlen = (float) sqrt(nx*nx + ny*ny);
+ float scale = lineWidth2/nlen;
+ float mmx = nx * scale, mmy = ny * scale;
+
+@@ -246,8 +248,8 @@
+ // define the bezier curve we're computing.
+ // It is computed using the constraints that P1-P0 and P3-P2 are parallel
+ // to the arc tangents at the endpoints, and that |P1-P0|=|P3-P2|.
+- float cv = (float)((4.0 / 3.0) * Math.sqrt(0.5-cosext2) /
+- (1.0 + Math.sqrt(cosext2+0.5)));
++ float cv = (float) ((4.0 / 3.0) * sqrt(0.5-cosext2) /
++ (1.0 + sqrt(cosext2+0.5)));
+ // if clockwise, we need to negate cv.
+ if (rev) { // rev is equivalent to isCW(omx, omy, mx, my)
+ cv = -cv;
+@@ -284,28 +286,20 @@
+ false);
+ }
+
+- // Return the intersection point of the lines (x0, y0) -> (x1, y1)
+- // and (x0p, y0p) -> (x1p, y1p) in m[0] and m[1]
+- private void computeMiter(final float x0, final float y0,
+- final float x1, final float y1,
+- final float x0p, final float y0p,
+- final float x1p, final float y1p,
+- final float[] m, int off)
++ // Put the intersection point of the lines (x0, y0) -> (x1, y1)
++ // and (x0p, y0p) -> (x1p, y1p) in m[off] and m[off+1].
++ // If the lines are parallel, it will put a non finite number in m.
++ private void computeIntersection(final float x0, final float y0,
++ final float x1, final float y1,
++ final float x0p, final float y0p,
++ final float x1p, final float y1p,
++ final float[] m, int off)
+ {
+ float x10 = x1 - x0;
+ float y10 = y1 - y0;
+ float x10p = x1p - x0p;
+ float y10p = y1p - y0p;
+
+- // if this is 0, the lines are parallel. If they go in the
+- // same direction, there is no intersection so m[off] and
+- // m[off+1] will contain infinity, so no miter will be drawn.
+- // If they go in the same direction that means that the start of the
+- // current segment and the end of the previous segment have the same
+- // tangent, in which case this method won't even be involved in
+- // miter drawing because it won't be called by drawMiter (because
+- // (mx == omx && my == omy) will be true, and drawMiter will return
+- // immediately).
+ float den = x10*y10p - x10p*y10;
+ float t = x10p*(y0-y0p) - y10p*(x0-x0p);
+ t /= den;
+@@ -321,7 +315,8 @@
+ {
+ if ((mx == omx && my == omy) ||
+ (pdx == 0 && pdy == 0) ||
+- (dx == 0 && dy == 0)) {
++ (dx == 0 && dy == 0))
++ {
+ return;
+ }
+
+@@ -332,12 +327,17 @@
+ my = -my;
+ }
+
+- computeMiter((x0 - pdx) + omx, (y0 - pdy) + omy, x0 + omx, y0 + omy,
+- (dx + x0) + mx, (dy + y0) + my, x0 + mx, y0 + my,
+- miter, 0);
++ computeIntersection((x0 - pdx) + omx, (y0 - pdy) + omy, x0 + omx, y0 + omy,
++ (dx + x0) + mx, (dy + y0) + my, x0 + mx, y0 + my,
++ miter, 0);
+
+ float lenSq = (miter[0]-x0)*(miter[0]-x0) + (miter[1]-y0)*(miter[1]-y0);
+
++ // If the lines are parallel, lenSq will be either NaN or +inf
++ // (actually, I'm not sure if the latter is possible. The important
++ // thing is that -inf is not possible, because lenSq is a square).
++ // For both of those values, the comparison below will fail and
++ // no miter will be drawn, which is correct.
+ if (lenSq < miterLimitSq) {
+ emitLineTo(miter[0], miter[1], rev);
+ }
+@@ -566,8 +566,8 @@
+
+ // if p1 == p2 && p3 == p4: draw line from p1->p4, unless p1 == p4,
+ // in which case ignore if p1 == p2
+- final boolean p1eqp2 = within(x1,y1,x2,y2, 6 * Math.ulp(y2));
+- final boolean p3eqp4 = within(x3,y3,x4,y4, 6 * Math.ulp(y4));
++ final boolean p1eqp2 = within(x1,y1,x2,y2, 6 * ulp(y2));
++ final boolean p3eqp4 = within(x3,y3,x4,y4, 6 * ulp(y4));
+ if (p1eqp2 && p3eqp4) {
+ getLineOffsets(x1, y1, x4, y4, leftOff, rightOff);
+ return 4;
+@@ -583,7 +583,7 @@
+ float dotsq = (dx1 * dx4 + dy1 * dy4);
+ dotsq = dotsq * dotsq;
+ float l1sq = dx1 * dx1 + dy1 * dy1, l4sq = dx4 * dx4 + dy4 * dy4;
+- if (Helpers.within(dotsq, l1sq * l4sq, 4 * Math.ulp(dotsq))) {
++ if (Helpers.within(dotsq, l1sq * l4sq, 4 * ulp(dotsq))) {
+ getLineOffsets(x1, y1, x4, y4, leftOff, rightOff);
+ return 4;
+ }
+@@ -693,8 +693,6 @@
+ return 8;
+ }
+
+- // compute offset curves using bezier spline through t=0.5 (i.e.
+- // ComputedCurve(0.5) == IdealParallelCurve(0.5))
+ // return the kind of curve in the right and left arrays.
+ private int computeOffsetQuad(float[] pts, final int off,
+ float[] leftOff, float[] rightOff)
+@@ -703,56 +701,67 @@
+ final float x2 = pts[off + 2], y2 = pts[off + 3];
+ final float x3 = pts[off + 4], y3 = pts[off + 5];
+
+- float dx3 = x3 - x2;
+- float dy3 = y3 - y2;
+- float dx1 = x2 - x1;
+- float dy1 = y2 - y1;
++ final float dx3 = x3 - x2;
++ final float dy3 = y3 - y2;
++ final float dx1 = x2 - x1;
++ final float dy1 = y2 - y1;
+
+- // if p1=p2 or p3=p4 it means that the derivative at the endpoint
+- // vanishes, which creates problems with computeOffset. Usually
+- // this happens when this stroker object is trying to winden
+- // a curve with a cusp. What happens is that curveTo splits
+- // the input curve at the cusp, and passes it to this function.
+- // because of inaccuracies in the splitting, we consider points
+- // equal if they're very close to each other.
++ // this computes the offsets at t = 0, 1
++ computeOffset(dx1, dy1, lineWidth2, offset[0]);
++ computeOffset(dx3, dy3, lineWidth2, offset[1]);
+
+- // if p1 == p2 && p3 == p4: draw line from p1->p4, unless p1 == p4,
+- // in which case ignore.
+- final boolean p1eqp2 = within(x1,y1,x2,y2, 6 * Math.ulp(y2));
+- final boolean p2eqp3 = within(x2,y2,x3,y3, 6 * Math.ulp(y3));
+- if (p1eqp2 || p2eqp3) {
+- getLineOffsets(x1, y1, x3, y3, leftOff, rightOff);
+- return 4;
++ leftOff[0] = x1 + offset[0][0]; leftOff[1] = y1 + offset[0][1];
++ leftOff[4] = x3 + offset[1][0]; leftOff[5] = y3 + offset[1][1];
++ rightOff[0] = x1 - offset[0][0]; rightOff[1] = y1 - offset[0][1];
++ rightOff[4] = x3 - offset[1][0]; rightOff[5] = y3 - offset[1][1];
++
++ float x1p = leftOff[0]; // start
++ float y1p = leftOff[1]; // point
++ float x3p = leftOff[4]; // end
++ float y3p = leftOff[5]; // point
++
++ // Corner cases:
++ // 1. If the two control vectors are parallel, we'll end up with NaN's
++ // in leftOff (and rightOff in the body of the if below), so we'll
++ // do getLineOffsets, which is right.
++ // 2. If the first or second two points are equal, then (dx1,dy1)==(0,0)
++ // or (dx3,dy3)==(0,0), so (x1p, y1p)==(x1p+dx1, y1p+dy1)
++ // or (x3p, y3p)==(x3p-dx3, y3p-dy3), which means that
++ // computeIntersection will put NaN's in leftOff and right off, and
++ // we will do getLineOffsets, which is right.
++ computeIntersection(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, leftOff, 2);
++ float cx = leftOff[2];
++ float cy = leftOff[3];
++
++ if (!(isFinite(cx) && isFinite(cy))) {
++ // maybe the right path is not degenerate.
++ x1p = rightOff[0];
++ y1p = rightOff[1];
++ x3p = rightOff[4];
++ y3p = rightOff[5];
++ computeIntersection(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, rightOff, 2);
++ cx = rightOff[2];
++ cy = rightOff[3];
++ if (!(isFinite(cx) && isFinite(cy))) {
++ // both are degenerate. This curve is a line.
++ getLineOffsets(x1, y1, x3, y3, leftOff, rightOff);
++ return 4;
++ }
++ // {left,right}Off[0,1,4,5] are already set to the correct values.
++ leftOff[2] = 2*x2 - cx;
++ leftOff[3] = 2*y2 - cy;
++ return 6;
+ }
+
+- // if p2-p1 and p4-p3 are parallel, that must mean this curve is a line
+- float dotsq = (dx1 * dx3 + dy1 * dy3);
+- dotsq = dotsq * dotsq;
+- float l1sq = dx1 * dx1 + dy1 * dy1, l3sq = dx3 * dx3 + dy3 * dy3;
+- if (Helpers.within(dotsq, l1sq * l3sq, 4 * Math.ulp(dotsq))) {
+- getLineOffsets(x1, y1, x3, y3, leftOff, rightOff);
+- return 4;
+- }
++ // rightOff[2,3] = (x2,y2) - ((left_x2, left_y2) - (x2, y2))
++ // == 2*(x2, y2) - (left_x2, left_y2)
++ rightOff[2] = 2*x2 - cx;
++ rightOff[3] = 2*y2 - cy;
++ return 6;
++ }
+
+- // this computes the offsets at t=0, 0.5, 1, using the property that
+- // for any bezier curve the vectors p2-p1 and p4-p3 are parallel to
+- // the (dx/dt, dy/dt) vectors at the endpoints.
+- computeOffset(dx1, dy1, lineWidth2, offset[0]);
+- computeOffset(dx3, dy3, lineWidth2, offset[1]);
+- float x1p = x1 + offset[0][0]; // start
+- float y1p = y1 + offset[0][1]; // point
+- float x3p = x3 + offset[1][0]; // end
+- float y3p = y3 + offset[1][1]; // point
+-
+- computeMiter(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, leftOff, 2);
+- leftOff[0] = x1p; leftOff[1] = y1p;
+- leftOff[4] = x3p; leftOff[5] = y3p;
+- x1p = x1 - offset[0][0]; y1p = y1 - offset[0][1];
+- x3p = x3 - offset[1][0]; y3p = y3 - offset[1][1];
+- computeMiter(x1p, y1p, x1p+dx1, y1p+dy1, x3p, y3p, x3p-dx3, y3p-dy3, rightOff, 2);
+- rightOff[0] = x1p; rightOff[1] = y1p;
+- rightOff[4] = x3p; rightOff[5] = y3p;
+- return 6;
++ private static boolean isFinite(float x) {
++ return (Float.NEGATIVE_INFINITY < x && x < Float.POSITIVE_INFINITY);
+ }
+
+ // This is where the curve to be processed is put. We give it
+@@ -812,12 +821,12 @@
+ // if these vectors are too small, normalize them, to avoid future
+ // precision problems.
+ if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) {
+- float len = (float)Math.sqrt(dxs*dxs + dys*dys);
++ float len = (float) sqrt(dxs*dxs + dys*dys);
+ dxs /= len;
+ dys /= len;
+ }
+ if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) {
+- float len = (float)Math.sqrt(dxf*dxf + dyf*dyf);
++ float len = (float) sqrt(dxf*dxf + dyf*dyf);
+ dxf /= len;
+ dyf /= len;
+ }
+@@ -834,7 +843,6 @@
+ while(it.hasNext()) {
+ int curCurveOff = it.next();
+
+- kind = 0;
+ switch (type) {
+ case 8:
+ kind = computeOffsetCubic(middle, curCurveOff, lp, rp);
+@@ -843,24 +851,22 @@
+ kind = computeOffsetQuad(middle, curCurveOff, lp, rp);
+ break;
+ }
+- if (kind != 0) {
+- emitLineTo(lp[0], lp[1]);
+- switch(kind) {
+- case 8:
+- emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false);
+- emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true);
+- break;
+- case 6:
+- emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false);
+- emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true);
+- break;
+- case 4:
+- emitLineTo(lp[2], lp[3]);
+- emitLineTo(rp[0], rp[1], true);
+- break;
+- }
+- emitLineTo(rp[kind - 2], rp[kind - 1], true);
++ emitLineTo(lp[0], lp[1]);
++ switch(kind) {
++ case 8:
++ emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false);
++ emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true);
++ break;
++ case 6:
++ emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false);
++ emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true);
++ break;
++ case 4:
++ emitLineTo(lp[2], lp[3]);
++ emitLineTo(rp[0], rp[1], true);
++ break;
+ }
++ emitLineTo(rp[kind - 2], rp[kind - 1], true);
+ }
+
+ this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2;
+@@ -887,7 +893,7 @@
+ // we rotate it so that the first vector in the control polygon is
+ // parallel to the x-axis. This will ensure that rotated quarter
+ // circles won't be subdivided.
+- final float hypot = (float)Math.sqrt(x12 * x12 + y12 * y12);
++ final float hypot = (float) sqrt(x12 * x12 + y12 * y12);
+ final float cos = x12 / hypot;
+ final float sin = y12 / hypot;
+ final float x1 = cos * pts[0] + sin * pts[1];
+@@ -976,12 +982,12 @@
+ // if these vectors are too small, normalize them, to avoid future
+ // precision problems.
+ if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) {
+- float len = (float)Math.sqrt(dxs*dxs + dys*dys);
++ float len = (float) sqrt(dxs*dxs + dys*dys);
+ dxs /= len;
+ dys /= len;
+ }
+ if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) {
+- float len = (float)Math.sqrt(dxf*dxf + dyf*dyf);
++ float len = (float) sqrt(dxf*dxf + dyf*dyf);
+ dxf /= len;
+ dyf /= len;
+ }
+@@ -999,20 +1005,18 @@
+ int curCurveOff = it.next();
+
+ kind = computeOffsetCubic(middle, curCurveOff, lp, rp);
+- if (kind != 0) {
+- emitLineTo(lp[0], lp[1]);
+- switch(kind) {
+- case 8:
+- emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false);
+- emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true);
+- break;
+- case 4:
+- emitLineTo(lp[2], lp[3]);
+- emitLineTo(rp[0], rp[1], true);
+- break;
+- }
+- emitLineTo(rp[kind - 2], rp[kind - 1], true);
++ emitLineTo(lp[0], lp[1]);
++ switch(kind) {
++ case 8:
++ emitCurveTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], lp[6], lp[7], false);
++ emitCurveTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], rp[6], rp[7], true);
++ break;
++ case 4:
++ emitLineTo(lp[2], lp[3]);
++ emitLineTo(rp[0], rp[1], true);
++ break;
+ }
++ emitLineTo(rp[kind - 2], rp[kind - 1], true);
+ }
+
+ this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2;
+@@ -1050,12 +1054,12 @@
+ // if these vectors are too small, normalize them, to avoid future
+ // precision problems.
+ if (Math.abs(dxs) < 0.1f && Math.abs(dys) < 0.1f) {
+- float len = (float)Math.sqrt(dxs*dxs + dys*dys);
++ float len = (float) sqrt(dxs*dxs + dys*dys);
+ dxs /= len;
+ dys /= len;
+ }
+ if (Math.abs(dxf) < 0.1f && Math.abs(dyf) < 0.1f) {
+- float len = (float)Math.sqrt(dxf*dxf + dyf*dyf);
++ float len = (float) sqrt(dxf*dxf + dyf*dyf);
+ dxf /= len;
+ dyf /= len;
+ }
+@@ -1073,20 +1077,18 @@
+ int curCurveOff = it.next();
+
+ kind = computeOffsetQuad(middle, curCurveOff, lp, rp);
+- if (kind != 0) {
+- emitLineTo(lp[0], lp[1]);
+- switch(kind) {
+- case 6:
+- emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false);
+- emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true);
+- break;
+- case 4:
+- emitLineTo(lp[2], lp[3]);
+- emitLineTo(rp[0], rp[1], true);
+- break;
+- }
+- emitLineTo(rp[kind - 2], rp[kind - 1], true);
++ emitLineTo(lp[0], lp[1]);
++ switch(kind) {
++ case 6:
++ emitQuadTo(lp[0], lp[1], lp[2], lp[3], lp[4], lp[5], false);
++ emitQuadTo(rp[0], rp[1], rp[2], rp[3], rp[4], rp[5], true);
++ break;
++ case 4:
++ emitLineTo(lp[2], lp[3]);
++ emitLineTo(rp[0], rp[1], true);
++ break;
+ }
++ emitLineTo(rp[kind - 2], rp[kind - 1], true);
+ }
+
+ this.cmx = (lp[kind - 2] - rp[kind - 2]) / 2;
+diff -r a07c9e09b4ca -r 24f474ad1703 test/sun/java2d/pisces/Test7036754.java
+--- /dev/null Thu Jan 01 00:00:00 1970 +0000
++++ openjdk/jdk/test/sun/java2d/pisces/Test7036754.java Thu Apr 28 08:55:19 2011 -0400
+@@ -0,0 +1,58 @@
++/*
++ * 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 7036754
++ *
++ * @summary Verifies that there are no non-finite numbers when stroking
More information about the distro-pkg-dev
mailing list