Title: [240593] trunk/Source/_javascript_Core
Revision
240593
Author
[email protected]
Date
2019-01-28 11:52:17 -0800 (Mon, 28 Jan 2019)

Log Message

[JSC] RegExpConstructor should not have own IsoSubspace
https://bugs.webkit.org/show_bug.cgi?id=193801

Reviewed by Mark Lam.

This patch finally removes RegExpConstructor's cached data to JSGlobalObject and remove IsoSubspace for RegExpConstructor.
sizeof(RegExpConstructor) != sizeof(InternalFunction), so that we have 16KB memory just for RegExpConstructor. But cached
regexp matching data (e.g. `RegExp.$1`) is per-JSGlobalObject one, and we can move this data to JSGlobalObject and remove
it from RegExpConstructor members.

We introduce RegExpGlobalData, which holds the per-global RegExp matching data. And we perform `performMatch` etc. with
JSGlobalObject instead of RegExpConstructor. This change requires small changes in DFG / FTL's RecordRegExpCachedResult
node since its 1st argument is changed from RegExpConstructor to JSGlobalObject.

We also move emptyRegExp from RegExpPrototype to VM's RegExpCache because it is more natural place to put it.

* CMakeLists.txt:
* _javascript_Core.xcodeproj/project.pbxproj:
* Sources.txt:
* dfg/DFGOperations.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileRecordRegExpCachedResult):
* dfg/DFGStrengthReductionPhase.cpp:
(JSC::DFG::StrengthReductionPhase::handleNode):
* ftl/FTLAbstractHeapRepository.cpp:
* ftl/FTLAbstractHeapRepository.h:
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileRecordRegExpCachedResult):
* runtime/JSGlobalObject.cpp:
(JSC::JSGlobalObject::init):
(JSC::JSGlobalObject::visitChildren):
* runtime/JSGlobalObject.h:
(JSC::JSGlobalObject::regExpGlobalData):
(JSC::JSGlobalObject::regExpGlobalDataOffset):
(JSC::JSGlobalObject::regExpConstructor const): Deleted.
* runtime/RegExpCache.cpp:
(JSC::RegExpCache::initialize):
* runtime/RegExpCache.h:
(JSC::RegExpCache::emptyRegExp const):
* runtime/RegExpCachedResult.cpp:
(JSC::RegExpCachedResult::visitAggregate):
(JSC::RegExpCachedResult::visitChildren): Deleted.
* runtime/RegExpCachedResult.h:
(JSC::RegExpCachedResult::RegExpCachedResult): Deleted.
* runtime/RegExpConstructor.cpp:
(JSC::RegExpConstructor::RegExpConstructor):
(JSC::regExpConstructorDollar):
(JSC::regExpConstructorInput):
(JSC::regExpConstructorMultiline):
(JSC::regExpConstructorLastMatch):
(JSC::regExpConstructorLastParen):
(JSC::regExpConstructorLeftContext):
(JSC::regExpConstructorRightContext):
(JSC::setRegExpConstructorInput):
(JSC::setRegExpConstructorMultiline):
(JSC::RegExpConstructor::destroy): Deleted.
(JSC::RegExpConstructor::visitChildren): Deleted.
(JSC::RegExpConstructor::getBackref): Deleted.
(JSC::RegExpConstructor::getLastParen): Deleted.
(JSC::RegExpConstructor::getLeftContext): Deleted.
(JSC::RegExpConstructor::getRightContext): Deleted.
* runtime/RegExpConstructor.h:
(JSC::RegExpConstructor::performMatch): Deleted.
(JSC::RegExpConstructor::recordMatch): Deleted.
* runtime/RegExpGlobalData.cpp: Added.
(JSC::RegExpGlobalData::visitAggregate):
(JSC::RegExpGlobalData::getBackref):
(JSC::RegExpGlobalData::getLastParen):
(JSC::RegExpGlobalData::getLeftContext):
(JSC::RegExpGlobalData::getRightContext):
* runtime/RegExpGlobalData.h: Added.
(JSC::RegExpGlobalData::cachedResult):
(JSC::RegExpGlobalData::setMultiline):
(JSC::RegExpGlobalData::multiline const):
(JSC::RegExpGlobalData::input):
(JSC::RegExpGlobalData::offsetOfCachedResult):
* runtime/RegExpGlobalDataInlines.h: Added.
(JSC::RegExpGlobalData::setInput):
(JSC::RegExpGlobalData::performMatch):
(JSC::RegExpGlobalData::recordMatch):
* runtime/RegExpObject.cpp:
(JSC::RegExpObject::matchGlobal):
* runtime/RegExpObjectInlines.h:
(JSC::RegExpObject::execInline):
(JSC::RegExpObject::matchInline):
(JSC::collectMatches):
* runtime/RegExpPrototype.cpp:
(JSC::RegExpPrototype::finishCreation):
(JSC::regExpProtoFuncSearchFast):
(JSC::RegExpPrototype::visitChildren): Deleted.
* runtime/RegExpPrototype.h:
* runtime/StringPrototype.cpp:
(JSC::removeUsingRegExpSearch):
(JSC::replaceUsingRegExpSearch):
* runtime/VM.cpp:
(JSC::VM::VM):
* runtime/VM.h:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/_javascript_Core/CMakeLists.txt (240592 => 240593)


--- trunk/Source/_javascript_Core/CMakeLists.txt	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/CMakeLists.txt	2019-01-28 19:52:17 UTC (rev 240593)
@@ -905,6 +905,8 @@
     runtime/PutDirectIndexMode.h
     runtime/PutPropertySlot.h
     runtime/RegExp.h
+    runtime/RegExpCachedResult.h
+    runtime/RegExpGlobalData.h
     runtime/RegExpKey.h
     runtime/RegExpObject.h
     runtime/RuntimeFlags.h

Modified: trunk/Source/_javascript_Core/ChangeLog (240592 => 240593)


--- trunk/Source/_javascript_Core/ChangeLog	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/ChangeLog	2019-01-28 19:52:17 UTC (rev 240593)
@@ -1,3 +1,103 @@
+2019-01-28  Yusuke Suzuki  <[email protected]>
+
+        [JSC] RegExpConstructor should not have own IsoSubspace
+        https://bugs.webkit.org/show_bug.cgi?id=193801
+
+        Reviewed by Mark Lam.
+
+        This patch finally removes RegExpConstructor's cached data to JSGlobalObject and remove IsoSubspace for RegExpConstructor.
+        sizeof(RegExpConstructor) != sizeof(InternalFunction), so that we have 16KB memory just for RegExpConstructor. But cached
+        regexp matching data (e.g. `RegExp.$1`) is per-JSGlobalObject one, and we can move this data to JSGlobalObject and remove
+        it from RegExpConstructor members.
+
+        We introduce RegExpGlobalData, which holds the per-global RegExp matching data. And we perform `performMatch` etc. with
+        JSGlobalObject instead of RegExpConstructor. This change requires small changes in DFG / FTL's RecordRegExpCachedResult
+        node since its 1st argument is changed from RegExpConstructor to JSGlobalObject.
+
+        We also move emptyRegExp from RegExpPrototype to VM's RegExpCache because it is more natural place to put it.
+
+        * CMakeLists.txt:
+        * _javascript_Core.xcodeproj/project.pbxproj:
+        * Sources.txt:
+        * dfg/DFGOperations.cpp:
+        * dfg/DFGSpeculativeJIT.cpp:
+        (JSC::DFG::SpeculativeJIT::compileRecordRegExpCachedResult):
+        * dfg/DFGStrengthReductionPhase.cpp:
+        (JSC::DFG::StrengthReductionPhase::handleNode):
+        * ftl/FTLAbstractHeapRepository.cpp:
+        * ftl/FTLAbstractHeapRepository.h:
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::compileRecordRegExpCachedResult):
+        * runtime/JSGlobalObject.cpp:
+        (JSC::JSGlobalObject::init):
+        (JSC::JSGlobalObject::visitChildren):
+        * runtime/JSGlobalObject.h:
+        (JSC::JSGlobalObject::regExpGlobalData):
+        (JSC::JSGlobalObject::regExpGlobalDataOffset):
+        (JSC::JSGlobalObject::regExpConstructor const): Deleted.
+        * runtime/RegExpCache.cpp:
+        (JSC::RegExpCache::initialize):
+        * runtime/RegExpCache.h:
+        (JSC::RegExpCache::emptyRegExp const):
+        * runtime/RegExpCachedResult.cpp:
+        (JSC::RegExpCachedResult::visitAggregate):
+        (JSC::RegExpCachedResult::visitChildren): Deleted.
+        * runtime/RegExpCachedResult.h:
+        (JSC::RegExpCachedResult::RegExpCachedResult): Deleted.
+        * runtime/RegExpConstructor.cpp:
+        (JSC::RegExpConstructor::RegExpConstructor):
+        (JSC::regExpConstructorDollar):
+        (JSC::regExpConstructorInput):
+        (JSC::regExpConstructorMultiline):
+        (JSC::regExpConstructorLastMatch):
+        (JSC::regExpConstructorLastParen):
+        (JSC::regExpConstructorLeftContext):
+        (JSC::regExpConstructorRightContext):
+        (JSC::setRegExpConstructorInput):
+        (JSC::setRegExpConstructorMultiline):
+        (JSC::RegExpConstructor::destroy): Deleted.
+        (JSC::RegExpConstructor::visitChildren): Deleted.
+        (JSC::RegExpConstructor::getBackref): Deleted.
+        (JSC::RegExpConstructor::getLastParen): Deleted.
+        (JSC::RegExpConstructor::getLeftContext): Deleted.
+        (JSC::RegExpConstructor::getRightContext): Deleted.
+        * runtime/RegExpConstructor.h:
+        (JSC::RegExpConstructor::performMatch): Deleted.
+        (JSC::RegExpConstructor::recordMatch): Deleted.
+        * runtime/RegExpGlobalData.cpp: Added.
+        (JSC::RegExpGlobalData::visitAggregate):
+        (JSC::RegExpGlobalData::getBackref):
+        (JSC::RegExpGlobalData::getLastParen):
+        (JSC::RegExpGlobalData::getLeftContext):
+        (JSC::RegExpGlobalData::getRightContext):
+        * runtime/RegExpGlobalData.h: Added.
+        (JSC::RegExpGlobalData::cachedResult):
+        (JSC::RegExpGlobalData::setMultiline):
+        (JSC::RegExpGlobalData::multiline const):
+        (JSC::RegExpGlobalData::input):
+        (JSC::RegExpGlobalData::offsetOfCachedResult):
+        * runtime/RegExpGlobalDataInlines.h: Added.
+        (JSC::RegExpGlobalData::setInput):
+        (JSC::RegExpGlobalData::performMatch):
+        (JSC::RegExpGlobalData::recordMatch):
+        * runtime/RegExpObject.cpp:
+        (JSC::RegExpObject::matchGlobal):
+        * runtime/RegExpObjectInlines.h:
+        (JSC::RegExpObject::execInline):
+        (JSC::RegExpObject::matchInline):
+        (JSC::collectMatches):
+        * runtime/RegExpPrototype.cpp:
+        (JSC::RegExpPrototype::finishCreation):
+        (JSC::regExpProtoFuncSearchFast):
+        (JSC::RegExpPrototype::visitChildren): Deleted.
+        * runtime/RegExpPrototype.h:
+        * runtime/StringPrototype.cpp:
+        (JSC::removeUsingRegExpSearch):
+        (JSC::replaceUsingRegExpSearch):
+        * runtime/VM.cpp:
+        (JSC::VM::VM):
+        * runtime/VM.h:
+
 2018-12-15  Darin Adler  <[email protected]>
 
         Replace many uses of String::format with more type-safe alternatives

