8167110: Windows peering issue
authorserb
Sat, 19 Nov 2016 13:10:18 +0300
changeset 44754 cc5c1fb080a3
parent 44753 37d4270a2a8d
child 44755 e16b506a60b2
8167110: Windows peering issue Reviewed-by: ssadetsky, mschoene, prr
jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java
jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java
jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp
jdk/src/java.desktop/windows/native/libawt/windows/awt_Menu.cpp
jdk/src/java.desktop/windows/native/libawt/windows/awt_Menu.h
jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp
jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h
jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp
jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.h
jdk/src/java.desktop/windows/native/libawt/windows/awt_PopupMenu.cpp
jdk/src/java.desktop/windows/native/libawt/windows/awt_PopupMenu.h
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java	Thu Oct 20 15:10:52 2016 +0100
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java	Sat Nov 19 13:10:18 2016 +0300
@@ -71,7 +71,7 @@
         enable(false);
     }
 
-    public void readShortcutLabel() {
+    private void readShortcutLabel() {
         //Fix for 6288578: PIT. Windows: Shortcuts displayed for the menuitems in a popup menu
         WMenuPeer ancestor = parent;
         while (ancestor != null && !(ancestor instanceof WMenuBarPeer)) {
@@ -115,7 +115,7 @@
         readShortcutLabel();
     }
 
-    protected void checkMenuCreation()
+    void checkMenuCreation()
     {
         // fix for 5088782: check if menu peer is created successfully
         if (pData == 0)
--- a/jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java	Thu Oct 20 15:10:52 2016 +0100
+++ b/jdk/src/java.desktop/windows/classes/sun/awt/windows/WObjectPeer.java	Sat Nov 19 13:10:18 2016 +0300
@@ -36,14 +36,14 @@
     // The Windows handle for the native widget.
     volatile long pData;
     // if the native peer has been destroyed
-    volatile boolean destroyed = false;
+    private volatile boolean destroyed;
     // The associated AWT object.
-    Object target;
+    volatile Object target;
 
     private volatile boolean disposed;
 
     // set from JNI if any errors in creating the peer occur
-    protected Error createError = null;
+    volatile Error createError = null;
 
     // used to synchronize the state of this peer
     private final Object stateLock = new Object();
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Thu Oct 20 15:10:52 2016 +0100
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp	Sat Nov 19 13:10:18 2016 +0300
@@ -4220,7 +4220,7 @@
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 
     if (drawInfo.CtlType == ODT_MENU) {
-        if (drawInfo.itemData != 0) {
+        if (IsMenu((HMENU)drawInfo.hwndItem) && drawInfo.itemData != 0) {
             AwtMenu* menu = (AwtMenu*)(drawInfo.itemData);
             menu->DrawItem(drawInfo);
         }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Menu.cpp	Thu Oct 20 15:10:52 2016 +0100
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Menu.cpp	Sat Nov 19 13:10:18 2016 +0300
@@ -34,6 +34,13 @@
 /* IMPORTANT! Read the README.JNI file for notes on JNI converted AWT code.
  */
 
+/***********************************************************************/
+// struct for _DelItem() method
+struct DelItemStruct {
+    jobject menuitem;
+    jint index;
+};
+
 /************************************************************************
  * AwtMenuItem fields
  */
@@ -64,7 +71,6 @@
         ::DestroyMenu(m_hMenu);
         m_hMenu = NULL;
     }
-
     AwtMenuItem::Dispose();
 }
 
@@ -73,7 +79,7 @@
 }
 
 /* Create a new AwtMenu object and menu.   */
-AwtMenu* AwtMenu::Create(jobject self, AwtMenu* parentMenu)
+AwtMenu* AwtMenu::Create(jobject self, jobject parent)
 {
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 
@@ -85,6 +91,9 @@
             return NULL;
         }
 
+        JNI_CHECK_NULL_GOTO(parent, "peer", done);
+        AwtMenu* parentMenu = (AwtMenu*) JNI_GET_PDATA(parent);
+
         target = env->GetObjectField(self, AwtObject::targetID);
         JNI_CHECK_NULL_GOTO(target, "null target", done);
 
@@ -119,6 +128,46 @@
     return menu;
 }
 
+void AwtMenu::_AddSeparator(void *param)
+{
+    if (AwtToolkit::IsMainThread()) {
+        JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+        jobject self = (jobject)param;
+        AwtMenu *m = NULL;
+        PDATA pData;
+        JNI_CHECK_PEER_GOTO(self, ret);
+        m = (AwtMenu *)pData;
+        m->AddSeparator();
+ret:
+        env->DeleteGlobalRef(self);
+    } else {
+        AwtToolkit::GetInstance().InvokeFunction(AwtMenu::_AddSeparator, param);
+    }
+}
+
+void AwtMenu::_DelItem(void *param)
+{
+    if (AwtToolkit::IsMainThread()) {
+        JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+        DelItemStruct *dis = (DelItemStruct*) param;
+        jobject self = dis->menuitem;
+        jint index = dis->index;
+
+        AwtMenu *m = NULL;
+        PDATA pData;
+        JNI_CHECK_PEER_GOTO(self, ret);
+        m = (AwtMenu *)pData;
+        m->DeleteItem(static_cast<UINT>(index));
+ret:
+        env->DeleteGlobalRef(self);
+        delete dis;
+    } else {
+        AwtToolkit::GetInstance().InvokeFunction(AwtMenu::_DelItem, param);
+    }
+}
+
 void AwtMenu::UpdateLayout()
 {
     UpdateLayout(GetHMenu());
@@ -323,24 +372,6 @@
     return (GetMenuBar() == GetMenuContainer());
 }
 
-LRESULT AwtMenu::WinThreadExecProc(ExecuteArgs * args)
-{
-    switch( args->cmdId ) {
-        case MENU_ADDSEPARATOR:
-            this->AddSeparator();
-            break;
-
-        case MENU_DELITEM:
-            this->DeleteItem(static_cast<UINT>(args->param1));
-            break;
-
-        default:
-            AwtMenuItem::WinThreadExecProc(args);
-            break;
-    }
-    return 0L;
-}
-
 /************************************************************************
  * WMenuPeer native methods
  */
@@ -382,15 +413,14 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(self);
+    jobject selfGlobalRef = env->NewGlobalRef(self);
 
-    AwtObject::WinThreadExec(self, AwtMenu::MENU_ADDSEPARATOR);
+    AwtToolkit::GetInstance().SyncCall(AwtMenu::_AddSeparator, selfGlobalRef);
+    // selfGlobalRef is deleted in _AddSeparator
 
     CATCH_BAD_ALLOC;
 }
 
