[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

andreas.kling at nokia.com andreas.kling at nokia.com
Wed Dec 22 11:09:27 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit d9acc42f0eae28376053fcf2b8c7ff78900bd0b5
Author: andreas.kling at nokia.com <andreas.kling at nokia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Wed Jul 14 00:29:32 2010 +0000

    2010-07-13  Andreas Kling  <andreas.kling at nokia.com>
    
            Reviewed by Darin Adler.
    
            Avoid slow-path for put() in Array.splice()
            https://bugs.webkit.org/show_bug.cgi?id=41920
    
            Defer creation of the returned array until its final size is known
            to avoid growing it while adding elements.
    
            * runtime/JSArray.cpp:
            (JSC::JSArray::JSArray): Add two modes of creation, CreateInitialized (old)
            and CreateCompact (which should only be used when constructing arrays whose
            size and contents are known at the time of creation.)
            (JSC::JSArray::setLength): Skip first consistency check if in CreateCompact
            initialization mode. (Only applies to non-empty arrays.)
            (JSC::JSArray::checkConsistency): Build fix (JSValue::type() is gone)
            * runtime/JSArray.h:
            (JSC::JSArray::uncheckedSetIndex): Added for fast initialization of compact
            arrays. Does no bounds or other sanity checking.
            * runtime/ArrayPrototype.cpp:
            (JSC::arrayProtoFuncSplice): Optimized creation of the returned JSArray.
            * runtime/ArrayConstructor.cpp:
            (JSC::constructArrayWithSizeQuirk): Pass CreateInitialized to ctor.
            * runtime/JSGlobalObject.h:
            (JSC::constructEmptyArray): Pass CreateInitialized to ctor.
            * runtime/RegExpConstructor.cpp:
            (JSC::RegExpMatchesArray::RegExpMatchesArray): Pass CreateInitialized to ctor.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@63268 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 3321e78..a14ac23 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,32 @@
+2010-07-13  Andreas Kling  <andreas.kling at nokia.com>
+
+        Reviewed by Darin Adler.
+
+        Avoid slow-path for put() in Array.splice()
+        https://bugs.webkit.org/show_bug.cgi?id=41920
+
+        Defer creation of the returned array until its final size is known
+        to avoid growing it while adding elements.
+
+        * runtime/JSArray.cpp:
+        (JSC::JSArray::JSArray): Add two modes of creation, CreateInitialized (old)
+        and CreateCompact (which should only be used when constructing arrays whose
+        size and contents are known at the time of creation.)
+        (JSC::JSArray::setLength): Skip first consistency check if in CreateCompact
+        initialization mode. (Only applies to non-empty arrays.)
+        (JSC::JSArray::checkConsistency): Build fix (JSValue::type() is gone)
+        * runtime/JSArray.h:
+        (JSC::JSArray::uncheckedSetIndex): Added for fast initialization of compact
+        arrays. Does no bounds or other sanity checking.
+        * runtime/ArrayPrototype.cpp:
+        (JSC::arrayProtoFuncSplice): Optimized creation of the returned JSArray.
+        * runtime/ArrayConstructor.cpp:
+        (JSC::constructArrayWithSizeQuirk): Pass CreateInitialized to ctor.
+        * runtime/JSGlobalObject.h:
+        (JSC::constructEmptyArray): Pass CreateInitialized to ctor.
+        * runtime/RegExpConstructor.cpp:
+        (JSC::RegExpMatchesArray::RegExpMatchesArray): Pass CreateInitialized to ctor.
+
 2010-07-13  Gavin Barraclough  <barraclough at apple.com>
 
         Reviewed by Oliver Hunt.
diff --git a/JavaScriptCore/runtime/ArrayConstructor.cpp b/JavaScriptCore/runtime/ArrayConstructor.cpp
index 589739a..e5d0dac 100644
--- a/JavaScriptCore/runtime/ArrayConstructor.cpp
+++ b/JavaScriptCore/runtime/ArrayConstructor.cpp
@@ -58,7 +58,7 @@ static inline JSObject* constructArrayWithSizeQuirk(ExecState* exec, const ArgLi
         uint32_t n = args.at(0).toUInt32(exec);
         if (n != args.at(0).toNumber(exec))
             return throwError(exec, createRangeError(exec, "Array size is not a small enough positive integer."));
-        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), n);
+        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), n, CreateInitialized);
     }
 
     // otherwise the array is constructed with the arguments in it
diff --git a/JavaScriptCore/runtime/ArrayPrototype.cpp b/JavaScriptCore/runtime/ArrayPrototype.cpp
index f6d48da..e79c46d 100644
--- a/JavaScriptCore/runtime/ArrayPrototype.cpp
+++ b/JavaScriptCore/runtime/ArrayPrototype.cpp
@@ -547,8 +547,6 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
     JSObject* thisObj = thisValue.toThisObject(exec);
 
     // 15.4.4.12
