changeset 12123:ecdb635eaf48 jdk8u121-b03

Merge
author asaha
date Mon, 03 Oct 2016 10:56:07 -0700
parents 1b35fabb3d88 920bb0a994d1
children 2f27f84788e1
files
diffstat 17 files changed, 198 insertions(+), 139 deletions(-) [+]
line wrap: on
line diff
--- a/src/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/classes/com/apple/eawt/_AppMenuBarHandler.java	Mon Oct 03 10:56:07 2016 -0700
@@ -121,7 +121,7 @@
         }
 
         // grab the pointer to the CMenuBar, and retain it in native
-        nativeSetDefaultMenuBar(((CMenuBar)peer).getModel());
+        ((CMenuBar) peer).execute(_AppMenuBarHandler::nativeSetDefaultMenuBar);
     }
 
     void setAboutMenuItemVisible(final boolean present) {
--- a/src/macosx/classes/sun/lwawt/macosx/CCheckboxMenuItem.java	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CCheckboxMenuItem.java	Mon Oct 03 10:56:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -26,29 +26,28 @@
 package sun.lwawt.macosx;
 
 import java.awt.CheckboxMenuItem;
-import java.awt.EventQueue;
 import java.awt.event.ItemEvent;
 import java.awt.peer.CheckboxMenuItemPeer;
 
 import sun.awt.SunToolkit;
 
 public class CCheckboxMenuItem extends CMenuItem implements CheckboxMenuItemPeer {
-    boolean fAutoToggle = true;
-    boolean fIsIndeterminate = false;
+    volatile boolean fAutoToggle = true;
+    volatile boolean fIsIndeterminate = false;
 
     private native void nativeSetState(long modelPtr, boolean state);
     private native void nativeSetIsCheckbox(long modelPtr);
 
-    CCheckboxMenuItem(CheckboxMenuItem target) {
+    CCheckboxMenuItem(final CheckboxMenuItem target) {
         super(target);
-        nativeSetIsCheckbox(getModel());
+        execute(this::nativeSetIsCheckbox);
         setState(target.getState());
     }
 
     // MenuItemPeer implementation
     @Override
-    public void setState(boolean state) {
-        nativeSetState(getModel(), state);
+    public void setState(final boolean state) {
+        execute(ptr -> nativeSetState(ptr, state));
     }
 
     public void handleAction(final boolean state) {
--- a/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java	Mon Oct 03 10:56:07 2016 -0700
@@ -23,7 +23,6 @@
  * questions.
  */
 
-
 package sun.lwawt.macosx;
 
 /**
@@ -34,6 +33,7 @@
     private static native void nativeCFRelease(final long ptr, final boolean disposeOnAppKitThread);
 
     private final boolean disposeOnAppKitThread;
+    // TODO this pointer should be private and accessed via CFNativeAction class
     protected volatile long ptr;
 
     /**
@@ -70,8 +70,72 @@
         nativeCFRelease(oldPtr, disposeOnAppKitThread); // perform outside of the synchronized block
     }
 
+    /**
+     * The interface which allows to execute some native operations with
+     * assumption that the native pointer will be valid till the end.
+     */
+    public interface CFNativeAction {
+
+        /**
+         * The native operation should be called from this method.
+         *
+         * @param  ptr the pointer to the native data
+         */
+        void run(long ptr);
+    }
+
+    /**
+     * The interface which allows to execute some native operations and get a
+     * result with assumption that the native pointer will be valid till the
+     * end.
+     */
+    interface CFNativeActionGet {
+
+        /**
+         * The native operation should be called from this method.
+         *
+         * @param  ptr the pointer to the native data
+         * @return result of the native operation
+         */
+        long run(long ptr);
+    }
+
+    /**
+     * This is utility method which should be used instead of the direct access
+     * to the {@link #ptr}, because this method guaranteed that the pointer will
+     * not be zero and will be valid till the end of the operation.It is highly
+     * recomended to not use any external lock in action. If the current
+     * {@link #ptr} is {@code 0} then action will be ignored.
+     *
+     * @param  action The native operation
+     */
+    public final synchronized void execute(final CFNativeAction action) {
+        if (ptr != 0) {
+            action.run(ptr);
+        }
+    }
+
+    /**
+     * This is utility method which should be used instead of the direct access
+     * to the {@link #ptr}, because this method guaranteed that the pointer will
+     * not be zero and will be valid till the end of the operation. It is highly
+     * recomended to not use any external lock in action. If the current
+     * {@link #ptr} is {@code 0} then action will be ignored and {@code} is
+     * returned.
+     *
+     * @param  action the native operation
+     * @return result of the native operation, usually the native pointer to
+     *         some other data
+     */
+    final synchronized long executeGet(final CFNativeActionGet action) {
+        if (ptr != 0) {
+            return action.run(ptr);
+        }
+        return 0;
+    }
+
     @Override
-    protected void finalize() throws Throwable {
+    protected final void finalize() throws Throwable {
         dispose();
     }
 }
--- a/src/macosx/classes/sun/lwawt/macosx/CMenu.java	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CMenu.java	Mon Oct 03 10:56:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -25,7 +25,9 @@
 
 package sun.lwawt.macosx;
 
-import java.awt.*;
+import java.awt.Menu;
+import java.awt.MenuBar;
+import java.awt.MenuItem;
 import java.awt.peer.MenuItemPeer;
 import java.awt.peer.MenuPeer;
 
@@ -37,7 +39,7 @@
 
     // This way we avoiding invocation of the setters twice
     @Override
-    protected void initialize(MenuItem target) {
+    protected final void initialize(MenuItem target) {
         setLabel(target.getLabel());
         setEnabled(target.isEnabled());
     }
@@ -57,52 +59,50 @@
     }
 
     @Override
-    protected long createModel() {
+    long createModel() {
         CMenuComponent parent = (CMenuComponent)
             LWCToolkit.targetToPeer(getTarget().getParent());
 
-        if (parent instanceof CMenu ||
-            parent instanceof CPopupMenu)
-        {
-            return nativeCreateSubMenu(parent.getModel());
-        } else if (parent instanceof CMenuBar) {
+        if (parent instanceof CMenu) {
+            return parent.executeGet(this::nativeCreateSubMenu);
+        }
+        if (parent instanceof CMenuBar) {
             MenuBar parentContainer = (MenuBar)getTarget().getParent();
             boolean isHelpMenu = parentContainer.getHelpMenu() == getTarget();
             int insertionLocation = ((CMenuBar)parent).getNextInsertionIndex();
-            return nativeCreateMenu(parent.getModel(),
-                                    isHelpMenu, insertionLocation);
-        } else {
-            throw new InternalError("Parent must be CMenu or CMenuBar");
+            return parent.executeGet(ptr -> nativeCreateMenu(ptr, isHelpMenu,
+                                                             insertionLocation));
         }
+        throw new InternalError("Parent must be CMenu or CMenuBar");
     }
 
     @Override
-    public void addItem(MenuItem item) {
+    public final void addItem(MenuItem item) {
         // Nothing to do here -- we added it when we created the
         // menu item's peer.
     }
 
     @Override
-    public void delItem(int index) {
-        nativeDeleteItem(getModel(), index);
+    public final void delItem(final int index) {
+        execute(ptr -> nativeDeleteItem(ptr, index));
     }
 
     @Override
-    public void setLabel(String label) {
-        nativeSetMenuTitle(getModel(), label);
+    public final void setLabel(final String label) {
+        execute(ptr->nativeSetMenuTitle(ptr, label));
         super.setLabel(label);
     }
 
     // Note that addSeparator is never called directly from java.awt.Menu,
     // though it is required in the MenuPeer interface.
     @Override
-    public void addSeparator() {
-        nativeAddSeparator(getModel());
+    public final void addSeparator() {
+        execute(this::nativeAddSeparator);
     }
 
     // Used by ScreenMenuBar to get to the native menu for event handling.
-    public long getNativeMenu() {
-        return nativeGetNSMenu(getModel());
+    public final long getNativeMenu() {
+        return executeGet(this::nativeGetNSMenu);
     }
 
     private native long nativeCreateMenu(long parentMenuPtr,
--- a/src/macosx/classes/sun/lwawt/macosx/CMenuBar.java	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CMenuBar.java	Mon Oct 03 10:56:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -29,7 +29,9 @@
 import java.awt.MenuBar;
 import java.awt.peer.MenuBarPeer;
 
-public class CMenuBar extends CMenuComponent implements MenuBarPeer {
+import sun.awt.AWTAccessor;
+
+public final class CMenuBar extends CMenuComponent implements MenuBarPeer {
 
     private int nextInsertionIndex = -1;
 
@@ -38,15 +40,16 @@
     }
 
     @Override
-    protected long createModel() {
+    long createModel() {
         return nativeCreateMenuBar();
     }
 
     @Override
-    public void addHelpMenu(Menu m) {
-        CMenu cMenu = (CMenu)m.getPeer();
-        nativeSetHelpMenu(getModel(), cMenu.getModel());
-    }
+    public void addHelpMenu(final Menu m) {
+        final CMenu cMenu = AWTAccessor.getMenuComponentAccessor().getPeer(m);
+        execute(parentPtr -> cMenu.execute(
+                menuPtr -> nativeSetHelpMenu(parentPtr, menuPtr)));
+     }
 
     public int getNextInsertionIndex() {
         return nextInsertionIndex;
@@ -63,8 +66,8 @@
     }
 
     @Override
-    public void delMenu(int index) {
-        nativeDelMenu(getModel(), index);
+    public void delMenu(final int index) {
+        execute(ptr -> nativeDelMenu(ptr, index));
     }
 
     private native long nativeCreateMenuBar();
--- a/src/macosx/classes/sun/lwawt/macosx/CMenuComponent.java	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CMenuComponent.java	Mon Oct 03 10:56:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -29,36 +29,32 @@
 import java.awt.MenuComponent;
 import java.awt.peer.MenuComponentPeer;
 
-public abstract class CMenuComponent implements MenuComponentPeer {
+abstract class CMenuComponent extends CFRetainedResource
+        implements MenuComponentPeer {
 
-    private MenuComponent target;
-    private long modelPtr;
+    private final MenuComponent target;
 
-    CMenuComponent(MenuComponent target) {
+    CMenuComponent(final MenuComponent target) {
+        super(0, true);
         this.target = target;
-        this.modelPtr = createModel();
+        setPtr(createModel());
     }
 
-    MenuComponent getTarget() {
+    final MenuComponent getTarget() {
         return target;
     }
 
-    public long getModel() {
-        return modelPtr;
+    abstract long createModel();
+
+    @Override
+    public final void dispose() {
+        super.dispose();
+        LWCToolkit.targetDisposedPeer(target, this);
     }
 
-    protected abstract long createModel();
-
-    public void dispose() {
-        LWCToolkit.targetDisposedPeer(target, this);
-        nativeDispose(modelPtr);
-        target = null;
-    }
-
-    private native void nativeDispose(long modelPtr);
-
     // 1.5 peer method
-    public void setFont(Font f) {
+    @Override
+    public final void setFont(final Font f) {
         // no-op, as we don't currently support menu fonts
         // c.f. radar 4032912
     }
--- a/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CMenuItem.java	Mon Oct 03 10:56:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -25,16 +25,17 @@
 
 package sun.lwawt.macosx;
 
+import java.awt.MenuItem;
+import java.awt.MenuShortcut;
+import java.awt.event.ActionEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.peer.MenuItemPeer;
+import java.util.concurrent.atomic.AtomicBoolean;
+
 import sun.awt.SunToolkit;
 import sun.lwawt.LWToolkit;
 
-import java.awt.MenuContainer;
-import java.awt.MenuItem;
-import java.awt.MenuShortcut;
-import java.awt.event.*;
-import java.awt.peer.MenuItemPeer;
-import java.util.concurrent.atomic.AtomicBoolean;
-
 public class CMenuItem extends CMenuComponent implements MenuItemPeer {
 
     private final AtomicBoolean enabled = new AtomicBoolean(true);
@@ -58,9 +59,9 @@
     }
 
     @Override
-    protected long createModel() {
+    long createModel() {
         CMenuComponent parent = (CMenuComponent)LWToolkit.targetToPeer(getTarget().getParent());
-        return nativeCreate(parent.getModel(), isSeparator());
+        return parent.executeGet(ptr->nativeCreate(ptr, isSeparator()));
     }
 
     public void setLabel(String label, char keyChar, int keyCode, int modifiers) {
@@ -90,7 +91,12 @@
             keyChar = 0;
         }
 
-        nativeSetLabel(getModel(), label, keyChar, keyCode, keyMask);
+        final String finalLabel = label;
+        final char finalKeyChar = keyChar;
+        final int finalKeyCode = keyCode;
+        final int finalKeyMask = keyMask;
+        execute(ptr -> nativeSetLabel(ptr, finalLabel, finalKeyChar,
+                                      finalKeyCode, finalKeyMask));
     }
 
     @Override
@@ -105,16 +111,16 @@
      * There isn't a need to expose this except in a instanceof because
      * it isn't defined in the peer api.
      */
-    public void setImage(java.awt.Image img) {
+    public final void setImage(final java.awt.Image img) {
         CImage cimg = CImage.getCreator().createFromImage(img);
-        nativeSetImage(getModel(), cimg == null ? 0L : cimg.ptr);
+        execute(ptr -> nativeSetImage(ptr, cimg == null ? 0L : cimg.ptr));
     }
 
     /**
      * New API for tooltips
      */
-    public void setToolTipText(String text) {
-        nativeSetTooltip(getModel(), text);
+    public final void setToolTipText(final String text) {
+        execute(ptr -> nativeSetTooltip(ptr, text));
     }
 
 //    @Override
@@ -138,7 +144,8 @@
             b &= ((CMenuItem) parent).isEnabled();
         }
         if (enabled.compareAndSet(!b, b)) {
-            nativeSetEnabled(getModel(), b);
+            final boolean finalB = b;
+            execute(ptr->nativeSetEnabled(ptr, finalB));
         }
     }
 
--- a/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java	Mon Oct 03 10:56:07 2016 -0700
@@ -419,7 +419,7 @@
         final long nsWindowPtr = getNSWindowPtr();
         CMenuBar mbPeer = (CMenuBar)LWToolkit.targetToPeer(mb);
         if (mbPeer != null) {
-            nativeSetNSWindowMenuBar(nsWindowPtr, mbPeer.getModel());
+            mbPeer.execute(ptr -> nativeSetNSWindowMenuBar(nsWindowPtr, ptr));
         } else {
             nativeSetNSWindowMenuBar(nsWindowPtr, 0);
         }
--- a/src/macosx/classes/sun/lwawt/macosx/CPopupMenu.java	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CPopupMenu.java	Mon Oct 03 10:56:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -25,18 +25,20 @@
 
 package sun.lwawt.macosx;
 
-import java.awt.*;
+import java.awt.Component;
+import java.awt.Event;
+import java.awt.Point;
+import java.awt.PopupMenu;
 import java.awt.peer.PopupMenuPeer;
 
-import sun.lwawt.LWWindowPeer;
+final class CPopupMenu extends CMenu implements PopupMenuPeer {
 
-public class CPopupMenu extends CMenu implements PopupMenuPeer {
     CPopupMenu(PopupMenu target) {
         super(target);
     }
 
     @Override
-    protected long createModel() {
+    long createModel() {
         return nativeCreatePopupMenu();
     }
 
@@ -50,7 +52,7 @@
             Point loc = origin.getLocationOnScreen();
             e.x += loc.x;
             e.y += loc.y;
-            nativeShowPopupMenu(getModel(), e.x, e.y);
+            execute(ptr -> nativeShowPopupMenu(ptr, e.x, e.y));
         }
     }
 }
--- a/src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/classes/sun/lwawt/macosx/CTrayIcon.java	Mon Oct 03 10:56:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -104,7 +104,10 @@
                 return 0L;
             }
         }
-        return checkAndCreatePopupPeer().getModel();
+        // This method is executed on Appkit, so if ptr is not zero means that,
+        // it is still not deallocated(even if we call NSApp postRunnableEvent)
+        // and sent CFRelease to the native queue
+        return checkAndCreatePopupPeer().ptr;
     }
 
     /**
--- a/src/macosx/native/sun/awt/CMenu.m	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/native/sun/awt/CMenu.m	Mon Oct 03 10:56:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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,7 +38,7 @@
 - (id)initWithPeer:(jobject)peer {
 AWT_ASSERT_APPKIT_THREAD;
     // Create the new NSMenu
-    self = [super initWithPeer:peer asSeparator:[NSNumber numberWithBool:NO]];
+    self = [super initWithPeer:peer asSeparator:NO];
     if (self) {
         fMenu = [NSMenu javaMenuWithTitle:@""];
         [fMenu retain];
@@ -134,14 +134,13 @@
 
 CMenu * createCMenu (jobject cPeerObjGlobal) {
 
-    CMenu *aCMenu = nil;
+    __block CMenu *aCMenu = nil;
 
-    // We use an array here only to be able to get a return value
-    NSMutableArray *args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], nil];
+    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
 
-    [ThreadUtilities performOnMainThread:@selector(_create_OnAppKitThread:) on:[CMenu alloc] withObject:args waitUntilDone:YES];
-
-    aCMenu = (CMenu *)[args objectAtIndex: 0];
+        aCMenu = [[CMenu alloc] initWithPeer:cPeerObjGlobal];
+        // the aCMenu is released in CMenuComponent.dispose()
+    }];
 
     if (aCMenu == nil) {
         return 0L;
--- a/src/macosx/native/sun/awt/CMenuBar.m	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/native/sun/awt/CMenuBar.m	Mon Oct 03 10:56:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -383,27 +383,20 @@
 Java_sun_lwawt_macosx_CMenuBar_nativeCreateMenuBar
     (JNIEnv *env, jobject peer)
 {
-    CMenuBar *aCMenuBar = nil;
+    __block CMenuBar *aCMenuBar = nil;
     JNF_COCOA_ENTER(env);
 
     jobject cPeerObjGlobal = (*env)->NewGlobalRef(env, peer);
 
-    // We use an array here only to be able to get a return value
-    NSMutableArray *args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], nil];
+    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
 
-    [ThreadUtilities performOnMainThread:@selector(_create_OnAppKitThread:) on:[CMenuBar alloc] withObject:args waitUntilDone:YES];
-
-    aCMenuBar = (CMenuBar *)[args objectAtIndex: 0];
-
+        aCMenuBar = [[CMenuBar alloc] initWithPeer:cPeerObjGlobal];
+        // the aCMenuBar is released in CMenuComponent.dispose()
+    }];
     if (aCMenuBar == nil) {
         return 0L;
     }
 
-    // [args release];
-
-    // A strange memory managment after that.
-
-
     JNF_COCOA_EXIT(env);
     if (aCMenuBar) {
         CFRetain(aCMenuBar); // GC
--- a/src/macosx/native/sun/awt/CMenuComponent.m	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/native/sun/awt/CMenuComponent.m	Mon Oct 03 10:56:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
--- a/src/macosx/native/sun/awt/CMenuItem.h	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/native/sun/awt/CMenuItem.h	Mon Oct 03 10:56:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -32,7 +32,7 @@
 }
 
 // Setup
-- (id) initWithPeer:(jobject)peer asSeparator: (NSNumber *) asSeparator;
+- (id) initWithPeer:(jobject)peer asSeparator: (BOOL) asSeparator;
 - (void) setIsCheckbox;
 
 // Events
--- a/src/macosx/native/sun/awt/CMenuItem.m	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/macosx/native/sun/awt/CMenuItem.m	Mon Oct 03 10:56:07 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 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
@@ -39,11 +39,11 @@
 
 @implementation CMenuItem
 
-- (id) initWithPeer:(jobject)peer asSeparator: (NSNumber *) asSeparator{
+- (id) initWithPeer:(jobject)peer asSeparator: (BOOL) asSeparator{
 AWT_ASSERT_APPKIT_THREAD;
     self = [super initWithPeer:peer];
     if (self) {
-        if ([asSeparator boolValue]) {
+        if (asSeparator) {
             fMenuItem = (NSMenuItem*)[NSMenuItem separatorItem];
             [fMenuItem retain];
         } else {
@@ -199,12 +199,9 @@
     }];
 }
 
-- (void)cleanup {
+- (void)dealloc {
     [fMenuItem setAction:NULL];
     [fMenuItem setTarget:nil];
-}
-
-- (void)dealloc {
     [fMenuItem release];
     fMenuItem = nil;
 
@@ -223,14 +220,6 @@
     fIsCheckbox = YES;
 }
 
-- (void) _createMenuItem_OnAppKitThread: (NSMutableArray *)argValue {
-    jobject cPeerObjGlobal = (jobject)[[argValue objectAtIndex: 0] pointerValue];
-    NSNumber * asSeparator = (NSNumber *)[argValue objectAtIndex: 1];
-    CMenuItem *aCMenuItem = [self initWithPeer: cPeerObjGlobal asSeparator: asSeparator];
-    [argValue removeAllObjects];
-    [argValue addObject: aCMenuItem];
-}
-
 - (NSString *)description {
     return [NSString stringWithFormat:@"CMenuItem[ %@ ]", fMenuItem];
 }
@@ -392,24 +381,18 @@
     (JNIEnv *env, jobject peer, jlong parentCMenuObj, jboolean isSeparator)
 {
 
-    CMenuItem *aCMenuItem = nil;
+    __block CMenuItem *aCMenuItem = nil;
+    BOOL asSeparator = (isSeparator == JNI_TRUE) ? YES: NO;
     CMenu *parentCMenu = (CMenu *)jlong_to_ptr(parentCMenuObj);
 JNF_COCOA_ENTER(env);
 
     jobject cPeerObjGlobal = (*env)->NewGlobalRef(env, peer);
 
-    NSMutableArray *args = nil;
-
-    // Create a new item....
-    if (isSeparator == JNI_TRUE) {
-        args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:YES],  nil];
-    } else {
-        args = [[NSMutableArray alloc] initWithObjects:[NSValue valueWithBytes:&cPeerObjGlobal objCType:@encode(jobject)], [NSNumber numberWithBool:NO],  nil];
-    }
-
-    [ThreadUtilities performOnMainThread:@selector(_createMenuItem_OnAppKitThread:) on:[CMenuItem alloc] withObject:args waitUntilDone:YES];
-
-    aCMenuItem = (CMenuItem *)[args objectAtIndex: 0];
+     [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+        aCMenuItem = [[CMenuItem alloc] initWithPeer: cPeerObjGlobal
+                                         asSeparator: asSeparator];
+        // the CMenuItem is released in CMenuComponent.dispose()
+    }];
 
     if (aCMenuItem == nil) {
         return 0L;
--- a/src/share/classes/java/awt/MenuComponent.java	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/share/classes/java/awt/MenuComponent.java	Mon Oct 03 10:56:07 2016 -0700
@@ -145,6 +145,10 @@
                 public Font getFont_NoClientCode(MenuComponent menuComp) {
                     return menuComp.getFont_NoClientCode();
                 }
+                @SuppressWarnings("unchecked")
+                public <T extends MenuComponentPeer> T getPeer(MenuComponent menuComp) {
+                    return (T) menuComp.peer;
+                }
             });
     }
 
--- a/src/share/classes/sun/awt/AWTAccessor.java	Mon Oct 03 08:45:53 2016 -0700
+++ b/src/share/classes/sun/awt/AWTAccessor.java	Mon Oct 03 10:56:07 2016 -0700
@@ -36,6 +36,7 @@
 import java.awt.event.KeyEvent;
 import java.awt.geom.Point2D;
 import java.awt.peer.ComponentPeer;
+import java.awt.peer.MenuComponentPeer;
 
 import java.lang.reflect.InvocationTargetException;
 import java.security.AccessControlContext;
@@ -463,6 +464,11 @@
          * Gets the font used for this menu component.
          */
         Font getFont_NoClientCode(MenuComponent menuComp);
+
+        /**
+         * Returns the peer of the menu component.
+         */
+        <T extends MenuComponentPeer> T getPeer(MenuComponent menuComp);
     }
 
     /**