Modified: trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj (240592 => 240593)


--- trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/_javascript_Core.xcodeproj/project.pbxproj	2019-01-28 19:52:17 UTC (rev 240593)
@@ -1733,6 +1733,7 @@
 		E3201C1E1F8E824C0076A032 /* ScriptFetchParameters.h in Headers */ = {isa = PBXBuildFile; fileRef = E38D060C1F8E814100649CF2 /* ScriptFetchParameters.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E322E5A31DA64439006E7709 /* DFGSnippetParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E322E5A11DA64435006E7709 /* DFGSnippetParams.h */; };
 		E322E5A71DA644A8006E7709 /* FTLSnippetParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E322E5A51DA644A4006E7709 /* FTLSnippetParams.h */; };
+		E325956421FDA2C9008EDC9C /* RegExpGlobalDataInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E325956321FDA2C8008EDC9C /* RegExpGlobalDataInlines.h */; };
 		E3282BBB1FE930AF00EDAF71 /* YarrErrorCode.h in Headers */ = {isa = PBXBuildFile; fileRef = E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E328C6C71DA4304500D255FD /* MaxFrameExtentForSlowPathCall.h in Headers */ = {isa = PBXBuildFile; fileRef = 65860177185A8F5E00030EEE /* MaxFrameExtentForSlowPathCall.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E328C6C81DA4306100D255FD /* RegisterAtOffsetList.h in Headers */ = {isa = PBXBuildFile; fileRef = 6540C79D1B82D99D000F6B79 /* RegisterAtOffsetList.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1741,6 +1742,7 @@
 		E328DAE91D38D005001A2529 /* BytecodeGraph.h in Headers */ = {isa = PBXBuildFile; fileRef = E3D264281D38C042000BE174 /* BytecodeGraph.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E328DAEB1D38D005001A2529 /* BytecodeRewriter.h in Headers */ = {isa = PBXBuildFile; fileRef = E3D2642A1D38C042000BE174 /* BytecodeRewriter.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E32AB2441DCD75F400D7533A /* MacroAssemblerHelpers.h in Headers */ = {isa = PBXBuildFile; fileRef = E380A76B1DCD7195000F89E6 /* MacroAssemblerHelpers.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		E334CBB521FD96A9000EB178 /* RegExpGlobalData.h in Headers */ = {isa = PBXBuildFile; fileRef = E334CBB321FD96A9000EB178 /* RegExpGlobalData.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E33637A61B63220200EE0840 /* ReflectObject.h in Headers */ = {isa = PBXBuildFile; fileRef = E33637A41B63220200EE0840 /* ReflectObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E33B3E261B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h in Headers */ = {isa = PBXBuildFile; fileRef = E33B3E251B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h */; };
 		E33E8D1D1B9013C300346B52 /* JSNativeStdFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = E33E8D1B1B9013C300346B52 /* JSNativeStdFunction.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -1767,6 +1769,7 @@
 		E3A0531C21342B680022EC14 /* WasmSectionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A0531821342B670022EC14 /* WasmSectionParser.h */; };
 		E3A32BC71FC83147007D7E76 /* WeakMapImpl.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A32BC61FC8312E007D7E76 /* WeakMapImpl.h */; };
 		E3A421431D6F58930007C617 /* PreciseJumpTargetsInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = E3A421421D6F588F0007C617 /* PreciseJumpTargetsInlines.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		E3AC277721FDB4940024452C /* RegExpCachedResult.h in Headers */ = {isa = PBXBuildFile; fileRef = 86F75EFC151C062F007C9BA3 /* RegExpCachedResult.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E3BFA5D021E853A1009C0EBA /* DFGDesiredGlobalProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = E3BFA5CD21E853A1009C0EBA /* DFGDesiredGlobalProperty.h */; };
 		E3BFD0BC1DAF808E0065DEA2 /* AccessCaseSnippetParams.h in Headers */ = {isa = PBXBuildFile; fileRef = E3BFD0BA1DAF807C0065DEA2 /* AccessCaseSnippetParams.h */; };
 		E3C295DD1ED2CBDA00D3016F /* ObjectPropertyChangeAdaptiveWatchpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = E3C295DC1ED2CBAA00D3016F /* ObjectPropertyChangeAdaptiveWatchpoint.h */; };
@@ -4650,6 +4653,7 @@
 		E322E5A11DA64435006E7709 /* DFGSnippetParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGSnippetParams.h; path = dfg/DFGSnippetParams.h; sourceTree = "<group>"; };
 		E322E5A41DA644A4006E7709 /* FTLSnippetParams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = FTLSnippetParams.cpp; path = ftl/FTLSnippetParams.cpp; sourceTree = "<group>"; };
 		E322E5A51DA644A4006E7709 /* FTLSnippetParams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FTLSnippetParams.h; path = ftl/FTLSnippetParams.h; sourceTree = "<group>"; };
+		E325956321FDA2C8008EDC9C /* RegExpGlobalDataInlines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpGlobalDataInlines.h; sourceTree = "<group>"; };
 		E326C4961ECBEF5700A9A905 /* ClassInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ClassInfo.cpp; sourceTree = "<group>"; };
 		E3282BB91FE930A300EDAF71 /* YarrErrorCode.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = YarrErrorCode.cpp; path = yarr/YarrErrorCode.cpp; sourceTree = "<group>"; };
 		E3282BBA1FE930A400EDAF71 /* YarrErrorCode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = YarrErrorCode.h; path = yarr/YarrErrorCode.h; sourceTree = "<group>"; };
@@ -4657,6 +4661,8 @@
 		E3305FB020B0F78700CEB82B /* InByIdVariant.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InByIdVariant.cpp; sourceTree = "<group>"; };
 		E3305FB120B0F78800CEB82B /* InByIdVariant.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InByIdVariant.h; sourceTree = "<group>"; };
 		E3305FB220B0F78800CEB82B /* InByIdStatus.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InByIdStatus.cpp; sourceTree = "<group>"; };
+		E334CBB221FD96A8000EB178 /* RegExpGlobalData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RegExpGlobalData.cpp; sourceTree = "<group>"; };
+		E334CBB321FD96A9000EB178 /* RegExpGlobalData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegExpGlobalData.h; sourceTree = "<group>"; };
 		E33637A31B63220200EE0840 /* ReflectObject.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ReflectObject.cpp; sourceTree = "<group>"; };
 		E33637A41B63220200EE0840 /* ReflectObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ReflectObject.h; sourceTree = "<group>"; };
 		E33B3E251B7ABD750048DB2E /* InspectorInstrumentationObject.lut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorInstrumentationObject.lut.h; sourceTree = "<group>"; };
@@ -7077,6 +7083,9 @@
 				86F75EFC151C062F007C9BA3 /* RegExpCachedResult.h */,
 				BCD202BD0E1706A7002C7E82 /* RegExpConstructor.cpp */,
 				BCD202BE0E1706A7002C7E82 /* RegExpConstructor.h */,
+				E334CBB221FD96A8000EB178 /* RegExpGlobalData.cpp */,
+				E334CBB321FD96A9000EB178 /* RegExpGlobalData.h */,
+				E325956321FDA2C8008EDC9C /* RegExpGlobalDataInlines.h */,
 				0F7C39FA1C8F629300480151 /* RegExpInlines.h */,
 				A1712B4011C7B235007A5315 /* RegExpKey.h */,
 				86F75EFD151C062F007C9BA3 /* RegExpMatchesArray.cpp */,
@@ -9561,8 +9570,11 @@
 				0FA7A8EC18B413C80052371D /* Reg.h in Headers */,
 				BC18C45A0E16F5CD00B34460 /* RegExp.h in Headers */,
 				A1712B3F11C7B228007A5315 /* RegExpCache.h in Headers */,
+				E3AC277721FDB4940024452C /* RegExpCachedResult.h in Headers */,
 				BCD202C20E1706A7002C7E82 /* RegExpConstructor.h in Headers */,
 				BCD202D60E170708002C7E82 /* RegExpConstructor.lut.h in Headers */,
+				E334CBB521FD96A9000EB178 /* RegExpGlobalData.h in Headers */,
+				E325956421FDA2C9008EDC9C /* RegExpGlobalDataInlines.h in Headers */,
 				0F7C39FB1C8F629300480151 /* RegExpInlines.h in Headers */,
 				A1712B4111C7B235007A5315 /* RegExpKey.h in Headers */,
 				BC18C45B0E16F5CD00B34460 /* RegExpObject.h in Headers */,

Modified: trunk/Source/_javascript_Core/Sources.txt (240592 => 240593)


--- trunk/Source/_javascript_Core/Sources.txt	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/Sources.txt	2019-01-28 19:52:17 UTC (rev 240593)
@@ -902,6 +902,7 @@
 runtime/RegExpCache.cpp
 runtime/RegExpCachedResult.cpp
 runtime/RegExpConstructor.cpp
+runtime/RegExpGlobalData.cpp
 runtime/RegExpMatchesArray.cpp
 runtime/RegExpObject.cpp
 runtime/RegExpPrototype.cpp

Modified: trunk/Source/_javascript_Core/dfg/DFGOperations.cpp (240592 => 240593)


--- trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/dfg/DFGOperations.cpp	2019-01-28 19:52:17 UTC (rev 240593)
@@ -65,7 +65,7 @@
 #include "ObjectConstructor.h"
 #include "Operations.h"
 #include "ParseInt.h"
-#include "RegExpConstructor.h"
+#include "RegExpGlobalDataInlines.h"
 #include "RegExpMatchesArray.h"
 #include "RegExpObjectInlines.h"
 #include "Repatch.h"
@@ -1174,7 +1174,6 @@
 
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    RegExpConstructor* regExpConstructor = globalObject->regExpConstructor();
     String input = string->value(exec);
     RETURN_IF_EXCEPTION(scope, { });
 
@@ -1187,7 +1186,7 @@
     }
 
     RETURN_IF_EXCEPTION(scope, { });
-    regExpConstructor->recordMatch(vm, regExp, string, result);
+    globalObject->regExpGlobalData().recordMatch(vm, globalObject, regExp, string, result);
     return JSValue::encode(array);
 }
 
@@ -1217,12 +1216,10 @@
     String s = string->value(exec);
     RETURN_IF_EXCEPTION(scope, { });
 
-    RegExpConstructor* regExpConstructor = globalObject->regExpConstructor();
-
     if (regExp->unicode()) {
         unsigned stringLength = s.length();
         RELEASE_AND_RETURN(scope, JSValue::encode(collectMatches(
-            vm, exec, string, s, regExpConstructor, regExp,
+            vm, exec, string, s, globalObject, regExp,
             [&] (size_t end) -> size_t {
                 return advanceStringUnicode(s, stringLength, end);
             })));
@@ -1229,7 +1226,7 @@
     }
 
     RELEASE_AND_RETURN(scope, JSValue::encode(collectMatches(
-        vm, exec, string, s, regExpConstructor, regExp,
+        vm, exec, string, s, globalObject, regExp,
         [&] (size_t end) -> size_t {
             return end + 1;
         })));

Modified: trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp (240592 => 240593)


--- trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/dfg/DFGSpeculativeJIT.cpp	2019-01-28 19:52:17 UTC (rev 240593)
@@ -58,7 +58,7 @@
 #include "JSLexicalEnvironment.h"
 #include "JSPropertyNameEnumerator.h"
 #include "LinkBuffer.h"
-#include "RegExpConstructor.h"
+#include "RegExpObject.h"
 #include "ScopedArguments.h"
 #include "ScratchRegisterAllocator.h"
 #include "SuperSampler.h"
@@ -11491,45 +11491,45 @@
 
 void SpeculativeJIT::compileRecordRegExpCachedResult(Node* node)
 {
-    Edge constructorEdge = m_jit.graph().varArgChild(node, 0);
+    Edge globalObjectEdge = m_jit.graph().varArgChild(node, 0);
     Edge regExpEdge = m_jit.graph().varArgChild(node, 1);
     Edge stringEdge = m_jit.graph().varArgChild(node, 2);
     Edge startEdge = m_jit.graph().varArgChild(node, 3);
     Edge endEdge = m_jit.graph().varArgChild(node, 4);
 
-    SpeculateCellOperand constructor(this, constructorEdge);
+    SpeculateCellOperand globalObject(this, globalObjectEdge);
     SpeculateCellOperand regExp(this, regExpEdge);
     SpeculateCellOperand string(this, stringEdge);
     SpeculateInt32Operand start(this, startEdge);
     SpeculateInt32Operand end(this, endEdge);
 
-    GPRReg constructorGPR = constructor.gpr();
+    GPRReg globalObjectGPR = globalObject.gpr();
     GPRReg regExpGPR = regExp.gpr();
     GPRReg stringGPR = string.gpr();
     GPRReg startGPR = start.gpr();
     GPRReg endGPR = end.gpr();
 
-    ptrdiff_t offset = RegExpConstructor::offsetOfCachedResult();
+    ptrdiff_t offset = JSGlobalObject::regExpGlobalDataOffset() + RegExpGlobalData::offsetOfCachedResult();
 
     m_jit.storePtr(
         regExpGPR,
-        JITCompiler::Address(constructorGPR, offset + RegExpCachedResult::offsetOfLastRegExp()));
+        JITCompiler::Address(globalObjectGPR, offset + RegExpCachedResult::offsetOfLastRegExp()));
     m_jit.storePtr(
         stringGPR,
-        JITCompiler::Address(constructorGPR, offset + RegExpCachedResult::offsetOfLastInput()));
+        JITCompiler::Address(globalObjectGPR, offset + RegExpCachedResult::offsetOfLastInput()));
     m_jit.store32(
         startGPR,
         JITCompiler::Address(
-            constructorGPR,
+            globalObjectGPR,
             offset + RegExpCachedResult::offsetOfResult() + OBJECT_OFFSETOF(MatchResult, start)));
     m_jit.store32(
         endGPR,
         JITCompiler::Address(
-            constructorGPR,
+            globalObjectGPR,
             offset + RegExpCachedResult::offsetOfResult() + OBJECT_OFFSETOF(MatchResult, end)));
     m_jit.store8(
         TrustedImm32(0),
-        JITCompiler::Address(constructorGPR, offset + RegExpCachedResult::offsetOfReified()));
+        JITCompiler::Address(globalObjectGPR, offset + RegExpCachedResult::offsetOfReified()));
 
     noResult(node);
 }

