Title: [155365] branches/safari-534.59-branch/Source/_javascript_Core

Diff

Modified: branches/safari-534.59-branch/Source/_javascript_Core/ChangeLog (155364 => 155365)


--- branches/safari-534.59-branch/Source/_javascript_Core/ChangeLog	2013-09-09 18:19:47 UTC (rev 155364)
+++ branches/safari-534.59-branch/Source/_javascript_Core/ChangeLog	2013-09-09 18:21:06 UTC (rev 155365)
@@ -1,3 +1,18 @@
+2013-09-09  Lucas Forschler  <[email protected]>
+
+        Merge fix for <rdar:/problem/14909253>
+    
+    2013-09-09  Filip Pizlo  <[email protected]>
+    
+            * runtime/ArrayPrototype.cpp:
+            (JSC::arrayProtoFuncSort):
+            * runtime/JSArray.cpp:
+            (JSC::JSArray::sortNumeric):
+            (JSC::JSArray::sort):
+            (JSC::JSArray::compactForSorting):
+            * runtime/JSArray.h:
+            (JSC::JSArray::hasSparseMap):
+
 2013-03-14  Lucas Forschler  <[email protected]>
 
         Merge r138606

Modified: branches/safari-534.59-branch/Source/_javascript_Core/runtime/ArrayPrototype.cpp (155364 => 155365)


--- branches/safari-534.59-branch/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2013-09-09 18:19:47 UTC (rev 155364)
+++ branches/safari-534.59-branch/Source/_javascript_Core/runtime/ArrayPrototype.cpp	2013-09-09 18:21:06 UTC (rev 155365)
@@ -538,7 +538,7 @@
     CallData callData;
     CallType callType = getCallData(function, callData);
 
-    if (thisObj->classInfo() == &JSArray::s_info) {
+    if (thisObj->classInfo() == &JSArray::s_info && !asArray(thisObj)->hasSparseMap()) {
         if (isNumericCompareFunction(exec, callType, callData))
             asArray(thisObj)->sortNumeric(exec, function, callType, callData);
         else if (callType != CallTypeNone)

Modified: branches/safari-534.59-branch/Source/_javascript_Core/runtime/JSArray.cpp (155364 => 155365)


--- branches/safari-534.59-branch/Source/_javascript_Core/runtime/JSArray.cpp	2013-09-09 18:19:47 UTC (rev 155364)
+++ branches/safari-534.59-branch/Source/_javascript_Core/runtime/JSArray.cpp	2013-09-09 18:21:06 UTC (rev 155365)
@@ -964,10 +964,8 @@
     ArrayStorage* storage = m_storage;
 
     unsigned lengthNotIncludingUndefined = compactForSorting();
-    if (storage->m_sparseValueMap) {
-        throwOutOfMemoryError(exec);
-        return;
-    }
+    
+    ASSERT(!storage->m_sparseValueMap);
 
     if (!lengthNotIncludingUndefined)
         return;
@@ -997,10 +995,7 @@
     ArrayStorage* storage = m_storage;
 
     unsigned lengthNotIncludingUndefined = compactForSorting();
-    if (storage->m_sparseValueMap) {
-        throwOutOfMemoryError(exec);
-        return;
-    }
+    ASSERT(!storage->m_sparseValueMap);
 
     if (!lengthNotIncludingUndefined)
         return;
@@ -1154,7 +1149,7 @@
         return;
 
     unsigned usedVectorLength = min(storage->m_length, m_vectorLength);
-    unsigned nodeCount = usedVectorLength + (storage->m_sparseValueMap ? storage->m_sparseValueMap->size() : 0);
+    unsigned nodeCount = usedVectorLength;
 
     if (!nodeCount)
         return;
@@ -1182,6 +1177,8 @@
 
     // Iterate over the array, ignoring missing values, counting undefined ones, and inserting all other ones into the tree.
     for (; numDefined < usedVectorLength; ++numDefined) {
+        if (numDefined >= m_vectorLength)
+            break;
         JSValue v = storage->m_vector[numDefined].get();
         if (!v || v.isUndefined())
             break;
@@ -1189,6 +1186,8 @@
         tree.insert(numDefined);
     }
     for (unsigned i = numDefined; i < usedVectorLength; ++i) {
+        if (i >= m_vectorLength)
+            break;
         JSValue v = storage->m_vector[i].get();
         if (v) {
             if (v.isUndefined())
@@ -1203,49 +1202,30 @@
 
     unsigned newUsedVectorLength = numDefined + numUndefined;
 
-    if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
-        newUsedVectorLength += map->size();
-        if (newUsedVectorLength > m_vectorLength) {
-            // Check that it is possible to allocate an array large enough to hold all the entries.
-            if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength)) {
-                throwOutOfMemoryError(exec);
-                return;
-            }
-        }
-        
-        storage = m_storage;
-
-        SparseArrayValueMap::iterator end = map->end();
-        for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it) {
-            tree.abstractor().m_nodes[numDefined].value = it->second.get();
-            tree.insert(numDefined);
-            ++numDefined;
-        }
-
-        delete map;
-        storage->m_sparseValueMap = 0;
-    }
-
-    ASSERT(tree.abstractor().m_nodes.size() >= numDefined);
-
-    // FIXME: If the compare function changed the length of the array, the following might be
-    // modifying the vector incorrectly.
-
+    ASSERT(!storage->m_sparseValueMap);
+    
+    // The array size may have changed.  Figure out the new bounds.
+    unsigned newestUsedVectorLength = min(m_storage->m_length, m_vectorLength); 
+    
+    unsigned elementsToExtractThreshold = min(min(newestUsedVectorLength, numDefined), static_cast<unsigned>(tree.abstractor().m_nodes.size())); 
+    unsigned undefinedElementsThreshold = min(newestUsedVectorLength, newUsedVectorLength); 
+    unsigned clearElementsThreshold = min(newestUsedVectorLength, usedVectorLength);     
+    
     // Copy the values back into m_storage.
     AVLTree<AVLTreeAbstractorForArrayCompare, 44>::Iterator iter;
     iter.start_iter_least(tree);
     JSGlobalData& globalData = exec->globalData();