-
 /*
  * Class:     sun_awt_windows_WMenuPeer
  * Method:    delItem
@@ -402,10 +432,12 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(self);
+    DelItemStruct *dis = new DelItemStruct;
+    dis->menuitem = env->NewGlobalRef(self);
+    dis->index = index;
 
-    AwtObject::WinThreadExec(self, AwtMenu::MENU_DELITEM, index);
+    AwtToolkit::GetInstance().SyncCall(AwtMenu::_DelItem, dis);
+    // global refs and dis are deleted in _DelItem
 
     CATCH_BAD_ALLOC;
 }
@@ -421,13 +453,8 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(menuBar);
-
-    AwtMenuBar* awtMenuBar = (AwtMenuBar *)pData;
-    AwtToolkit::CreateComponent(self, awtMenuBar,
-                                (AwtToolkit::ComponentFactory)AwtMenu::Create,FALSE);
-    JNI_CHECK_PEER_CREATION_RETURN(self);
+    AwtToolkit::CreateComponent(self, menuBar,
+                                (AwtToolkit::ComponentFactory)AwtMenu::Create);
 
     CATCH_BAD_ALLOC;
 }
@@ -443,13 +470,8 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(menu);
-
-    AwtMenu* awtMenu = (AwtMenu *)pData;
-    AwtToolkit::CreateComponent(self, awtMenu,
-                                (AwtToolkit::ComponentFactory)AwtMenu::Create,FALSE);
-    JNI_CHECK_PEER_CREATION_RETURN(self);
+    AwtToolkit::CreateComponent(self, menu,
+                                (AwtToolkit::ComponentFactory)AwtMenu::Create);
 
     CATCH_BAD_ALLOC;
 }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_Menu.h	Thu Oct 20 15:10:52 2016 +0100
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_Menu.h	Sat Nov 19 13:10:18 2016 +0300
@@ -42,13 +42,6 @@
 
 class AwtMenu : public AwtMenuItem {
 public:
-    // id's for methods executed on toolkit thread
-    enum {
-        MENU_ADDSEPARATOR = MENUITEM_LAST+1,
-        MENU_DELITEM,
-        MENU_LAST
-    };
-
     /* method ids for java.awt.Menu */
     static jmethodID countItemsMID;
     static jmethodID getItemMID;
