RegExp matches arrays should use contiguous indexing.
authorakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 28 Apr 2015 00:14:47 +0000 (00:14 +0000)
committerakling@apple.com <akling@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 28 Apr 2015 00:14:47 +0000 (00:14 +0000)
<https://webkit.org/b/144286>

Reviewed by Geoffrey Garen.

We had a custom Structure being used for RegExp matches arrays that would
put the arrays into SlowPutArrayStorageShape mode. This was just left
from when matches arrays were custom, lazily initialized objects.

This change removes that Structure and switches the matches arrays to
using the default ContiguousShape Structure. This allows the FTL JIT
to compile the inner loop of the Octane/regexp benchmark.

Also made a version of initializeIndex() [inline] that takes the indexing
type in an argument, allowing createRegExpMatchesArray() to initialize
the entire array without branching on the indexing type for each entry.

~3% progression on Octane/regexp.

* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::mapStructure):
(JSC::JSGlobalObject::regExpMatchesArrayStructure): Deleted.
* runtime/JSObject.h:
(JSC::JSObject::initializeIndex):
* runtime/RegExpMatchesArray.cpp:
(JSC::createRegExpMatchesArray):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@183438 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/JSGlobalObject.cpp
Source/JavaScriptCore/runtime/JSGlobalObject.h
Source/JavaScriptCore/runtime/JSObject.h
Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp

index 9912d35..136cead 100644 (file)
@@ -1,3 +1,35 @@
+2015-04-27  Andreas Kling  <akling@apple.com>
+
+        RegExp matches arrays should use contiguous indexing.
+        <https://webkit.org/b/144286>
+
+        Reviewed by Geoffrey Garen.
+
+        We had a custom Structure being used for RegExp matches arrays that would
+        put the arrays into SlowPutArrayStorageShape mode. This was just left
+        from when matches arrays were custom, lazily initialized objects.
+
+        This change removes that Structure and switches the matches arrays to
+        using the default ContiguousShape Structure. This allows the FTL JIT
+        to compile the inner loop of the Octane/regexp benchmark.
+
+        Also made a version of initializeIndex() [inline] that takes the indexing
+        type in an argument, allowing createRegExpMatchesArray() to initialize
+        the entire array without branching on the indexing type for each entry.
+
+        ~3% progression on Octane/regexp.
+
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::mapStructure):
+        (JSC::JSGlobalObject::regExpMatchesArrayStructure): Deleted.
+        * runtime/JSObject.h:
+        (JSC::JSObject::initializeIndex):
+        * runtime/RegExpMatchesArray.cpp:
+        (JSC::createRegExpMatchesArray):
+
 2015-04-27  Ryosuke Niwa  <rniwa@webkit.org>
 
         REGRESSION (r183373): ASSERT failed in wtf/SHA1.h
index 638ad28..1835168 100644 (file)
@@ -305,8 +305,6 @@ void JSGlobalObject::init(VM& vm)
     for (unsigned i = 0; i < NumberOfIndexingShapes; ++i)
         m_arrayStructureForIndexingShapeDuringAllocation[i] = m_originalArrayStructureForIndexingShape[i];
 
-    m_regExpMatchesArrayStructure.set(vm, this, Structure::create(vm, this, m_arrayPrototype.get(), TypeInfo(ObjectType, StructureFlags), JSArray::info(), ArrayWithSlowPutArrayStorage));
-    
     RegExp* emptyRegex = RegExp::create(vm, "", NoFlags);
     
     m_regExpPrototype.set(vm, this, RegExpPrototype::create(vm, RegExpPrototype::createStructure(vm, this, m_objectPrototype.get()), emptyRegex));
@@ -764,7 +762,6 @@ void JSGlobalObject::visitChildren(JSCell* cell, SlotVisitor& visitor)
     visitor.append(&thisObject->m_boundFunctionStructure);
     visitor.append(&thisObject->m_namedFunctionStructure);
     visitor.append(&thisObject->m_symbolObjectStructure);
-    visitor.append(&thisObject->m_regExpMatchesArrayStructure);
     visitor.append(&thisObject->m_regExpStructure);
     visitor.append(&thisObject->m_consoleStructure);
     visitor.append(&thisObject->m_dollarVMStructure);
