From 4700877d1636246aff6efb6a17d32b6716e99a38 Mon Sep 17 00:00:00 2001 From: "akling@apple.com" Date: Tue, 28 Apr 2015 00:14:47 +0000 Subject: [PATCH] RegExp matches arrays should use contiguous indexing. 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 | 32 ++++++++++++++++++++++ Source/JavaScriptCore/runtime/JSGlobalObject.cpp | 3 -- Source/JavaScriptCore/runtime/JSGlobalObject.h | 2 -- Source/JavaScriptCore/runtime/JSObject.h | 9 ++++-- .../JavaScriptCore/runtime/RegExpMatchesArray.cpp | 14 +++++----- 5 files changed, 46 insertions(+), 14 deletions(-) diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog index 9912d35..136cead 100644 --- a/Source/JavaScriptCore/ChangeLog +++ b/Source/JavaScriptCore/ChangeLog @@ -1,3 +1,35 @@ +2015-04-27 Andreas Kling + + RegExp matches arrays should use contiguous indexing. + + + 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 REGRESSION (r183373): ASSERT failed in wtf/SHA1.h diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp index 638ad28..1835168 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp +++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp @@ -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); diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.h b/Source/JavaScriptCore/runtime/JSGlobalObject.h index e5f2e6a..589fa39 100644 --- a/Source/JavaScriptCore/runtime/JSGlobalObject.h +++ b/Source/JavaScriptCore/runtime/JSGlobalObject.h @@ -232,7 +232,6 @@ protected: WriteBarrier m_namedFunctionStructure; PropertyOffset m_functionNameOffset; WriteBarrier m_privateNameStructure; - WriteBarrier m_regExpMatchesArrayStructure; WriteBarrier m_regExpStructure; WriteBarrier m_consoleStructure; WriteBarrier 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(); } diff --git a/Source/JavaScriptCore/runtime/JSObject.h b/Source/JavaScriptCore/runtime/JSObject.h index a46902a..d6282b07 100644 --- a/Source/JavaScriptCore/runtime/JSObject.h +++ b/Source/JavaScriptCore/runtime/JSObject.h @@ -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; diff --git a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp index 3461cf0..9157c67 100644 --- a/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp +++ b/Source/JavaScriptCore/runtime/RegExpMatchesArray.cpp @@ -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 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(position) == result.start); ASSERT(result.start == static_cast(subpatternResults[0])); ASSERT(result.end == static_cast(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; } -- 1.8.3.1