-    for (unsigned i = 0; i < numDefined; ++i) {
+    for (unsigned i = 0; i < elementsToExtractThreshold; ++i) {
         storage->m_vector[i].set(globalData, this, tree.abstractor().m_nodes[*iter].value);
         ++iter;
     }
 
     // Put undefined values back in.
-    for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
+    for (unsigned i = elementsToExtractThreshold; i < undefinedElementsThreshold; ++i)
         storage->m_vector[i].setUndefined();
 
     // Ensure that unused values in the vector are zeroed out.
-    for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)
+    for (unsigned i = undefinedElementsThreshold; i < clearElementsThreshold; ++i)
         storage->m_vector[i].clear();
 
     storage->m_numValuesInVector = newUsedVectorLength;
@@ -1318,25 +1298,8 @@
 
     unsigned newUsedVectorLength = numDefined + numUndefined;
 
-    if (SparseArrayValueMap* map = storage->m_sparseValueMap) {
-        newUsedVectorLength += map->size();
-        if (newUsedVectorLength > m_vectorLength) {
-            // Check that it is possible to allocate an array large enough to hold all the entries - if not,
-            // exception is thrown by caller.
-            if ((newUsedVectorLength > MAX_STORAGE_VECTOR_LENGTH) || !increaseVectorLength(newUsedVectorLength))
-                return 0;
+    ASSERT(!storage->m_sparseValueMap);
 
-            storage = m_storage;
-        }
-
-        SparseArrayValueMap::iterator end = map->end();
-        for (SparseArrayValueMap::iterator it = map->begin(); it != end; ++it)
-            storage->m_vector[numDefined++].setWithoutWriteBarrier(it->second.get());
-
-        delete map;
-        storage->m_sparseValueMap = 0;
-    }
-
     for (unsigned i = numDefined; i < newUsedVectorLength; ++i)
         storage->m_vector[i].setUndefined();
     for (unsigned i = newUsedVectorLength; i < usedVectorLength; ++i)

Modified: branches/safari-534.59-branch/Source/_javascript_Core/runtime/JSArray.h (155364 => 155365)


--- branches/safari-534.59-branch/Source/_javascript_Core/runtime/JSArray.h	2013-09-09 18:19:47 UTC (rev 155364)
+++ branches/safari-534.59-branch/Source/_javascript_Core/runtime/JSArray.h	2013-09-09 18:21:06 UTC (rev 155365)
@@ -173,6 +173,11 @@
         }
 
         static void visitChildren(JSCell*, SlotVisitor&);
+        
+        bool hasSparseMap()
+        {
+            return !!m_storage->m_sparseValueMap;
+        }
 
     protected:
         static const unsigned StructureFlags = OverridesGetOwnPropertySlot | OverridesVisitChildren | OverridesGetPropertyNames | JSObject::StructureFlags;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to