Modified: trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp (240592 => 240593)


--- trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/dfg/DFGStrengthReductionPhase.cpp	2019-01-28 19:52:17 UTC (rev 240593)
@@ -37,7 +37,7 @@
 #include "DFGVariableAccessDataDump.h"
 #include "JSCInlines.h"
 #include "MathCommon.h"
-#include "RegExpConstructor.h"
+#include "RegExpObject.h"
 #include "StringPrototype.h"
 #include <cstdlib>
 #include <wtf/text/StringBuilder.h>
@@ -620,8 +620,7 @@
                 }
                 m_graph.registerStructure(structure);
 
-                RegExpConstructor* constructor = globalObject->regExpConstructor();
-                FrozenValue* constructorFrozenValue = m_graph.freeze(constructor);
+                FrozenValue* globalObjectFrozenValue = m_graph.freeze(globalObject);
 
                 MatchResult result;
                 Vector<int> ovector;
@@ -736,7 +735,7 @@
                 } else
                     m_graph.convertToConstant(m_node, jsBoolean(!!result));
 
-                // Whether it's Exec or Test, we need to tell the constructor and RegExpObject what's up.
+                // Whether it's Exec or Test, we need to tell the globalObject and RegExpObject what's up.
                 // Because SetRegExpObjectLastIndex may exit and it clobbers exit state, we do that
                 // first.
 
@@ -756,7 +755,7 @@
                     unsigned firstChild = m_graph.m_varArgChildren.size();
                     m_graph.m_varArgChildren.append(
                         m_insertionSet.insertConstantForUse(
-                            m_nodeIndex, origin, constructorFrozenValue, KnownCellUse));
+                            m_nodeIndex, origin, globalObjectFrozenValue, KnownCellUse));
                     m_graph.m_varArgChildren.append(
                         m_insertionSet.insertConstantForUse(
                             m_nodeIndex, origin, regExpFrozenValue, KnownCellUse));

Modified: trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.cpp (240592 => 240593)


--- trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.cpp	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.cpp	2019-01-28 19:52:17 UTC (rev 240593)
@@ -39,7 +39,6 @@
 #include "JSPropertyNameEnumerator.h"
 #include "JSScope.h"
 #include "JSCInlines.h"
-#include "RegExpConstructor.h"
 #include "RegExpObject.h"
 #include "ScopedArguments.h"
 #include "ScopedArgumentsTable.h"

Modified: trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h (240592 => 240593)


--- trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h	2019-01-28 19:52:17 UTC (rev 240593)
@@ -33,6 +33,7 @@
 #include "HasOwnPropertyCache.h"
 #include "IndexingType.h"
 #include "JSFixedArray.h"
+#include "JSGlobalObject.h"
 #include "JSMap.h"
 #include "JSSet.h"
 #include "JSWeakMap.h"
@@ -75,6 +76,11 @@
     macro(JSFunction_executable, JSFunction::offsetOfExecutable()) \
     macro(JSFunction_scope, JSFunction::offsetOfScopeChain()) \
     macro(JSFunction_rareData, JSFunction::offsetOfRareData()) \
