IDEA-155423 [follow-up]

- Rolled back the original patch for this issue.
- Instead, applied the latest patch from OpenJDK 9, fixing JDK-8028486.
- Rolled back the patch for IDEA-156490 as it's no longer needed.
diff --git a/src/macosx/classes/sun/java2d/opengl/CGLLayer.java b/src/macosx/classes/sun/java2d/opengl/CGLLayer.java
index d80c6a6..32a099c 100644
--- a/src/macosx/classes/sun/java2d/opengl/CGLLayer.java
+++ b/src/macosx/classes/sun/java2d/opengl/CGLLayer.java
@@ -81,7 +81,7 @@
     }
 
     public SurfaceData replaceSurfaceData() {
-        if (peer == null || getBounds().isEmpty()) {
+        if (getBounds().isEmpty()) {
             surfaceData = NullSurfaceData.theInstance;
             return surfaceData;
         }
@@ -116,8 +116,6 @@
 
     @Override
     public void dispose() {
-        surfaceData = null;
-        peer = null;
         // break the connection between the layer and the buffer
         validate(null);
         super.dispose();
diff --git a/src/share/classes/sun/java2d/pipe/BufferedContext.java b/src/share/classes/sun/java2d/pipe/BufferedContext.java
index 4513c67..3475c43 100644
--- a/src/share/classes/sun/java2d/pipe/BufferedContext.java
+++ b/src/share/classes/sun/java2d/pipe/BufferedContext.java
@@ -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<AccelSurface> validSrcDataRef = new WeakReference<>(null);
+    private Reference<AccelSurface> validDstDataRef = new WeakReference<>(null);
+    private Reference<Region> validClipRef = new WeakReference<>(null);
+    private Reference<Composite> validCompRef = new WeakReference<>(null);
+    private Reference<Paint> 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;
     }
diff --git a/test/java/awt/Window/WindowsLeak/WindowsLeak.java b/test/java/awt/Window/WindowsLeak/WindowsLeak.java
index dd776a8..0c25ede 100644
--- a/test/java/awt/Window/WindowsLeak/WindowsLeak.java
+++ b/test/java/awt/Window/WindowsLeak/WindowsLeak.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 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,41 +23,40 @@
 
 /*
  * @test
- * @bug 8013563
+ * @bug 8013563 8028486
  * @summary Tests that windows are removed from windows list
+ * @library /javax/swing/regtesthelpers
+ * @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();
 
-        Vector garbage = new Vector();
-        while (true)
-        {
-            try
-            {
-                garbage.add(new byte[1000]);
-            }
-            catch (OutOfMemoryError e)
-            {
-                break;
-            }
+        Disposer.addRecord(new Object(), () -> disposerPhantomComplete = true);
+
+        while (!disposerPhantomComplete) {
+            Util.generateOOME();
         }
-        garbage = null;
 
         Vector<WeakReference<Window>> windowList =
                         (Vector<WeakReference<Window>>) AppContext.getAppContext().get(Window.class);