-    JSArray* resObj = constructEmptyArray(exec);
-    JSValue result = resObj;
 
     // FIXME: Firefox returns an empty array.
     if (!exec->argumentCount())
@@ -569,10 +567,12 @@ EncodedJSValue JSC_HOST_CALL arrayProtoFuncSplice(ExecState* exec)
     else
         deleteCount = length - begin;
 
-    for (unsigned k = 0; k < deleteCount; k++) {
-        if (JSValue v = getProperty(exec, thisObj, k + begin))
-            resObj->put(exec, k, v);
-    }
+    JSArray* resObj = new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), deleteCount, CreateCompact);
+    JSValue result = resObj;
+
+    for (unsigned k = 0; k < deleteCount; k++)
+        resObj->uncheckedSetIndex(k, getProperty(exec, thisObj, k + begin));
+
     resObj->setLength(deleteCount);
 
     unsigned additionalArgs = std::max<int>(exec->argumentCount() - 2, 0);
diff --git a/JavaScriptCore/runtime/JSArray.cpp b/JavaScriptCore/runtime/JSArray.cpp
index 362f89b..56603a3 100644
--- a/JavaScriptCore/runtime/JSArray.cpp
+++ b/JavaScriptCore/runtime/JSArray.cpp
@@ -33,8 +33,6 @@
 #include <wtf/OwnPtr.h>
 #include <Operations.h>
 
-#define CHECK_ARRAY_CONSISTENCY 0
-
 using namespace std;
 using namespace WTF;
 
@@ -141,22 +139,37 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure)
     checkConsistency();
 }
 
-JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength)
+JSArray::JSArray(NonNullPassRefPtr<Structure> structure, unsigned initialLength, ArrayCreationMode creationMode)
     : JSObject(structure)
 {
-    unsigned initialCapacity = min(initialLength, MIN_SPARSE_ARRAY_INDEX);
+    unsigned initialCapacity;
+    if (creationMode == CreateCompact)
+        initialCapacity = initialLength;
+    else
+        initialCapacity = min(initialLength, MIN_SPARSE_ARRAY_INDEX);
 
     m_storage = static_cast<ArrayStorage*>(fastMalloc(storageSize(initialCapacity)));
-    m_storage->m_length = initialLength;
     m_vectorLength = initialCapacity;
-    m_storage->m_numValuesInVector = 0;
     m_storage->m_sparseValueMap = 0;
     m_storage->subclassData = 0;
     m_storage->reportedMapCapacity = 0;
 
-    JSValue* vector = m_storage->m_vector;
-    for (size_t i = 0; i < initialCapacity; ++i)
-        vector[i] = JSValue();
+    if (creationMode == CreateCompact) {
+#if CHECK_ARRAY_CONSISTENCY
+        m_storage->m_inCompactInitialization = !!initialCapacity;
+#endif
+        m_storage->m_length = 0;
+        m_storage->m_numValuesInVector = initialCapacity;
+    } else {
+#if CHECK_ARRAY_CONSISTENCY
+        m_storage->m_inCompactInitialization = false;
+#endif
+        m_storage->m_length = initialLength;
+        m_storage->m_numValuesInVector = 0;
+        JSValue* vector = m_storage->m_vector;
+        for (size_t i = 0; i < initialCapacity; ++i)
+            vector[i] = JSValue();
+    }
 
     checkConsistency();
 
@@ -175,6 +188,9 @@ JSArray::JSArray(NonNullPassRefPtr<Structure> structure, const ArgList& list)
     m_storage->m_sparseValueMap = 0;
     m_storage->subclassData = 0;
     m_storage->reportedMapCapacity = 0;
+#if CHECK_ARRAY_CONSISTENCY
+    m_storage->m_inCompactInitialization = false;
+#endif
 
     size_t i = 0;
     ArgList::const_iterator end = list.end();
@@ -524,7 +540,12 @@ bool JSArray::increaseVectorLength(unsigned newLength)
 
 void JSArray::setLength(unsigned newLength)
 {
-    checkConsistency();
+#if CHECK_ARRAY_CONSISTENCY
+    if (!m_storage->m_inCompactInitialization)
+        checkConsistency();
+    else
+        m_storage->m_inCompactInitialization = false;
+#endif
 
     ArrayStorage* storage = m_storage;
 
@@ -1045,7 +1066,7 @@ void JSArray::checkConsistency(ConsistencyCheckType type)
         if (JSValue value = m_storage->m_vector[i]) {
             ASSERT(i < m_storage->m_length);
             if (type != DestructorConsistencyCheck)
-                value->type(); // Likely to crash if the object was deallocated.
+                value.isUndefined(); // Likely to crash if the object was deallocated.
             ++numValuesInVector;
         } else {
             if (type == SortConsistencyCheck)
@@ -1064,7 +1085,7 @@ void JSArray::checkConsistency(ConsistencyCheckType type)
             ASSERT(index <= MAX_ARRAY_INDEX);
             ASSERT(it->second);
             if (type != DestructorConsistencyCheck)
-                it->second->type(); // Likely to crash if the object was deallocated.
+                it->second.isUndefined(); // Likely to crash if the object was deallocated.
         }
     }
 }