+    macro(JSGlobalObject_regExpGlobalData_cachedResult_lastRegExp, JSGlobalObject::regExpGlobalDataOffset() + RegExpGlobalData::offsetOfCachedResult() + RegExpCachedResult::offsetOfLastRegExp()) \
+    macro(JSGlobalObject_regExpGlobalData_cachedResult_lastInput, JSGlobalObject::regExpGlobalDataOffset() + RegExpGlobalData::offsetOfCachedResult() + RegExpCachedResult::offsetOfLastInput()) \
+    macro(JSGlobalObject_regExpGlobalData_cachedResult_result_start, JSGlobalObject::regExpGlobalDataOffset() + RegExpGlobalData::offsetOfCachedResult() + RegExpCachedResult::offsetOfResult() + OBJECT_OFFSETOF(MatchResult, start)) \
+    macro(JSGlobalObject_regExpGlobalData_cachedResult_result_end, JSGlobalObject::regExpGlobalDataOffset() + RegExpGlobalData::offsetOfCachedResult() + RegExpCachedResult::offsetOfResult() + OBJECT_OFFSETOF(MatchResult, end)) \
+    macro(JSGlobalObject_regExpGlobalData_cachedResult_reified, JSGlobalObject::regExpGlobalDataOffset() + RegExpGlobalData::offsetOfCachedResult() + RegExpCachedResult::offsetOfReified()) \
     macro(JSObject_butterfly, JSObject::butterflyOffset()) \
     macro(JSPropertyNameEnumerator_cachedInlineCapacity, JSPropertyNameEnumerator::cachedInlineCapacityOffset()) \
     macro(JSPropertyNameEnumerator_cachedPropertyNamesVector, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()) \
@@ -87,11 +93,6 @@
     macro(JSString_value, JSString::offsetOfValue()) \
     macro(JSSymbolTableObject_symbolTable, JSSymbolTableObject::offsetOfSymbolTable()) \
     macro(JSWrapperObject_internalValue, JSWrapperObject::internalValueOffset()) \
