8075006: Threads spinning infinitely in WeakHashMap.get running test262parallel
authorhannesw
Fri, 13 Mar 2015 18:40:07 +0100
changeset 29534 f0a6624dce16
parent 29433 c97e2d1bad97
child 29535 436194135f7d
8075006: Threads spinning infinitely in WeakHashMap.get running test262parallel Reviewed-by: lagergren, attila
nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java	Wed Jul 05 20:24:25 2017 +0200
+++ b/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/nashorn/internal/runtime/PropertyMap.java	Fri Mar 13 18:40:07 2015 +0100
@@ -330,12 +330,15 @@
      * Indicate that proto itself has changed in hierarchy somewhere.
      */
     synchronized void invalidateAllProtoGetSwitchPoints() {
-        if (protoGetSwitches != null && !protoGetSwitches.isEmpty()) {
-            if (Context.DEBUG) {
-                protoInvalidations += protoGetSwitches.size();
+        if (protoGetSwitches != null) {
+            final int size = protoGetSwitches.size();
+            if (size > 0) {
+                if (Context.DEBUG) {
+                    protoInvalidations += size;
+                }
+                SwitchPoint.invalidateAll(protoGetSwitches.values().toArray(new SwitchPoint[size]));
+                protoGetSwitches.clear();
             }
-            SwitchPoint.invalidateAll(protoGetSwitches.values().toArray(new SwitchPoint[protoGetSwitches.values().size()]));
-            protoGetSwitches.clear();
         }
     }
 
@@ -375,7 +378,8 @@
         }
     }
 
-    // Update the free slots bitmap for a property that has been deleted and/or added.
+    // Update the free slots bitmap for a property that has been deleted and/or added. This method is not synchronized
+    // as it is always invoked on a newly created instance.
     private void updateFreeSlots(final Property oldProperty, final Property newProperty) {
         // Free slots bitset is possibly shared with parent map, so we must clone it before making modifications.
         boolean freeSlotsCloned = false;
@@ -425,7 +429,7 @@
      *
      * @return New {@link PropertyMap} with {@link Property} added.
      */
-    public PropertyMap addProperty(final Property property) {
+    public synchronized PropertyMap addProperty(final Property property) {
         if (listeners != null) {
             listeners.propertyAdded(property);
         }
@@ -434,9 +438,9 @@
         if (newMap == null) {
             final PropertyHashMap newProperties = properties.immutableAdd(property);
             newMap = new PropertyMap(this, newProperties);
-            addToHistory(property, newMap);
             newMap.updateFlagsAndBoundaries(property);
             newMap.updateFreeSlots(null, property);
+            addToHistory(property, newMap);
         }
 
         return newMap;
@@ -449,7 +453,7 @@
      *
      * @return New {@link PropertyMap} with {@link Property} removed or {@code null} if not found.
      */
-    public PropertyMap deleteProperty(final Property property) {
+    public synchronized PropertyMap deleteProperty(final Property property) {
         if (listeners != null) {
             listeners.propertyDeleted(property);
         }
@@ -881,8 +885,7 @@
      * @param newProto New prototype object to replace oldProto.
      * @return New {@link PropertyMap} with prototype changed.
      */
-    public PropertyMap changeProto(final ScriptObject newProto) {
-
+    public synchronized PropertyMap changeProto(final ScriptObject newProto) {
         final PropertyMap nextMap = checkProtoHistory(newProto);
         if (nextMap != null) {
             return nextMap;