--- old/src/java.desktop/share/classes/sun/java2d/pipe/BufferedContext.java 2016-05-02 22:10:57.000000000 +0300 +++ new/src/java.desktop/share/classes/sun/java2d/pipe/BufferedContext.java 2016-05-02 22:10:57.000000000 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2016, 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 @@ -38,6 +38,8 @@ import static sun.java2d.pipe.BufferedRenderPipe.BYTES_PER_SPAN; import java.lang.annotation.Native; +import java.lang.ref.Reference; +import java.lang.ref.WeakReference; /** * Base context class for managing state in a single-threaded rendering @@ -87,11 +89,11 @@ */ protected static BufferedContext currentContext; - private AccelSurface validatedSrcData; - private AccelSurface validatedDstData; - private Region validatedClip; - private Composite validatedComp; - private Paint validatedPaint; + private Reference validSrcDataRef = new WeakReference<>(null); + private Reference validDstDataRef = new WeakReference<>(null); + private Reference validClipRef = new WeakReference<>(null); + private Reference validCompRef = new WeakReference<>(null); + private Reference validPaintRef = new WeakReference<>(null); // renamed from isValidatedPaintAColor as part of a work around for 6764257 private boolean isValidatedPaintJustAColor; private int validatedRGB; @@ -127,9 +129,9 @@ int flags) { // assert rq.lock.isHeldByCurrentThread(); - BufferedContext d3dc = dstData.getContext(); - d3dc.validate(srcData, dstData, - clip, comp, xform, paint, sg2d, flags); + BufferedContext context = dstData.getContext(); + context.validate(srcData, dstData, + clip, comp, xform, paint, sg2d, flags); } /** @@ -200,13 +202,15 @@ updatePaint = true; isValidatedPaintJustAColor = true; } - } else if (validatedPaint != paint) { + } else if (validPaintRef.get() != paint) { updatePaint = true; // this should be set when we are switching from paint to color // in which case this condition will be true isValidatedPaintJustAColor = false; } + final AccelSurface validatedSrcData = validSrcDataRef.get(); + final AccelSurface validatedDstData = validDstDataRef.get(); if ((currentContext != this) || (srcData != validatedSrcData) || (dstData != validatedDstData)) @@ -228,11 +232,12 @@ setSurfaces(srcData, dstData); currentContext = this; - validatedSrcData = srcData; - validatedDstData = dstData; + validSrcDataRef = new WeakReference<>(srcData); + validDstDataRef = new WeakReference<>(dstData); } // validate clip + final Region validatedClip = validClipRef.get(); if ((clip != validatedClip) || updateClip) { if (clip != null) { if (updateClip || @@ -248,13 +253,13 @@ } else { resetClip(); } - validatedClip = clip; + validClipRef = new WeakReference<>(clip); } // validate composite (note that a change in the context flags // may require us to update the composite state, even if the // composite has not changed) - if ((comp != validatedComp) || (flags != validatedFlags)) { + if ((comp != validCompRef.get()) || (flags != validatedFlags)) { if (comp != null) { setComposite(comp, flags); } else { @@ -263,7 +268,7 @@ // the paint state is dependent on the composite state, so make // sure we update the color below updatePaint = true; - validatedComp = comp; + validCompRef = new WeakReference<>(comp); validatedFlags = flags; } @@ -297,7 +302,7 @@ } else { BufferedPaints.resetPaint(rq); } - validatedPaint = paint; + validPaintRef = new WeakReference<>(paint); } // mark dstData dirty @@ -315,9 +320,9 @@ * @see RenderQueue#lock * @see RenderQueue#unlock */ - public void invalidateSurfaces() { - validatedSrcData = null; - validatedDstData = null; + private void invalidateSurfaces() { + validSrcDataRef.clear(); + validDstDataRef.clear(); } private void setSurfaces(AccelSurface srcData, @@ -434,9 +439,9 @@ resetClip(); BufferedPaints.resetPaint(rq); invalidateSurfaces(); - validatedComp = null; - validatedClip = null; - validatedPaint = null; + validCompRef.clear(); + validClipRef.clear(); + validPaintRef.clear(); isValidatedPaintJustAColor = false; xformInUse = false; } --- old/test/java/awt/Window/WindowsLeak/WindowsLeak.java 2016-05-02 22:10:58.000000000 +0300 +++ new/test/java/awt/Window/WindowsLeak/WindowsLeak.java 2016-05-02 22:10:58.000000000 +0300 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2016, 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 @@ -23,42 +23,42 @@ /* * @test - * @bug 8013563 + * @bug 8013563 8028486 * @summary Tests that windows are removed from windows list + * @library /javax/swing/regtesthelpers * @modules java.desktop/sun.awt + * java.desktop/sun.java2d + * @build Util * @run main/othervm -Xms32M -Xmx32M WindowsLeak */ -import java.awt.*; -import sun.awt.AppContext; - +import java.awt.Frame; +import java.awt.Robot; +import java.awt.Window; import java.lang.ref.WeakReference; - import java.util.Vector; +import sun.awt.AppContext; +import sun.java2d.Disposer; + public class WindowsLeak { - public static void main(String[] args) { - for (int i = 0; i < 100; i++) - { + private static volatile boolean disposerPhantomComplete; + + public static void main(String[] args) throws Exception { + Robot r = new Robot(); + for (int i = 0; i < 100; i++) { Frame f = new Frame(); f.pack(); f.dispose(); } + r.waitForIdle(); + + Disposer.addRecord(new Object(), () -> disposerPhantomComplete = true); - Vector garbage = new Vector(); - while (true) - { - try - { - garbage.add(new byte[1000]); - } - catch (OutOfMemoryError e) - { - break; - } + while (!disposerPhantomComplete) { + Util.generateOOME(); } - garbage = null; Vector> windowList = (Vector>) AppContext.getAppContext().get(Window.class);