WebKit Bugzilla
Attachment 362199 Details for
Bug 194735
: [JSC] Lazily create empty RegExp
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-194735-20190215191440.patch (text/plain), 7.12 KB, created by
Yusuke Suzuki
on 2019-02-15 19:14:41 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Yusuke Suzuki
Created:
2019-02-15 19:14:41 PST
Size:
7.12 KB
patch
obsolete
>Subversion Revision: 241638 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 8049f0c376bf46d80c48aaca4760499ac0aafde8..b3e119ad2fc52d82866763cc607eb9c553149af9 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,28 @@ >+2019-02-15 Yusuke Suzuki <ysuzuki@apple.com> >+ >+ [JSC] Lazily create empty RegExp >+ https://bugs.webkit.org/show_bug.cgi?id=194735 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Some scripts do not have any RegExp. In that case, allocating MarkedBlock for RegExp is costly. >+ Previously, there was always one RegExp, "empty RegExp". This patch lazily creates it and drop >+ one MarkedBlock. >+ >+ * runtime/JSGlobalObject.cpp: >+ (JSC::JSGlobalObject::init): >+ * runtime/RegExpCache.cpp: >+ (JSC::RegExpCache::ensureEmptyRegExpSlow): >+ (JSC::RegExpCache::initialize): Deleted. >+ * runtime/RegExpCache.h: >+ (JSC::RegExpCache::ensureEmptyRegExp): >+ (JSC::RegExpCache::emptyRegExp const): Deleted. >+ * runtime/RegExpCachedResult.cpp: >+ (JSC::RegExpCachedResult::lastResult): >+ * runtime/RegExpCachedResult.h: >+ * runtime/VM.cpp: >+ (JSC::VM::VM): >+ > 2019-02-15 Yusuke Suzuki <ysuzuki@apple.com> > > [JSC] Make builtin objects more lazily initialized under non-JIT mode >diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >index c23c19257f4b297c78bdb2ebd0c558e5991c9453..d0c7ccdbfe3fa9ffb5ff9dd0082ba95bc3001958 100644 >--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >@@ -688,7 +688,7 @@ void JSGlobalObject::init(VM& vm) > m_arrayConstructor.set(vm, this, arrayConstructor); > > 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)); >+ m_regExpGlobalData.cachedResult().record(vm, this, nullptr, 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)); >diff --git a/Source/JavaScriptCore/runtime/RegExpCache.cpp b/Source/JavaScriptCore/runtime/RegExpCache.cpp >index 2cb29c4023edb8940ca3666cd02aae9636e2f326..d76bb396297d46716949b39313b0f2acce9e48d1 100644 >--- a/Source/JavaScriptCore/runtime/RegExpCache.cpp >+++ b/Source/JavaScriptCore/runtime/RegExpCache.cpp >@@ -56,9 +56,11 @@ RegExpCache::RegExpCache(VM* vm) > { > } > >-void RegExpCache::initialize(VM& vm) >+RegExp* RegExpCache::ensureEmptyRegExpSlow(VM& vm) > { >- m_emptyRegExp.set(vm, RegExp::create(vm, "", NoFlags)); >+ RegExp* regExp = RegExp::create(vm, "", NoFlags); >+ m_emptyRegExp.set(vm, regExp); >+ return regExp; > } > > void RegExpCache::finalize(Handle<Unknown> handle, void*) >diff --git a/Source/JavaScriptCore/runtime/RegExpCache.h b/Source/JavaScriptCore/runtime/RegExpCache.h >index 2f5bdc3c55186fb3f17e6c7822e4bc305983eae2..d5c540bf8b5b50c41bacf2a80b424d3e6cc7d420 100644 >--- a/Source/JavaScriptCore/runtime/RegExpCache.h >+++ b/Source/JavaScriptCore/runtime/RegExpCache.h >@@ -46,9 +46,12 @@ class RegExpCache : private WeakHandleOwner { > RegExpCache(VM* vm); > void deleteAllCode(); > >- void initialize(VM&); >- >- RegExp* emptyRegExp() const { return m_emptyRegExp.get(); } >+ RegExp* ensureEmptyRegExp(VM& vm) >+ { >+ if (m_emptyRegExp) >+ return m_emptyRegExp.get(); >+ return ensureEmptyRegExpSlow(vm); >+ } > > private: > >@@ -58,6 +61,8 @@ class RegExpCache : private WeakHandleOwner { > > void finalize(Handle<Unknown>, void* context) override; > >+ RegExp* ensureEmptyRegExpSlow(VM&); >+ > RegExp* lookupOrCreate(const WTF::String& patternString, RegExpFlags); > void addToStrongCache(RegExp*); > RegExpCacheMap m_weakCache; // Holds all regular expressions currently live. >diff --git a/Source/JavaScriptCore/runtime/RegExpCachedResult.cpp b/Source/JavaScriptCore/runtime/RegExpCachedResult.cpp >index c6a6b032dfa228ba583007387d676d79e8093bb1..9e100d2403c54da611b30a88c1b897356ce997aa 100644 >--- a/Source/JavaScriptCore/runtime/RegExpCachedResult.cpp >+++ b/Source/JavaScriptCore/runtime/RegExpCachedResult.cpp >@@ -45,8 +45,11 @@ void RegExpCachedResult::visitAggregate(SlotVisitor& visitor) > > JSArray* RegExpCachedResult::lastResult(ExecState* exec, JSObject* owner) > { >+ VM& vm = exec->vm(); > if (!m_reified) { >- m_reifiedInput.set(exec->vm(), owner, m_lastInput.get()); >+ m_reifiedInput.set(vm, owner, m_lastInput.get()); >+ if (!m_lastRegExp) >+ m_lastRegExp.set(vm, owner, vm.regExpCache()->ensureEmptyRegExp(vm)); > if (m_result) > m_reifiedResult.setWithoutWriteBarrier(createRegExpMatchesArray(exec, exec->lexicalGlobalObject(), m_lastInput.get(), m_lastRegExp.get(), m_result.start)); > else >@@ -54,7 +57,7 @@ JSArray* RegExpCachedResult::lastResult(ExecState* exec, JSObject* owner) > m_reifiedLeftContext.clear(); > m_reifiedRightContext.clear(); > m_reified = true; >- exec->vm().heap.writeBarrier(owner); >+ vm.heap.writeBarrier(owner); > } > return m_reifiedResult.get(); > } >diff --git a/Source/JavaScriptCore/runtime/RegExpCachedResult.h b/Source/JavaScriptCore/runtime/RegExpCachedResult.h >index 88a6c663e713dac9d933d8d088a66efc011cc2d2..a5b039185ffa059212ea451b62da9325a6bc1ad3 100644 >--- a/Source/JavaScriptCore/runtime/RegExpCachedResult.h >+++ b/Source/JavaScriptCore/runtime/RegExpCachedResult.h >@@ -65,6 +65,8 @@ class RegExpCachedResult { > > void visitAggregate(SlotVisitor&); > >+ // m_lastRegExp would be nullptr when RegExpCachedResult is not reified. >+ // If we find m_lastRegExp is nullptr, it means this should hold the empty RegExp. > static ptrdiff_t offsetOfLastRegExp() { return OBJECT_OFFSETOF(RegExpCachedResult, m_lastRegExp); } > static ptrdiff_t offsetOfLastInput() { return OBJECT_OFFSETOF(RegExpCachedResult, m_lastInput); } > static ptrdiff_t offsetOfResult() { return OBJECT_OFFSETOF(RegExpCachedResult, m_result); } >diff --git a/Source/JavaScriptCore/runtime/VM.cpp b/Source/JavaScriptCore/runtime/VM.cpp >index 79022d62181168273e0e688b9b19a645b4baec69..0952ffefdf7cf6a19b4d5516b2e1f431f8b2915c 100644 >--- a/Source/JavaScriptCore/runtime/VM.cpp >+++ b/Source/JavaScriptCore/runtime/VM.cpp >@@ -401,7 +401,6 @@ VM::VM(VMType vmType, HeapType heapType) > 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);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
keith_miller
:
review+
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 194735
: 362199