@@ -61,7 +54,7 @@
     virtual LPCTSTR GetClassName();
 
     /* Create a new AwtMenu.  This must be run on the main thread. */
-    static AwtMenu* Create(jobject self, AwtMenu* parentMenu);
+    static AwtMenu* Create(jobject self, jobject parent);
 
     INLINE HMENU GetHMenu() { return m_hMenu; }
     INLINE void SetHMenu(HMENU hMenu) {
@@ -94,9 +87,9 @@
     void MeasureItem(HDC hDC, MEASUREITEMSTRUCT& measureInfo);
     void MeasureItems(HDC hDC, MEASUREITEMSTRUCT& measureInfo);
 
-    virtual LRESULT WinThreadExecProc(ExecuteArgs * args);
-
     // invoked on Toolkit thread
+    static void _AddSeparator(void *param);
+    static void _DelItem(void *param);
     static void _CreateMenu(void *param);
     static void _CreateSubMenu(void *param);
     virtual BOOL IsSeparator() { return FALSE; }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp	Thu Oct 20 15:10:52 2016 +0100
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.cpp	Sat Nov 19 13:10:18 2016 +0300
@@ -30,6 +30,12 @@
  */
 
 /***********************************************************************/
+// struct for _DelItem() method
+struct DelItemStruct {
+    jobject menuitem;
+    jint index;
+};
+/***********************************************************************/
 // struct for _AddMenu() method
 struct AddMenuStruct {
     jobject menubar;
@@ -130,18 +136,6 @@
         return myFrame->GetHWnd();
 }
 
-void AwtMenuBar::SendDrawItem(AwtMenuItem* awtMenuItem,
-                              DRAWITEMSTRUCT& drawInfo)
-{
-    awtMenuItem->DrawItem(drawInfo);
-}
-
-void AwtMenuBar::SendMeasureItem(AwtMenuItem* awtMenuItem,
-                                 HDC hDC, MEASUREITEMSTRUCT& measureInfo)
-{
-    awtMenuItem->MeasureItem(hDC, measureInfo);
-}
-
 int AwtMenuBar::CountItem(jobject menuBar)
 {
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@@ -164,9 +158,9 @@
 
     jobject menuItemPeer = GetPeerForTarget(env, menu);
     PDATA pData;
+    AwtMenuItem* awtMenuItem = NULL;
     JNI_CHECK_PEER_GOTO(menuItemPeer, done);
-
-    AwtMenuItem* awtMenuItem = (AwtMenuItem*)pData;
+    awtMenuItem = (AwtMenuItem*)pData;
 
 done:
     env->DeleteLocalRef(menu);
@@ -215,20 +209,6 @@
     VERIFY(::DrawMenuBar(GetOwnerHWnd()));
 }
 
-LRESULT AwtMenuBar::WinThreadExecProc(ExecuteArgs * args)
-{
-    switch( args->cmdId ) {
-        case MENUBAR_DELITEM:
-            this->DeleteItem(static_cast<UINT>(args->param1));
-            break;
-
-        default:
-            AwtMenu::WinThreadExecProc(args);
-            break;
-    }
-    return 0L;
-}
-
 void AwtMenuBar::_AddMenu(void *param)
 {
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@@ -257,6 +237,28 @@
     delete ams;
 }
 
+void AwtMenuBar::_DelItem(void *param)
+{
+    if (AwtToolkit::IsMainThread()) {
+        JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+        DelItemStruct *dis = (DelItemStruct*) param;
+        jobject self = dis->menuitem;
+        jint index = dis->index;
+
+        AwtMenuBar *m = NULL;
+        PDATA pData;
+        JNI_CHECK_PEER_GOTO(self, ret);
+        m = (AwtMenuBar *)pData;
+        m->DeleteItem(static_cast<UINT>(index));
+ret:
+        env->DeleteGlobalRef(self);
+        delete dis;
+    } else {
+        AwtToolkit::GetInstance().InvokeFunction(AwtMenuBar::_DelItem, param);
+    }
+}
+
 /************************************************************************
  * MenuBar native methods
  */
@@ -325,9 +327,12 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(self);
-    AwtObject::WinThreadExec(self, AwtMenuBar::MENUBAR_DELITEM, (LPARAM)index);
+    DelItemStruct *dis = new DelItemStruct;
+    dis->menuitem = env->NewGlobalRef(self);
+    dis->index = index;
+
+    AwtToolkit::GetInstance().SyncCall(AwtMenuBar::_DelItem, dis);
+    // global refs and dis are deleted in _DelItem
 
     CATCH_BAD_ALLOC;
 }