diff --git a/JavaScriptCore/runtime/JSArray.h b/JavaScriptCore/runtime/JSArray.h
index f65f2bc..b6dd7cc 100644
--- a/JavaScriptCore/runtime/JSArray.h
+++ b/JavaScriptCore/runtime/JSArray.h
@@ -23,6 +23,8 @@
 
 #include "JSObject.h"
 
+#define CHECK_ARRAY_CONSISTENCY 0
+
 namespace JSC {
 
     typedef HashMap<unsigned, JSValue> SparseArrayValueMap;
@@ -33,16 +35,29 @@ namespace JSC {
         SparseArrayValueMap* m_sparseValueMap;
         void* subclassData; // A JSArray subclass can use this to fill the vector lazily.
         size_t reportedMapCapacity;
+#if CHECK_ARRAY_CONSISTENCY
+        bool m_inCompactInitialization;
+#endif
         JSValue m_vector[1];
     };
 
+    // The CreateCompact creation mode is used for fast construction of arrays
+    // whose size and contents are known at time of creation.
+    //
+    // There are two obligations when using this mode:
+    //
+    //   - uncheckedSetIndex() must be used when initializing the array.
+    //   - setLength() must be called after initialization.
+
+    enum ArrayCreationMode { CreateCompact, CreateInitialized };
+
     class JSArray : public JSObject {
         friend class JIT;
         friend class Walker;
 
     public:
         explicit JSArray(NonNullPassRefPtr<Structure>);
-        JSArray(NonNullPassRefPtr<Structure>, unsigned initialLength);
+        JSArray(NonNullPassRefPtr<Structure>, unsigned initialLength, ArrayCreationMode);
         JSArray(NonNullPassRefPtr<Structure>, const ArgList& initialValues);
         virtual ~JSArray();
 
@@ -83,6 +98,15 @@ namespace JSC {
             x = v;
         }
 
+        void uncheckedSetIndex(unsigned i, JSValue v)
+        {
+            ASSERT(canSetIndex(i));
+#if CHECK_ARRAY_CONSISTENCY
+            ASSERT(m_storage->m_inCompactInitialization);
+#endif
+            m_storage->m_vector[i] = v;
+        }
+
         void fillArgList(ExecState*, MarkedArgumentBuffer&);
         void copyToRegisters(ExecState*, Register*, uint32_t);
 
diff --git a/JavaScriptCore/runtime/JSGlobalObject.h b/JavaScriptCore/runtime/JSGlobalObject.h
index 09a92a1..115af87 100644
--- a/JavaScriptCore/runtime/JSGlobalObject.h
+++ b/JavaScriptCore/runtime/JSGlobalObject.h
@@ -457,7 +457,7 @@ namespace JSC {
 
     inline JSArray* constructEmptyArray(ExecState* exec, unsigned initialLength)
     {
-        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength);
+        return new (exec) JSArray(exec->lexicalGlobalObject()->arrayStructure(), initialLength, CreateInitialized);
     }
 
     inline JSArray* constructArray(ExecState* exec, JSValue singleItemValue)
diff --git a/JavaScriptCore/runtime/RegExpConstructor.cpp b/JavaScriptCore/runtime/RegExpConstructor.cpp
index fa2a1e2..aff83e7 100644
--- a/JavaScriptCore/runtime/RegExpConstructor.cpp
+++ b/JavaScriptCore/runtime/RegExpConstructor.cpp
@@ -106,7 +106,7 @@ RegExpConstructor::RegExpConstructor(ExecState* exec, JSGlobalObject* globalObje
 }
 
 RegExpMatchesArray::RegExpMatchesArray(ExecState* exec, RegExpConstructorPrivate* data)
-    : JSArray(exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), data->lastNumSubPatterns + 1)
+    : JSArray(exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), data->lastNumSubPatterns + 1, CreateInitialized)
 {
     RegExpConstructorPrivate* d = new RegExpConstructorPrivate;
     d->input = data->lastInput;

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list