8169966: Larger AWT menus
authorserb
Tue, 21 Feb 2017 02:23:00 +0300
changeset 47406 f074c11b8fbf
parent 47405 7d686ef404c5
child 47407 2f79180e86e9
8169966: Larger AWT menus Reviewed-by: azvegint, prr, rhalade, mschoene
src/java.desktop/windows/native/libawt/windows/CmdIDList.cpp
src/java.desktop/windows/native/libawt/windows/CmdIDList.h
src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp
src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp
src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h
--- a/src/java.desktop/windows/native/libawt/windows/CmdIDList.cpp	Thu Nov 17 22:01:02 2016 +0300
+++ b/src/java.desktop/windows/native/libawt/windows/CmdIDList.cpp	Tue Feb 21 02:23:00 2017 +0300
@@ -61,29 +61,36 @@
     m_first_free = first_index; // head of the free list
 }
 
+
+jboolean AwtCmdIDList::isFreeIDAvailable() {
+    CriticalSection::Lock l(m_lock);
+
+    if (m_first_free == -1) {   // out of free ids
+        if (m_capacity == ARRAY_MAXIMUM_SIZE) {
+            return JNI_FALSE;
+        }
+    }
+    return JNI_TRUE;
+}
+
 // Assign an id to the object.  Recycle the first free entry from the
 // head of the free list or allocate more memory for a new free list.
 UINT AwtCmdIDList::Add(AwtObject* obj)
 {
     CriticalSection::Lock l(m_lock);
+    if (!isFreeIDAvailable()) {
+        throw std::bad_alloc(); // fatal error
+    }
 
     if (m_first_free == -1) {   // out of free ids
-        if (m_capacity == ARRAY_MAXIMUM_SIZE) {
-            // Really bad - out of ids.  Since we hardly can have *so*
-            // many items simultaneously in existence, we have an id
-            // leak somewhere.
-            DASSERT(FALSE);
-            return 0;
-        }
-        else {                  // snarf a bigger arena
-            UINT old_capacity = m_capacity; // will be the first free entry
-            m_capacity += ARRAY_SIZE_INCREMENT;
-            if (m_capacity > ARRAY_MAXIMUM_SIZE)
-                m_capacity = ARRAY_MAXIMUM_SIZE;
-            m_array = (CmdIDEntry *)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, m_array,
-                                        m_capacity, sizeof(CmdIDEntry*));
-            BuildFreeList(old_capacity);
-        }
+        // snarf a bigger arena
+        UINT old_capacity = m_capacity; // will be the first free entry
+        m_capacity += ARRAY_SIZE_INCREMENT;
+        if (m_capacity > ARRAY_MAXIMUM_SIZE)
+            m_capacity = ARRAY_MAXIMUM_SIZE;
+        m_array = (CmdIDEntry *)SAFE_SIZE_ARRAY_REALLOC(safe_Realloc, m_array,
+                                    m_capacity, sizeof(CmdIDEntry*));
+        BuildFreeList(old_capacity);
     }
 
     DASSERT(m_first_free != -1);
--- a/src/java.desktop/windows/native/libawt/windows/CmdIDList.h	Thu Nov 17 22:01:02 2016 +0300
+++ b/src/java.desktop/windows/native/libawt/windows/CmdIDList.h	Tue Feb 21 02:23:00 2017 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 1999, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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,7 @@
     UINT Add(AwtObject* obj);
     AwtObject* Lookup(UINT id);
     void Remove(UINT id);
+    jboolean isFreeIDAvailable();
 
     CriticalSection    m_lock;
 
--- a/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp	Thu Nov 17 22:01:02 2016 +0300
+++ b/src/java.desktop/windows/native/libawt/windows/awt_MenuItem.cpp	Tue Feb 21 02:23:00 2017 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -217,6 +217,10 @@
         if (env->EnsureLocalCapacity(1) < 0) {
             return NULL;
         }
+        if (!AwtToolkit::GetInstance().isFreeIDAvailable()) {
+            return NULL;
+        }
+
         JNI_CHECK_NULL_RETURN_NULL(menuPeer, "peer");
 
         /* target is a java.awt.MenuItem  */
--- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	Thu Nov 17 22:01:02 2016 +0300
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp	Tue Feb 21 02:23:00 2017 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -1869,6 +1869,11 @@
     }
 }
 
+jboolean AwtToolkit::isFreeIDAvailable()
+{
+    return m_cmdIDs->isFreeIDAvailable();
+}
+
 UINT AwtToolkit::CreateCmdID(AwtObject* object)
 {
     return m_cmdIDs->Add(object);
--- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h	Thu Nov 17 22:01:02 2016 +0300
+++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h	Tue Feb 21 02:23:00 2017 +0300
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2016, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2017, 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
@@ -373,6 +373,8 @@
     BOOL PreProcessMouseMsg(class AwtComponent* p, MSG& msg);
     BOOL PreProcessKeyMsg(class AwtComponent* p, MSG& msg);
 
+    /* Checks that an free ID exists. */
+    jboolean isFreeIDAvailable();
     /* Create an ID which maps to an AwtObject pointer, such as a menu. */
     UINT CreateCmdID(AwtObject* object);