@@ -346,9 +351,6 @@
     AwtToolkit::CreateComponent(self, frame,
                                 (AwtToolkit::ComponentFactory)
                                 AwtMenuBar::Create);
-    PDATA pData;
-    JNI_CHECK_PEER_CREATION_RETURN(self);
-
     CATCH_BAD_ALLOC;
 }
 
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h	Thu Oct 20 15:10:52 2016 +0100
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuBar.h	Sat Nov 19 13:10:18 2016 +0300
@@ -42,10 +42,6 @@
 
 class AwtMenuBar : public AwtMenu {
 public:
-    // id's for methods executed on toolkit thread
-    enum MenuExecIds {
-        MENUBAR_DELITEM = MENU_LAST+1
-    };
 
     /* java.awt.MenuBar method ids */
     static jmethodID getMenuCountMID;
@@ -73,20 +69,15 @@
     AwtMenuItem* GetItem(jobject target, long index);
     int CountItem(jobject menuBar);
 
-    void SendDrawItem(AwtMenuItem* awtMenuItem,
-                      DRAWITEMSTRUCT& drawInfo);
-    void SendMeasureItem(AwtMenuItem* awtMenuItem,
-                         HDC hDC, MEASUREITEMSTRUCT& measureInfo);
     void DrawItem(DRAWITEMSTRUCT& drawInfo);
     void MeasureItem(HDC hDC, MEASUREITEMSTRUCT& measureInfo);
 
     void AddItem(AwtMenuItem* item);
     void DeleteItem(UINT index);
 
-    virtual LRESULT WinThreadExecProc(ExecuteArgs * args);
-
     // called on Toolkit thread
     static void _AddMenu(void *param);
+    static void _DelItem(void *param);
 protected:
     AwtFrame* m_frame;
 };
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp	Thu Oct 20 15:10:52 2016 +0100
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp	Sat Nov 19 13:10:18 2016 +0300
@@ -50,6 +50,16 @@
     jobject menuitem;
     jstring label;
 };
+// struct for _SetEnable() method
+struct SetEnableStruct {
+    jobject menuitem;
+    jboolean isEnabled;
+};
+// struct for _setState() method
+struct SetStateStruct {
+    jobject menuitem;
+    jboolean isChecked;
+};
 /************************************************************************
  * AwtMenuItem fields
  */
@@ -104,6 +114,7 @@
 {
     if (m_freeId) {
         AwtToolkit::GetInstance().RemoveCmdID( GetID() );
+        m_freeId = FALSE;
     }
 }
 void AwtMenuItem::Dispose()
@@ -206,13 +217,12 @@
         if (env->EnsureLocalCapacity(1) < 0) {
             return NULL;
         }
-        PDATA pData;
-        JNI_CHECK_PEER_RETURN_NULL(menuPeer);
+        JNI_CHECK_NULL_RETURN_NULL(menuPeer, "peer");
 
         /* target is a java.awt.MenuItem  */
         target = env->GetObjectField(peer, AwtObject::targetID);
 