-    macro(RegExpConstructor_cachedResult_lastRegExp, RegExpConstructor::offsetOfCachedResult() + RegExpCachedResult::offsetOfLastRegExp()) \
-    macro(RegExpConstructor_cachedResult_lastInput, RegExpConstructor::offsetOfCachedResult() + RegExpCachedResult::offsetOfLastInput()) \
-    macro(RegExpConstructor_cachedResult_result_start, RegExpConstructor::offsetOfCachedResult() + RegExpCachedResult::offsetOfResult() + OBJECT_OFFSETOF(MatchResult, start)) \
-    macro(RegExpConstructor_cachedResult_result_end, RegExpConstructor::offsetOfCachedResult() + RegExpCachedResult::offsetOfResult() + OBJECT_OFFSETOF(MatchResult, end)) \
-    macro(RegExpConstructor_cachedResult_reified, RegExpConstructor::offsetOfCachedResult() + RegExpCachedResult::offsetOfReified()) \
     macro(RegExpObject_regExp, RegExpObject::offsetOfRegExp()) \
     macro(RegExpObject_lastIndex, RegExpObject::offsetOfLastIndex()) \
     macro(RegExpObject_lastIndexIsWritable, RegExpObject::offsetOfLastIndexIsWritable()) \

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (240592 => 240593)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp	2019-01-28 19:52:17 UTC (rev 240593)
@@ -11303,25 +11303,25 @@
 
     void compileRecordRegExpCachedResult()
     {
-        Edge constructorEdge = m_graph.varArgChild(m_node, 0);
+        Edge globalObjectEdge = m_graph.varArgChild(m_node, 0);
         Edge regExpEdge = m_graph.varArgChild(m_node, 1);
         Edge stringEdge = m_graph.varArgChild(m_node, 2);
         Edge startEdge = m_graph.varArgChild(m_node, 3);
         Edge endEdge = m_graph.varArgChild(m_node, 4);
         
-        LValue constructor = lowCell(constructorEdge);
+        LValue globalObject = lowCell(globalObjectEdge);
         LValue regExp = lowCell(regExpEdge);
         LValue string = lowCell(stringEdge);
         LValue start = lowInt32(startEdge);
         LValue end = lowInt32(endEdge);
 
-        m_out.storePtr(regExp, constructor, m_heaps.RegExpConstructor_cachedResult_lastRegExp);
-        m_out.storePtr(string, constructor, m_heaps.RegExpConstructor_cachedResult_lastInput);
-        m_out.store32(start, constructor, m_heaps.RegExpConstructor_cachedResult_result_start);
-        m_out.store32(end, constructor, m_heaps.RegExpConstructor_cachedResult_result_end);
+        m_out.storePtr(regExp, globalObject, m_heaps.JSGlobalObject_regExpGlobalData_cachedResult_lastRegExp);
+        m_out.storePtr(string, globalObject, m_heaps.JSGlobalObject_regExpGlobalData_cachedResult_lastInput);
+        m_out.store32(start, globalObject, m_heaps.JSGlobalObject_regExpGlobalData_cachedResult_result_start);
+        m_out.store32(end, globalObject, m_heaps.JSGlobalObject_regExpGlobalData_cachedResult_result_end);
         m_out.store32As8(
             m_out.constInt32(0),
-            m_out.address(constructor, m_heaps.RegExpConstructor_cachedResult_reified));
+            m_out.address(globalObject, m_heaps.JSGlobalObject_regExpGlobalData_cachedResult_reified));
     }
     
     struct ArgumentsLength {

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.cpp	2019-01-28 19:52:17 UTC (rev 240593)
@@ -149,6 +149,7 @@
 #include "ProxyObject.h"
 #include "ProxyRevoke.h"
 #include "ReflectObject.h"
+#include "RegExpCache.h"
 #include "RegExpConstructor.h"
 #include "RegExpMatchesArray.h"
 #include "RegExpObject.h"
@@ -685,7 +686,8 @@
     ArrayConstructor* arrayConstructor = ArrayConstructor::create(vm, this, ArrayConstructor::createStructure(vm, this, m_functionPrototype.get()), m_arrayPrototype.get(), m_speciesGetterSetter.get());
     m_arrayConstructor.set(vm, this, arrayConstructor);
     
-    m_regExpConstructor.set(vm, this, RegExpConstructor::create(vm, RegExpConstructor::createStructure(vm, this, m_functionPrototype.get()), m_regExpPrototype.get(), m_speciesGetterSetter.get()));
+    RegExpConstructor* regExpConstructor = RegExpConstructor::create(vm, RegExpConstructor::createStructure(vm, this, m_functionPrototype.get()), m_regExpPrototype.get(), m_speciesGetterSetter.get());
+    m_regExpGlobalData.cachedResult().record(vm, this, vm.regExpCache()->emptyRegExp(), jsEmptyString(&vm), MatchResult(0, 0));
     
     JSArrayBufferConstructor* arrayBufferConstructor = JSArrayBufferConstructor::create(vm, JSArrayBufferConstructor::createStructure(vm, this, m_functionPrototype.get()), m_arrayBufferPrototype.get(), m_speciesGetterSetter.get());
     m_arrayBufferPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, arrayBufferConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
@@ -765,12 +767,12 @@
     m_objectPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, objectConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
     m_functionPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, functionConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
     m_arrayPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, arrayConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
-    m_regExpPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, m_regExpConstructor.get(), static_cast<unsigned>(PropertyAttribute::DontEnum));
+    m_regExpPrototype->putDirectWithoutTransition(vm, vm.propertyNames->constructor, regExpConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
     
     putDirectWithoutTransition(vm, vm.propertyNames->Object, objectConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
     putDirectWithoutTransition(vm, vm.propertyNames->Function, functionConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
     putDirectWithoutTransition(vm, vm.propertyNames->Array, arrayConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
-    putDirectWithoutTransition(vm, vm.propertyNames->RegExp, m_regExpConstructor.get(), static_cast<unsigned>(PropertyAttribute::DontEnum));
+    putDirectWithoutTransition(vm, vm.propertyNames->RegExp, regExpConstructor, static_cast<unsigned>(PropertyAttribute::DontEnum));
 
     putDirectWithoutTransition(vm, vm.propertyNames->builtinNames().ObjectPrivateName(), objectConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
     putDirectWithoutTransition(vm, vm.propertyNames->builtinNames().ArrayPrivateName(), arrayConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly);
@@ -905,7 +907,7 @@
         GlobalPropertyInfo(vm.propertyNames->builtinNames().BuiltinLogPrivateName(), builtinLog, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().BuiltinDescribePrivateName(), builtinDescribe, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().NumberPrivateName(), numberConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
-        GlobalPropertyInfo(vm.propertyNames->builtinNames().RegExpPrivateName(), m_regExpConstructor.get(), PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
+        GlobalPropertyInfo(vm.propertyNames->builtinNames().RegExpPrivateName(), regExpConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().StringPrivateName(), stringConstructor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().absPrivateName(), privateFuncAbs, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
         GlobalPropertyInfo(vm.propertyNames->builtinNames().floorPrivateName(), privateFuncFloor, PropertyAttribute::DontEnum | PropertyAttribute::DontDelete | PropertyAttribute::ReadOnly),
@@ -1560,7 +1562,6 @@
     visitor.append(thisObject->m_globalScopeExtension);
     visitor.append(thisObject->m_globalCallee);
     visitor.append(thisObject->m_stackOverflowFrameCallee);
-    visitor.append(thisObject->m_regExpConstructor);
     visitor.append(thisObject->m_errorConstructor);
     thisObject->m_evalErrorStructure.visit(visitor);
     thisObject->m_rangeErrorStructure.visit(visitor);
@@ -1705,6 +1706,7 @@
     visitor.append(thisObject->m_speciesGetterSetter);
     thisObject->m_typedArrayProto.visit(visitor);
     thisObject->m_typedArraySuperConstructor.visit(visitor);
+    thisObject->m_regExpGlobalData.visitAggregate(visitor);
 }
 
 ExecState* JSGlobalObject::globalExec()

Modified: trunk/Source/_javascript_Core/runtime/JSGlobalObject.h (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/JSGlobalObject.h	2019-01-28 19:52:17 UTC (rev 240593)
@@ -39,6 +39,7 @@
 #include "LazyProperty.h"
 #include "LazyClassStructure.h"
 #include "NumberPrototype.h"
+#include "RegExpGlobalData.h"
 #include "RuntimeFlags.h"
 #include "SpecialPointer.h"
 #include "StringPrototype.h"
@@ -259,7 +260,6 @@
     WriteBarrier<JSScope> m_globalScopeExtension;
     WriteBarrier<JSCallee> m_globalCallee;
     WriteBarrier<JSCallee> m_stackOverflowFrameCallee;
-    WriteBarrier<RegExpConstructor> m_regExpConstructor;
 
     WriteBarrier<ErrorConstructor> m_errorConstructor;
     LazyClassStructure m_evalErrorStructure;
@@ -446,6 +446,7 @@
     std::unique_ptr<JSGlobalObjectRareData> m_rareData;
 
     WeakRandom m_weakRandom;
+    RegExpGlobalData m_regExpGlobalData;
 
     JSCallee* stackOverflowFrameCallee() const { return m_stackOverflowFrameCallee.get(); }
 
@@ -576,8 +577,6 @@
 
     GetterSetter* speciesGetterSetter() const { return m_speciesGetterSetter.get(); }
 
-    RegExpConstructor* regExpConstructor() const { return m_regExpConstructor.get(); }
-
     ArrayConstructor* arrayConstructor() const { return m_arrayConstructor.get(); }
     ObjectConstructor* objectConstructor() const { return m_objectConstructor.get(); }
     JSPromiseConstructor* promiseConstructor() const { return m_promiseConstructor.get(); }
@@ -766,6 +765,9 @@
     JS_EXPORT_PRIVATE void setRemoteDebuggingEnabled(bool);
     JS_EXPORT_PRIVATE bool remoteDebuggingEnabled() const;
 
+    RegExpGlobalData& regExpGlobalData() { return m_regExpGlobalData; }
+    static ptrdiff_t regExpGlobalDataOffset() { return OBJECT_OFFSETOF(JSGlobalObject, m_regExpGlobalData); }
+
 #if ENABLE(REMOTE_INSPECTOR)
     Inspector::JSGlobalObjectInspectorController& inspectorController() const { return *m_inspectorController.get(); }
     JSGlobalObjectDebuggable& inspectorDebuggable() { return *m_inspectorDebuggable.get(); }

Modified: trunk/Source/_javascript_Core/runtime/RegExpCache.cpp (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/RegExpCache.cpp	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/RegExpCache.cpp	2019-01-28 19:52:17 UTC (rev 240593)
@@ -56,6 +56,11 @@
 {
 }
 
+void RegExpCache::initialize(VM& vm)
+{
+    m_emptyRegExp.set(vm, RegExp::create(vm, "", NoFlags));
+}
+
 void RegExpCache::finalize(Handle<Unknown> handle, void*)
 {
     RegExp* regExp = static_cast<RegExp*>(handle.get().asCell());

Modified: trunk/Source/_javascript_Core/runtime/RegExpCache.h (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/RegExpCache.h	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/RegExpCache.h	2019-01-28 19:52:17 UTC (rev 240593)
@@ -46,6 +46,10 @@
     RegExpCache(VM* vm);
     void deleteAllCode();
 
+    void initialize(VM&);
+
+    RegExp* emptyRegExp() const { return m_emptyRegExp.get(); }
+
 private:
     
     static const unsigned maxStrongCacheablePatternLength = 256;
@@ -59,6 +63,7 @@
     RegExpCacheMap m_weakCache; // Holds all regular expressions currently live.
     int m_nextEntryInStrongCache;
     std::array<Strong<RegExp>, maxStrongCacheableEntries> m_strongCache; // Holds a select few regular expressions that have compiled and executed
+    Strong<RegExp> m_emptyRegExp;
     VM* m_vm;
 };
 

Modified: trunk/Source/_javascript_Core/runtime/RegExpCachedResult.cpp (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/RegExpCachedResult.cpp	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/RegExpCachedResult.cpp	2019-01-28 19:52:17 UTC (rev 240593)
@@ -31,7 +31,7 @@
 
 namespace JSC {
 
-void RegExpCachedResult::visitChildren(SlotVisitor& visitor)
+void RegExpCachedResult::visitAggregate(SlotVisitor& visitor)
 {
     visitor.append(m_lastInput);
     visitor.append(m_lastRegExp);

Modified: trunk/Source/_javascript_Core/runtime/RegExpCachedResult.h (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/RegExpCachedResult.h	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/RegExpCachedResult.h	2019-01-28 19:52:17 UTC (rev 240593)
@@ -25,7 +25,7 @@
 
 #pragma once
 
-#include "RegExpObject.h"
+#include "RegExp.h"
 
 namespace JSC {
 
@@ -43,14 +43,6 @@
 // m_reifiedResult and m_reifiedInput hold the cached results.
 class RegExpCachedResult {
 public:
-    RegExpCachedResult(VM& vm, JSObject* owner, RegExp* emptyRegExp)
-        : m_result(0, 0)
-        , m_reified(false)
-    {
-        m_lastInput.set(vm, owner, jsEmptyString(&vm));
-        m_lastRegExp.set(vm, owner, emptyRegExp);
-    }
-
     ALWAYS_INLINE void record(VM& vm, JSObject* owner, RegExp* regExp, JSString* input, MatchResult result)
     {
         vm.heap.writeBarrier(owner);
@@ -71,7 +63,7 @@
         return m_reified ? m_reifiedInput.get() : m_lastInput.get();
     }
 
-    void visitChildren(SlotVisitor&);
+    void visitAggregate(SlotVisitor&);
 
     static ptrdiff_t offsetOfLastRegExp() { return OBJECT_OFFSETOF(RegExpCachedResult, m_lastRegExp); }
     static ptrdiff_t offsetOfLastInput() { return OBJECT_OFFSETOF(RegExpCachedResult, m_lastInput); }
@@ -79,8 +71,8 @@
     static ptrdiff_t offsetOfReified() { return OBJECT_OFFSETOF(RegExpCachedResult, m_reified); }
 
 private:
-    MatchResult m_result;
-    bool m_reified;
+    MatchResult m_result { 0, 0 };
+    bool m_reified { false };
     WriteBarrier<JSString> m_lastInput;
     WriteBarrier<RegExp> m_lastRegExp;
     WriteBarrier<JSArray> m_reifiedResult;

Modified: trunk/Source/_javascript_Core/runtime/RegExpConstructor.cpp (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/RegExpConstructor.cpp	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/RegExpConstructor.cpp	2019-01-28 19:52:17 UTC (rev 240593)
@@ -25,6 +25,7 @@
 #include "Error.h"
 #include "GetterSetter.h"
 #include "JSCInlines.h"
+#include "RegExpGlobalDataInlines.h"
 #include "RegExpPrototype.h"
 #include "StructureInlines.h"
 
@@ -80,10 +81,8 @@
 static EncodedJSValue JSC_HOST_CALL callRegExpConstructor(ExecState*);
 static EncodedJSValue JSC_HOST_CALL constructWithRegExpConstructor(ExecState*);
 
-RegExpConstructor::RegExpConstructor(VM& vm, Structure* structure, RegExpPrototype* regExpPrototype)
+RegExpConstructor::RegExpConstructor(VM& vm, Structure* structure)
     : InternalFunction(vm, structure, callRegExpConstructor, constructWithRegExpConstructor)
-    , m_cachedResult(vm, this, regExpPrototype->emptyRegExp())
-    , m_multiline(false)
 {
 }
 
@@ -98,95 +97,62 @@
     putDirectNonIndexAccessor(vm, vm.propertyNames->speciesSymbol, speciesSymbol, PropertyAttribute::Accessor | PropertyAttribute::ReadOnly | PropertyAttribute::DontEnum);
 }
 
-void RegExpConstructor::destroy(JSCell* cell)
-{
-    static_cast<RegExpConstructor*>(cell)->RegExpConstructor::~RegExpConstructor();
-}
-
-void RegExpConstructor::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    RegExpConstructor* thisObject = jsCast<RegExpConstructor*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    Base::visitChildren(thisObject, visitor);
-    thisObject->m_cachedResult.visitChildren(visitor);
-}
-
-JSValue RegExpConstructor::getBackref(ExecState* exec, unsigned i)
-{
-    JSArray* array = m_cachedResult.lastResult(exec, this);
-
-    if (i < array->length()) {
-        JSValue result = JSValue(array).get(exec, i);
-        ASSERT(result.isString() || result.isUndefined());
-        if (!result.isUndefined())
-            return result;
-    }
-    return jsEmptyString(exec);
-}
-
-JSValue RegExpConstructor::getLastParen(ExecState* exec)
-{
-    JSArray* array = m_cachedResult.lastResult(exec, this);
-    unsigned length = array->length();
-    if (length > 1) {
-        JSValue result = JSValue(array).get(exec, length - 1);
-        ASSERT(result.isString() || result.isUndefined());
-        if (!result.isUndefined())
-            return result;
-    }
-    return jsEmptyString(exec);
-}
-
-JSValue RegExpConstructor::getLeftContext(ExecState* exec)
-{
-    return m_cachedResult.leftContext(exec, this);
-}
-
-JSValue RegExpConstructor::getRightContext(ExecState* exec)
-{
-    return m_cachedResult.rightContext(exec, this);
-}
-
 template<int N>
 EncodedJSValue regExpConstructorDollar(ExecState* exec, EncodedJSValue thisValue, PropertyName)
 {
-    return JSValue::encode(jsCast<RegExpConstructor*>(JSValue::decode(thisValue))->getBackref(exec, N));
+    VM& vm = exec->vm();
+    JSGlobalObject* globalObject = jsCast<RegExpConstructor*>(JSValue::decode(thisValue))->globalObject(vm);
+    return JSValue::encode(globalObject->regExpGlobalData().getBackref(exec, globalObject, N));
 }
 
-EncodedJSValue regExpConstructorInput(ExecState*, EncodedJSValue thisValue, PropertyName)
+EncodedJSValue regExpConstructorInput(ExecState* exec, EncodedJSValue thisValue, PropertyName)
 {
-    return JSValue::encode(jsCast<RegExpConstructor*>(JSValue::decode(thisValue))->input());
+    VM& vm = exec->vm();
+    JSGlobalObject* globalObject = jsCast<RegExpConstructor*>(JSValue::decode(thisValue))->globalObject(vm);
+    return JSValue::encode(globalObject->regExpGlobalData().input());
 }
 
-EncodedJSValue regExpConstructorMultiline(ExecState*, EncodedJSValue thisValue, PropertyName)
+EncodedJSValue regExpConstructorMultiline(ExecState* exec, EncodedJSValue thisValue, PropertyName)
 {
-    return JSValue::encode(jsBoolean(jsCast<RegExpConstructor*>(JSValue::decode(thisValue))->multiline()));
+    VM& vm = exec->vm();
+    JSGlobalObject* globalObject = jsCast<RegExpConstructor*>(JSValue::decode(thisValue))->globalObject(vm);
+    return JSValue::encode(jsBoolean(globalObject->regExpGlobalData().multiline()));
 }
 
 EncodedJSValue regExpConstructorLastMatch(ExecState* exec, EncodedJSValue thisValue, PropertyName)
 {
-    return JSValue::encode(jsCast<RegExpConstructor*>(JSValue::decode(thisValue))->getBackref(exec, 0));
+    VM& vm = exec->vm();
+    JSGlobalObject* globalObject = jsCast<RegExpConstructor*>(JSValue::decode(thisValue))->globalObject(vm);
+    return JSValue::encode(globalObject->regExpGlobalData().getBackref(exec, globalObject, 0));
 }
 
 EncodedJSValue regExpConstructorLastParen(ExecState* exec, EncodedJSValue thisValue, PropertyName)
 {
-    return JSValue::encode(jsCast<RegExpConstructor*>(JSValue::decode(thisValue))->getLastParen(exec));
+    VM& vm = exec->vm();
+    JSGlobalObject* globalObject = jsCast<RegExpConstructor*>(JSValue::decode(thisValue))->globalObject(vm);
+    return JSValue::encode(globalObject->regExpGlobalData().getLastParen(exec, globalObject));
 }
 
 EncodedJSValue regExpConstructorLeftContext(ExecState* exec, EncodedJSValue thisValue, PropertyName)
 {
-    return JSValue::encode(jsCast<RegExpConstructor*>(JSValue::decode(thisValue))->getLeftContext(exec));
+    VM& vm = exec->vm();
+    JSGlobalObject* globalObject = jsCast<RegExpConstructor*>(JSValue::decode(thisValue))->globalObject(vm);
+    return JSValue::encode(globalObject->regExpGlobalData().getLeftContext(exec, globalObject));
 }
 
 EncodedJSValue regExpConstructorRightContext(ExecState* exec, EncodedJSValue thisValue, PropertyName)
 {
-    return JSValue::encode(jsCast<RegExpConstructor*>(JSValue::decode(thisValue))->getRightContext(exec));
+    VM& vm = exec->vm();
+    JSGlobalObject* globalObject = jsCast<RegExpConstructor*>(JSValue::decode(thisValue))->globalObject(vm);
+    return JSValue::encode(globalObject->regExpGlobalData().getRightContext(exec, globalObject));
 }
 
 bool setRegExpConstructorInput(ExecState* exec, EncodedJSValue thisValue, EncodedJSValue value)
 {
-    if (auto constructor = jsDynamicCast<RegExpConstructor*>(exec->vm(), JSValue::decode(thisValue))) {
-        constructor->setInput(exec, JSValue::decode(value).toString(exec));
+    VM& vm = exec->vm();
+    if (auto constructor = jsDynamicCast<RegExpConstructor*>(vm, JSValue::decode(thisValue))) {
+        JSGlobalObject* globalObject = constructor->globalObject(vm);
+        globalObject->regExpGlobalData().setInput(exec, globalObject, JSValue::decode(value).toString(exec));
         return true;
     }
     return false;
@@ -194,8 +160,10 @@
 
 bool setRegExpConstructorMultiline(ExecState* exec, EncodedJSValue thisValue, EncodedJSValue value)
 {
-    if (auto constructor = jsDynamicCast<RegExpConstructor*>(exec->vm(), JSValue::decode(thisValue))) {
-        constructor->setMultiline(JSValue::decode(value).toBoolean(exec));
+    VM& vm = exec->vm();
+    if (auto constructor = jsDynamicCast<RegExpConstructor*>(vm, JSValue::decode(thisValue))) {
+        JSGlobalObject* globalObject = constructor->globalObject(vm);
+        globalObject->regExpGlobalData().setMultiline(JSValue::decode(value).toBoolean(exec));
         return true;
     }
     return false;

Modified: trunk/Source/_javascript_Core/runtime/RegExpConstructor.h (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/RegExpConstructor.h	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/RegExpConstructor.h	2019-01-28 19:52:17 UTC (rev 240593)
@@ -35,15 +35,9 @@
     typedef InternalFunction Base;
     static const unsigned StructureFlags = Base::StructureFlags | HasStaticPropertyTable;
 
-    template<typename CellType>
-    static IsoSubspace* subspaceFor(VM& vm)
-    {
-        return &vm.regExpConstructorSpace;
-    }
-
     static RegExpConstructor* create(VM& vm, Structure* structure, RegExpPrototype* regExpPrototype, GetterSetter* species)
     {
-        RegExpConstructor* constructor = new (NotNull, allocateCell<RegExpConstructor>(vm.heap)) RegExpConstructor(vm, structure, regExpPrototype);
+        RegExpConstructor* constructor = new (NotNull, allocateCell<RegExpConstructor>(vm.heap)) RegExpConstructor(vm, structure);
         constructor->finishCreation(vm, regExpPrototype, species);
         return constructor;
     }
@@ -55,77 +49,17 @@
 
     DECLARE_INFO;
 
-    MatchResult performMatch(VM&, RegExp*, JSString*, const String&, int startOffset, int** ovector);
-    MatchResult performMatch(VM&, RegExp*, JSString*, const String&, int startOffset);
-    void recordMatch(VM&, RegExp*, JSString*, const MatchResult&);
-
-    void setMultiline(bool multiline) { m_multiline = multiline; }
-    bool multiline() const { return m_multiline; }
-
-    JSValue getBackref(ExecState*, unsigned);
-    JSValue getLastParen(ExecState*);
-    JSValue getLeftContext(ExecState*);
-    JSValue getRightContext(ExecState*);
-
-    void setInput(ExecState* exec, JSString* string) { m_cachedResult.setInput(exec, this, string); }
-    JSString* input() { return m_cachedResult.input(); }
-
-    static void visitChildren(JSCell*, SlotVisitor&);
-
-    static ptrdiff_t offsetOfCachedResult() { return OBJECT_OFFSETOF(RegExpConstructor, m_cachedResult); }
-
 protected:
     void finishCreation(VM&, RegExpPrototype*, GetterSetter* species);
 
 private:
-    RegExpConstructor(VM&, Structure*, RegExpPrototype*);
-    static void destroy(JSCell*);
-
-    RegExpCachedResult m_cachedResult;
-    bool m_multiline;
-    Vector<int> m_ovector;
+    RegExpConstructor(VM&, Structure*);
 };
 
+static_assert(sizeof(RegExpConstructor) == sizeof(InternalFunction), "");
+
 JSObject* constructRegExp(ExecState*, JSGlobalObject*, const ArgList&, JSObject* callee = nullptr, JSValue newTarget = jsUndefined());
 
-/* 
-   To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular
-   _expression_ matching through the performMatch function. We use cached results to calculate, 
-   e.g., RegExp.lastMatch and RegExp.leftParen.
-*/
-ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(VM& vm, RegExp* regExp, JSString* string, const String& input, int startOffset, int** ovector)
-{
-    int position = regExp->match(vm, input, startOffset, m_ovector);
-
-    if (ovector)
-        *ovector = m_ovector.data();
-
-    if (position == -1)
-        return MatchResult::failed();
-
-    ASSERT(!m_ovector.isEmpty());
-    ASSERT(m_ovector[0] == position);
-    ASSERT(m_ovector[1] >= position);
-    size_t end = m_ovector[1];
-
-    m_cachedResult.record(vm, this, regExp, string, MatchResult(position, end));
-
-    return MatchResult(position, end);
-}
-ALWAYS_INLINE MatchResult RegExpConstructor::performMatch(VM& vm, RegExp* regExp, JSString* string, const String& input, int startOffset)
-{
-    MatchResult result = regExp->match(vm, input, startOffset);
-    if (result)
-        m_cachedResult.record(vm, this, regExp, string, result);
-    return result;
-}
-
-ALWAYS_INLINE void RegExpConstructor::recordMatch(VM& vm, RegExp* regExp, JSString* string, const MatchResult& result)
-{
-    ASSERT(result);
-    m_cachedResult.record(vm, this, regExp, string, result);
-}
-
 ALWAYS_INLINE bool isRegExp(VM& vm, ExecState* exec, JSValue value)
 {
     auto scope = DECLARE_THROW_SCOPE(vm);

Added: trunk/Source/_javascript_Core/runtime/RegExpGlobalData.cpp (0 => 240593)


--- trunk/Source/_javascript_Core/runtime/RegExpGlobalData.cpp	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/RegExpGlobalData.cpp	2019-01-28 19:52:17 UTC (rev 240593)
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "RegExpGlobalData.h"
+
+namespace JSC {
+
+void RegExpGlobalData::visitAggregate(SlotVisitor& visitor)
+{
+    m_cachedResult.visitAggregate(visitor);
+}
+
+JSValue RegExpGlobalData::getBackref(ExecState* exec, JSGlobalObject* owner, unsigned i)
+{
+    JSArray* array = m_cachedResult.lastResult(exec, owner);
+
+    if (i < array->length()) {
+        JSValue result = JSValue(array).get(exec, i);
+        ASSERT(result.isString() || result.isUndefined());
+        if (!result.isUndefined())
+            return result;
+    }
+    return jsEmptyString(exec);
+}
+
+JSValue RegExpGlobalData::getLastParen(ExecState* exec, JSGlobalObject* owner)
+{
+    JSArray* array = m_cachedResult.lastResult(exec, owner);
+    unsigned length = array->length();
+    if (length > 1) {
+        JSValue result = JSValue(array).get(exec, length - 1);
+        ASSERT(result.isString() || result.isUndefined());
+        if (!result.isUndefined())
+            return result;
+    }
+    return jsEmptyString(exec);
+}
+
+JSValue RegExpGlobalData::getLeftContext(ExecState* exec, JSGlobalObject* owner)
+{
+    return m_cachedResult.leftContext(exec, owner);
+}
+
+JSValue RegExpGlobalData::getRightContext(ExecState* exec, JSGlobalObject* owner)
+{
+    return m_cachedResult.rightContext(exec, owner);
+}
+
+} // namespace JSC

Added: trunk/Source/_javascript_Core/runtime/RegExpGlobalData.h (0 => 240593)


--- trunk/Source/_javascript_Core/runtime/RegExpGlobalData.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/RegExpGlobalData.h	2019-01-28 19:52:17 UTC (rev 240593)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "RegExpCachedResult.h"
+
+namespace JSC {
+
+class JSGlobalObject;
+
+class RegExpGlobalData {
+public:
+    RegExpCachedResult& cachedResult() { return m_cachedResult; }
+
+    void setMultiline(bool multiline) { m_multiline = multiline; }
+    bool multiline() const { return m_multiline; }
+
+    void setInput(ExecState*, JSGlobalObject* owner, JSString*);
+    JSString* input() { return m_cachedResult.input(); }
+
+    void visitAggregate(SlotVisitor&);
+
+    JSValue getBackref(ExecState*, JSGlobalObject* owner, unsigned);
+    JSValue getLastParen(ExecState*, JSGlobalObject* owner);
+    JSValue getLeftContext(ExecState*, JSGlobalObject* owner);
+    JSValue getRightContext(ExecState*, JSGlobalObject* owner);
+
+    MatchResult performMatch(VM&, JSGlobalObject*, RegExp*, JSString*, const String&, int startOffset, int** ovector);
+    MatchResult performMatch(VM&, JSGlobalObject*, RegExp*, JSString*, const String&, int startOffset);
+    void recordMatch(VM&, JSGlobalObject*, RegExp*, JSString*, const MatchResult&);
+
+    static ptrdiff_t offsetOfCachedResult() { return OBJECT_OFFSETOF(RegExpGlobalData, m_cachedResult); }
+
+private:
+    RegExpCachedResult m_cachedResult;
+    bool m_multiline { false };
+    Vector<int> m_ovector;
+};
+
+}

Added: trunk/Source/_javascript_Core/runtime/RegExpGlobalDataInlines.h (0 => 240593)


--- trunk/Source/_javascript_Core/runtime/RegExpGlobalDataInlines.h	                        (rev 0)
+++ trunk/Source/_javascript_Core/runtime/RegExpGlobalDataInlines.h	2019-01-28 19:52:17 UTC (rev 240593)
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2019 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "RegExpGlobalData.h"
+
+namespace JSC {
+
+inline void RegExpGlobalData::setInput(ExecState* exec, JSGlobalObject* owner, JSString* string)
+{
+    m_cachedResult.setInput(exec, owner, string);
+}
+
+/*
+   To facilitate result caching, exec(), test(), match(), search(), and replace() dipatch regular
+   _expression_ matching through the performMatch function. We use cached results to calculate,
+   e.g., RegExp.lastMatch and RegExp.leftParen.
+*/
+ALWAYS_INLINE MatchResult RegExpGlobalData::performMatch(VM& vm, JSGlobalObject* owner, RegExp* regExp, JSString* string, const String& input, int startOffset, int** ovector)
+{
+    int position = regExp->match(vm, input, startOffset, m_ovector);
+
+    if (ovector)
+        *ovector = m_ovector.data();
+
+    if (position == -1)
+        return MatchResult::failed();
+
+    ASSERT(!m_ovector.isEmpty());
+    ASSERT(m_ovector[0] == position);
+    ASSERT(m_ovector[1] >= position);
+    size_t end = m_ovector[1];
+
+    m_cachedResult.record(vm, owner, regExp, string, MatchResult(position, end));
+
+    return MatchResult(position, end);
+}
+
+ALWAYS_INLINE MatchResult RegExpGlobalData::performMatch(VM& vm, JSGlobalObject* owner, RegExp* regExp, JSString* string, const String& input, int startOffset)
+{
+    MatchResult result = regExp->match(vm, input, startOffset);
+    if (result)
+        m_cachedResult.record(vm, owner, regExp, string, result);
+    return result;
+}
+
+ALWAYS_INLINE void RegExpGlobalData::recordMatch(VM& vm, JSGlobalObject* owner, RegExp* regExp, JSString* string, const MatchResult& result)
+{
+    ASSERT(result);
+    m_cachedResult.record(vm, owner, regExp, string, result);
+}
+
+}

Modified: trunk/Source/_javascript_Core/runtime/RegExpObject.cpp (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/RegExpObject.cpp	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/RegExpObject.cpp	2019-01-28 19:52:17 UTC (rev 240593)
@@ -28,7 +28,6 @@
 #include "JSString.h"
 #include "Lookup.h"
 #include "JSCInlines.h"
-#include "RegExpConstructor.h"
 #include "RegExpObjectInlines.h"
 
 namespace JSC {
@@ -189,13 +188,12 @@
 
     String s = string->value(exec);
     RETURN_IF_EXCEPTION(scope, { });
-    RegExpConstructor* regExpConstructor = globalObject->regExpConstructor();
 
     ASSERT(!s.isNull());
     if (regExp->unicode()) {
         unsigned stringLength = s.length();
         RELEASE_AND_RETURN(scope, collectMatches(
-            vm, exec, string, s, regExpConstructor, regExp,
+            vm, exec, string, s, globalObject, regExp,
             [&] (size_t end) -> size_t {
                 return advanceStringUnicode(s, stringLength, end);
             }));
@@ -202,7 +200,7 @@
     }
 
     RELEASE_AND_RETURN(scope, collectMatches(
-        vm, exec, string, s, regExpConstructor, regExp,
+        vm, exec, string, s, globalObject, regExp,
         [&] (size_t end) -> size_t {
             return end + 1;
         }));

Modified: trunk/Source/_javascript_Core/runtime/RegExpObjectInlines.h (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/RegExpObjectInlines.h	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/RegExpObjectInlines.h	2019-01-28 19:52:17 UTC (rev 240593)
@@ -27,7 +27,7 @@
 #include "JSGlobalObject.h"
 #include "JSString.h"
 #include "JSCInlines.h"
-#include "RegExpConstructor.h"
+#include "RegExpGlobalDataInlines.h"
 #include "RegExpMatchesArray.h"
 #include "RegExpObject.h"
 
@@ -66,7 +66,6 @@
     auto scope = DECLARE_THROW_SCOPE(vm);
 
     RegExp* regExp = this->regExp();
-    RegExpConstructor* regExpConstructor = globalObject->regExpConstructor();
     String input = string->value(exec);
     RETURN_IF_EXCEPTION(scope, { });
 
@@ -95,7 +94,7 @@
     if (globalOrSticky)
         setLastIndex(exec, result.end);
     RETURN_IF_EXCEPTION(scope, { });
-    regExpConstructor->recordMatch(vm, regExp, string, result);
+    globalObject->regExpGlobalData().recordMatch(vm, globalObject, regExp, string, result);
     return array;
 }
 
@@ -107,13 +106,12 @@
     auto scope = DECLARE_THROW_SCOPE(vm);
 
     RegExp* regExp = this->regExp();
-    RegExpConstructor* regExpConstructor = globalObject->regExpConstructor();
     String input = string->value(exec);
     RETURN_IF_EXCEPTION(scope, { });
 
     if (!regExp->global() && !regExp->sticky()) {
         scope.release();
-        return regExpConstructor->performMatch(vm, regExp, string, input, 0);
+        return globalObject->regExpGlobalData().performMatch(vm, globalObject, regExp, string, input, 0);
     }
 
     unsigned lastIndex = getRegExpObjectLastIndexAsUnsigned(exec, this, input);
@@ -121,7 +119,7 @@
     if (lastIndex == UINT_MAX)
         return MatchResult::failed();
     
-    MatchResult result = regExpConstructor->performMatch(vm, regExp, string, input, lastIndex);
+    MatchResult result = globalObject->regExpGlobalData().performMatch(vm, globalObject, regExp, string, input, lastIndex);
     RETURN_IF_EXCEPTION(scope, { });
     scope.release();
     setLastIndex(exec, result.end);
@@ -145,11 +143,11 @@
 }
 
 template<typename FixEndFunc>
-JSValue collectMatches(VM& vm, ExecState* exec, JSString* string, const String& s, RegExpConstructor* constructor, RegExp* regExp, const FixEndFunc& fixEnd)
+JSValue collectMatches(VM& vm, ExecState* exec, JSString* string, const String& s, JSGlobalObject* globalObject, RegExp* regExp, const FixEndFunc& fixEnd)
 {
     auto scope = DECLARE_THROW_SCOPE(vm);
 
-    MatchResult result = constructor->performMatch(vm, regExp, string, s, 0);
+    MatchResult result = globalObject->regExpGlobalData().performMatch(vm, globalObject, regExp, string, s, 0);
     RETURN_IF_EXCEPTION(scope, { });
     if (!result)
         return jsNull();
@@ -171,7 +169,7 @@
         }
         if (!length)
             end = fixEnd(end);
-        result = constructor->performMatch(vm, regExp, string, s, end);
+        result = globalObject->regExpGlobalData().performMatch(vm, globalObject, regExp, string, s, end);
         if (UNLIKELY(scope.exception())) {
             hasException = true;
             return;
@@ -194,12 +192,12 @@
                 if (result.empty())
                     end = fixEnd(end);
                 
-                // Using RegExpConstructor::performMatch() instead of calling RegExp::match()
+                // Using RegExpGlobalData::performMatch() instead of calling RegExp::match()
                 // directly is a surprising but profitable choice: it means that when we do OOM, we
                 // will leave the cached result in the state it ought to have had just before the
                 // OOM! On the other hand, if this loop concludes that the result is small enough,
                 // then the iterate() loop below will overwrite the cached result anyway.
-                result = constructor->performMatch(vm, regExp, string, s, end);
+                result = globalObject->regExpGlobalData().performMatch(vm, globalObject, regExp, string, s, end);
                 RETURN_IF_EXCEPTION(scope, { });
             } while (result);
             

Modified: trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/RegExpPrototype.cpp	2019-01-28 19:52:17 UTC (rev 240593)
@@ -35,7 +35,6 @@
 #include "ObjectPrototype.h"
 #include "RegExp.h"
 #include "RegExpCache.h"
-#include "RegExpConstructor.h"
 #include "RegExpObject.h"
 #include "RegExpObjectInlines.h"
 #include "StringObject.h"
@@ -83,19 +82,8 @@
     JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->searchSymbol, regExpPrototypeSearchCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));
     JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->splitSymbol, regExpPrototypeSplitCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));
     JSC_BUILTIN_FUNCTION_WITHOUT_TRANSITION(vm.propertyNames->test, regExpPrototypeTestCodeGenerator, static_cast<unsigned>(PropertyAttribute::DontEnum));
-
-    m_emptyRegExp.set(vm, this, RegExp::create(vm, "", NoFlags));
 }
 
-void RegExpPrototype::visitChildren(JSCell* cell, SlotVisitor& visitor)
-{
-    RegExpPrototype* thisObject = jsCast<RegExpPrototype*>(cell);
-    ASSERT_GC_OBJECT_INHERITS(thisObject, info());
-    Base::visitChildren(thisObject, visitor);
-    
-    visitor.append(thisObject->m_emptyRegExp);
-}
-
 // ------------------------------ Functions ---------------------------
 
 EncodedJSValue JSC_HOST_CALL regExpProtoFuncTestFast(ExecState* exec)
@@ -497,8 +485,8 @@
     String s = string->value(exec);
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
 
-    RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
-    MatchResult result = regExpConstructor->performMatch(vm, regExp, string, s, 0);
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
+    MatchResult result = globalObject->regExpGlobalData().performMatch(vm, globalObject, regExp, string, s, 0);
     RETURN_IF_EXCEPTION(scope, encodedJSValue());
     return JSValue::encode(result ? jsNumber(result.start) : jsNumber(-1));
 }

Modified: trunk/Source/_javascript_Core/runtime/RegExpPrototype.h (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/RegExpPrototype.h	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/RegExpPrototype.h	2019-01-28 19:52:17 UTC (rev 240593)
@@ -44,17 +44,11 @@
         return Structure::create(vm, globalObject, prototype, TypeInfo(ObjectType, StructureFlags), info());
     }
 
-    JS_EXPORT_PRIVATE static void visitChildren(JSCell*, SlotVisitor&);
-
-    RegExp* emptyRegExp() const { return m_emptyRegExp.get(); }
-
 protected:
     RegExpPrototype(VM&, Structure*);
 
 private:
     void finishCreation(VM&, JSGlobalObject*);
-
-    WriteBarrier<RegExp> m_emptyRegExp;
 };
 
 EncodedJSValue JSC_HOST_CALL regExpProtoFuncMatchFast(ExecState*);

Modified: trunk/Source/_javascript_Core/runtime/StringPrototype.cpp (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/StringPrototype.cpp	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/StringPrototype.cpp	2019-01-28 19:52:17 UTC (rev 240593)
@@ -43,7 +43,7 @@
 #include "PropertyNameArray.h"
 #include "RegExpCache.h"
 #include "RegExpConstructor.h"
-#include "RegExpObject.h"
+#include "RegExpGlobalDataInlines.h"
 #include "SuperSampler.h"
 #include <algorithm>
 #include <unicode/uconfig.h>
@@ -483,11 +483,11 @@
     unsigned startPosition = 0;
 
     Vector<StringRange, 16> sourceRanges;
-    RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
     unsigned sourceLen = source.length();
 
     while (true) {
-        MatchResult result = regExpConstructor->performMatch(vm, regExp, string, source, startPosition);
+        MatchResult result = globalObject->regExpGlobalData().performMatch(vm, globalObject, regExp, string, source, startPosition);
         RETURN_IF_EXCEPTION(scope, nullptr);
         if (!result)
             break;
@@ -542,7 +542,7 @@
 
     // FIXME: This is wrong because we may be called directly from the FTL.
     // https://bugs.webkit.org/show_bug.cgi?id=154874
-    RegExpConstructor* regExpConstructor = exec->lexicalGlobalObject()->regExpConstructor();
+    JSGlobalObject* globalObject = exec->lexicalGlobalObject();
 
     size_t lastIndex = 0;
     unsigned startPosition = 0;
@@ -561,7 +561,7 @@
         RETURN_IF_EXCEPTION(scope, nullptr);
         while (true) {
             int* ovector;
-            MatchResult result = regExpConstructor->performMatch(vm, regExp, string, source, startPosition, &ovector);
+            MatchResult result = globalObject->regExpGlobalData().performMatch(vm, globalObject, regExp, string, source, startPosition, &ovector);
             RETURN_IF_EXCEPTION(scope, nullptr);
             if (!result)
                 break;
@@ -627,7 +627,7 @@
     } else {
         do {
             int* ovector;
-            MatchResult result = regExpConstructor->performMatch(vm, regExp, string, source, startPosition, &ovector);
+            MatchResult result = globalObject->regExpGlobalData().performMatch(vm, globalObject, regExp, string, source, startPosition, &ovector);
             RETURN_IF_EXCEPTION(scope, nullptr);
             if (!result)
                 break;

Modified: trunk/Source/_javascript_Core/runtime/VM.cpp (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/VM.cpp	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/VM.cpp	2019-01-28 19:52:17 UTC (rev 240593)
@@ -124,7 +124,6 @@
 #include "PropertyMapHashTable.h"
 #include "ProxyRevoke.h"
 #include "RegExpCache.h"
-#include "RegExpConstructor.h"
 #include "RegExpObject.h"
 #include "RegisterAtOffsetList.h"
 #include "RuntimeType.h"
@@ -309,7 +308,6 @@
 #endif
     , propertyTableSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), PropertyTable)
     , proxyRevokeSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), ProxyRevoke)
-    , regExpConstructorSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), RegExpConstructor)
     , structureRareDataSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), StructureRareData)
     , structureSpace ISO_SUBSPACE_INIT(heap, destructibleCellHeapCellType.get(), Structure)
     , weakSetSpace ISO_SUBSPACE_INIT(heap, destructibleObjectHeapCellType.get(), JSWeakSet)
@@ -434,6 +432,7 @@
     sentinelSetBucket.set(*this, JSSet::BucketType::createSentinel(*this));
     sentinelMapBucket.set(*this, JSMap::BucketType::createSentinel(*this));
 
+    m_regExpCache->initialize(*this);
     smallStrings.initializeCommonStrings(*this);
 
     Thread::current().setCurrentAtomicStringTable(existingEntryAtomicStringTable);

Modified: trunk/Source/_javascript_Core/runtime/VM.h (240592 => 240593)


--- trunk/Source/_javascript_Core/runtime/VM.h	2019-01-28 19:19:20 UTC (rev 240592)
+++ trunk/Source/_javascript_Core/runtime/VM.h	2019-01-28 19:52:17 UTC (rev 240593)
@@ -129,6 +129,7 @@
 class LLIntOffsetsExtractor;
 class NativeExecutable;
 class PromiseDeferredTimer;
+class RegExp;
 class RegExpCache;
 class Register;
 class RegisterAtOffsetList;
@@ -384,7 +385,6 @@
 #endif
     IsoSubspace propertyTableSpace;
     IsoSubspace proxyRevokeSpace;
-    IsoSubspace regExpConstructorSpace;
     IsoSubspace structureRareDataSpace;
     IsoSubspace structureSpace;
     IsoSubspace weakSetSpace;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to