[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:
* JavaScriptCore.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:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@240593 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/JavaScriptCore/runtime/RegExpGlobalData.h b/Source/JavaScriptCore/runtime/RegExpGlobalData.h
new file mode 100644
index 0000000..bd76c36
--- /dev/null
+++ b/Source/JavaScriptCore/runtime/RegExpGlobalData.h
@@ -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;
+};
+
+}