-        AwtMenu* menu = (AwtMenu *)pData;
+        AwtMenu* menu = (AwtMenu *)JNI_GET_PDATA(menuPeer);
         item = new AwtMenuItem();
         jboolean isCheckbox =
             (jboolean)env->GetBooleanField(peer, AwtMenuItem::isCheckboxID);
@@ -223,7 +233,9 @@
         item->LinkObjects(env, peer);
         item->SetMenuContainer(menu);
         item->SetNewID();
-        menu->AddItem(item);
+        if (menu != NULL) {
+            menu->AddItem(item);
+        }
     } catch (...) {
         env->DeleteLocalRef(target);
         throw;
@@ -764,30 +776,6 @@
     }
 }
 
-LRESULT AwtMenuItem::WinThreadExecProc(ExecuteArgs * args)
-{
-    switch( args->cmdId ) {
-        case MENUITEM_ENABLE:
-        {
-            BOOL        isEnabled = (BOOL)args->param1;
-            this->Enable(isEnabled);
-        }
-        break;
-
-        case MENUITEM_SETSTATE:
-        {
-            BOOL        isChecked = (BOOL)args->param1;
-            this->SetState(isChecked);
-        }
-        break;
-
-        default:
-            AwtObject::WinThreadExecProc(args);
-            break;
-    }
-    return 0L;
-}
-
 void AwtMenuItem::_SetLabel(void *param) {
     if (AwtToolkit::IsMainThread()) {
         JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
@@ -887,6 +875,53 @@
     }
 }
 
+void AwtMenuItem::_SetEnable(void *param)
+{
+    if (AwtToolkit::IsMainThread()) {
+        JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+        SetEnableStruct *ses = (SetEnableStruct*) param;
+        jobject self = ses->menuitem;
+        jboolean isEnabled = ses->isEnabled;
+
+        AwtMenuItem *m = NULL;
+
+        PDATA pData;
+        JNI_CHECK_PEER_GOTO(self, ret);
+
+        m = (AwtMenuItem *)pData;
+
+        m->Enable(isEnabled);
+ret:
+        env->DeleteGlobalRef(self);
+        delete ses;
+    } else {
+        AwtToolkit::GetInstance().InvokeFunction(AwtMenuItem::_SetEnable, param);
+    }
+}
+
+void AwtMenuItem::_SetState(void *param)
+{
+    if (AwtToolkit::IsMainThread()) {
+        JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+
+        SetStateStruct *sts = (SetStateStruct*) param;
+        jobject self = sts->menuitem;
+        jboolean isChecked = sts->isChecked;
+
+        AwtMenuItem *m = NULL;
+
+        PDATA pData;
+        JNI_CHECK_PEER_GOTO(self, ret);
+        m = (AwtMenuItem *)pData;
+        m->SetState(isChecked);
+ret:
+        env->DeleteGlobalRef(self);
+        delete sts;
+    } else {
+        AwtToolkit::GetInstance().InvokeFunction(AwtMenuItem::_SetState, param);
+    }
+}
 BOOL AwtMenuItem::IsSeparator() {
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
     if (env->EnsureLocalCapacity(2) < 0) {
@@ -1050,13 +1085,9 @@
 {
     TRY;
 
-    JNI_CHECK_NULL_RETURN(menu, "null Menu");
     AwtToolkit::CreateComponent(self, menu,
                                 (AwtToolkit::ComponentFactory)
                                 AwtMenuItem::Create);
-    PDATA pData;
-    JNI_CHECK_PEER_CREATION_RETURN(self);
-
     CATCH_BAD_ALLOC;
 }
 
@@ -1071,9 +1102,12 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(self);
-    AwtObject::WinThreadExec(self, AwtMenuItem::MENUITEM_ENABLE, (LPARAM)on );
+    SetEnableStruct *ses = new SetEnableStruct;
+    ses->menuitem = env->NewGlobalRef(self);
+    ses->isEnabled = on;
+
+    AwtToolkit::GetInstance().SyncCall(AwtMenuItem::_SetEnable, ses);
+    // global refs and ses are deleted in _SetEnable
 
     CATCH_BAD_ALLOC;
 }
@@ -1112,9 +1146,12 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(self);
-    AwtObject::WinThreadExec(self, AwtMenuItem::MENUITEM_SETSTATE, (LPARAM)on);
+    SetStateStruct *sts = new SetStateStruct;
+    sts->menuitem = env->NewGlobalRef(self);
+    sts->isChecked = on;
+
+    AwtToolkit::GetInstance().SyncCall(AwtMenuItem::_SetState, sts);
+    // global refs and sts are deleted in _SetState
 
     CATCH_BAD_ALLOC;
 }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.h	Thu Oct 20 15:10:52 2016 +0100
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.h	Sat Nov 19 13:10:18 2016 +0300
@@ -45,13 +45,6 @@
 
 class AwtMenuItem : public AwtObject {
 public:
-    // id's for methods executed on toolkit thread
-    enum {
-        MENUITEM_ENABLE,
-        MENUITEM_SETSTATE,
-        MENUITEM_LAST
-    };
-
     /* java.awt.MenuComponent fields */
     static jfieldID fontID;
     static jfieldID appContextID;
@@ -154,13 +147,14 @@
      */
     MsgRouting WmNotify(UINT notifyCode);
 
-    virtual LRESULT WinThreadExecProc(ExecuteArgs * args);
     virtual BOOL IsDisabledAndPopup() {
         return FALSE;
     }
     virtual BOOL IsSeparator();
 
     // invoked on Toolkit thread
+    static void _SetState(void *param);
+    static void _SetEnable(void *param);
     static void _SetLabel(void *param);
     static void _UpdateLayout(void *param);
 
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_PopupMenu.cpp	Thu Oct 20 15:10:52 2016 +0100
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_PopupMenu.cpp	Sat Nov 19 13:10:18 2016 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 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
@@ -65,7 +65,7 @@
 }
 
 /* Create a new AwtPopupMenu object and menu.   */