index e5f2e6a..589fa39 100644 (file)
@@ -232,7 +232,6 @@ protected:
     WriteBarrier<Structure> m_namedFunctionStructure;
     PropertyOffset m_functionNameOffset;
     WriteBarrier<Structure> m_privateNameStructure;
-    WriteBarrier<Structure> m_regExpMatchesArrayStructure;
     WriteBarrier<Structure> m_regExpStructure;
     WriteBarrier<Structure> m_consoleStructure;
     WriteBarrier<Structure> m_dollarVMStructure;
@@ -474,7 +473,6 @@ public:
     Structure* privateNameStructure() const { return m_privateNameStructure.get(); }
     Structure* internalFunctionStructure() const { return m_internalFunctionStructure.get(); }
     Structure* mapStructure() const { return m_mapStructure.get(); }
-    Structure* regExpMatchesArrayStructure() const { return m_regExpMatchesArrayStructure.get(); }
     Structure* regExpStructure() const { return m_regExpStructure.get(); }
     Structure* setStructure() const { return m_setStructure.get(); }
     Structure* stringObjectStructure() const { return m_stringObjectStructure.get(); }
index a46902a..d6282b0 100644 (file)
@@ -364,10 +364,15 @@ public:
             RELEASE_ASSERT_NOT_REACHED();
         }
     }
-        
+
     void initializeIndex(VM& vm, unsigned i, JSValue v)
     {
-        switch (indexingType()) {
+        initializeIndex(vm, i, v, indexingType());
+    }
+
+    void initializeIndex(VM& vm, unsigned i, JSValue v, IndexingType indexingType)
+    {
+        switch (indexingType) {
         case ALL_UNDECIDED_INDEXING_TYPES: {
             setIndexQuicklyToUndecided(vm, i, v);
             break;
index 3461cf0..9157c67 100644 (file)
@@ -35,16 +35,16 @@ JSArray* createRegExpMatchesArray(ExecState* exec, JSString* input, RegExp* regE
 {
     ASSERT(result);
     VM& vm = exec->vm();
-    JSArray* array = JSArray::tryCreateUninitialized(vm, exec->lexicalGlobalObject()->regExpMatchesArrayStructure(), regExp->numSubpatterns() + 1);
+    JSArray* array = JSArray::tryCreateUninitialized(vm, exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ContiguousShape), regExp->numSubpatterns() + 1);
     RELEASE_ASSERT(array);
 
     SamplingRegion samplingRegion("Reifying substring properties");
 
-    array->putDirectIndex(exec, 0, jsSubstring(exec, input, result.start, result.end - result.start));
+    array->initializeIndex(vm, 0, jsSubstring(exec, input, result.start, result.end - result.start), ContiguousShape);
 
     if (unsigned numSubpatterns = regExp->numSubpatterns()) {
         Vector<int, 32> subpatternResults;
-        int position = regExp->match(exec->vm(), input->value(exec), result.start, subpatternResults);
+        int position = regExp->match(vm, input->value(exec), result.start, subpatternResults);
         ASSERT_UNUSED(position, position >= 0 && static_cast<size_t>(position) == result.start);
         ASSERT(result.start == static_cast<size_t>(subpatternResults[0]));
         ASSERT(result.end == static_cast<size_t>(subpatternResults[1]));
@@ -52,14 +52,14 @@ JSArray* createRegExpMatchesArray(ExecState* exec, JSString* input, RegExp* regE
         for (unsigned i = 1; i <= numSubpatterns; ++i) {
             int start = subpatternResults[2 * i];
             if (start >= 0)
-                array->putDirectIndex(exec, i, jsSubstring(exec, input, start, subpatternResults[2 * i + 1] - start));
+                array->initializeIndex(vm, i, jsSubstring(exec, input, start, subpatternResults[2 * i + 1] - start), ContiguousShape);
             else
-                array->putDirectIndex(exec, i, jsUndefined());
+                array->initializeIndex(vm, i, jsUndefined(), ContiguousShape);
         }
     }
 
-    array->putDirect(exec->vm(), exec->propertyNames().index, jsNumber(result.start));
-    array->putDirect(exec->vm(), exec->propertyNames().input, input);
+    array->putDirect(vm, vm.propertyNames->index, jsNumber(result.start));
+    array->putDirect(vm, vm.propertyNames->input, input);
 
     return array;
 }