-AwtPopupMenu* AwtPopupMenu::Create(jobject self, AwtComponent* parent)
+AwtPopupMenu* AwtPopupMenu::Create(jobject self, jobject parent)
 {
     JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
 
@@ -77,6 +77,9 @@
             return NULL;
         }
 
+        JNI_CHECK_NULL_GOTO(parent, "peer", done);
+        AwtComponent* awtParent = (AwtComponent*) JNI_GET_PDATA(parent);
+
         target = env->GetObjectField(self, AwtObject::targetID);
         JNI_CHECK_NULL_GOTO(target, "null target", done);
 
@@ -94,7 +97,7 @@
         popupMenu->SetHMenu(hMenu);
 
         popupMenu->LinkObjects(env, self);
-        popupMenu->SetParent(parent);
+        popupMenu->SetParent(awtParent);
     } catch (...) {
         env->DeleteLocalRef(target);
         throw;
@@ -274,12 +277,8 @@
 {
     TRY;
 
-    PDATA pData;
-    JNI_CHECK_PEER_RETURN(parent);
-    AwtComponent* awtParent = (AwtComponent *)pData;
     AwtToolkit::CreateComponent(
-        self, awtParent, (AwtToolkit::ComponentFactory)AwtPopupMenu::Create, FALSE);
-    JNI_CHECK_PEER_CREATION_RETURN(self);
+        self, parent, (AwtToolkit::ComponentFactory)AwtPopupMenu::Create);
 
     CATCH_BAD_ALLOC;
 }
--- a/jdk/src/java.desktop/windows/native/libawt/windows/awt_PopupMenu.h	Thu Oct 20 15:10:52 2016 +0100
+++ b/jdk/src/java.desktop/windows/native/libawt/windows/awt_PopupMenu.h	Sat Nov 19 13:10:18 2016 +0300
@@ -47,7 +47,7 @@
     virtual LPCTSTR GetClassName();
 
     /* Create a new AwtPopupMenu.  This must be run on the main thread. */
-    static AwtPopupMenu* Create(jobject self, AwtComponent* parent);
+    static AwtPopupMenu* Create(jobject self, jobject parent);
 
     /* Display the popup modally. */
     void Show(JNIEnv *env, jobject event, BOOL isTrayIconPopup);