Changeset 243408 in webkit
- Timestamp:
- Mar 23, 2019, 12:58:07 AM (7 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 4 edited
-
ChangeLog (modified) (1 diff)
-
runtime/RegExp.cpp (modified) (11 diffs)
-
runtime/RegExp.h (modified) (3 diffs)
-
runtime/RegExpInlines.h (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r243396 r243408 1 2019-03-23 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Shrink sizeof(RegExp) 4 https://bugs.webkit.org/show_bug.cgi?id=196133 5 6 Reviewed by Mark Lam. 7 8 Some applications have many RegExp cells. But RegExp cells are very large (144B). 9 This patch reduces the size from 144B to 48B by, 10 11 1. Allocate Yarr::YarrCodeBlock in non-GC heap. We can avoid this allocation if JIT is disabled. 12 2. m_captureGroupNames and m_namedGroupToParenIndex are moved to RareData. They are only used when RegExp has named capture groups. 13 14 * runtime/RegExp.cpp: 15 (JSC::RegExp::finishCreation): 16 (JSC::RegExp::estimatedSize): 17 (JSC::RegExp::compile): 18 (JSC::RegExp::matchConcurrently): 19 (JSC::RegExp::compileMatchOnly): 20 (JSC::RegExp::deleteCode): 21 (JSC::RegExp::printTraceData): 22 * runtime/RegExp.h: 23 * runtime/RegExpInlines.h: 24 (JSC::RegExp::hasCodeFor): 25 (JSC::RegExp::matchInline): 26 (JSC::RegExp::hasMatchOnlyCodeFor): 27 1 28 2019-03-22 Keith Rollin <krollin@apple.com> 2 29 -
trunk/Source/JavaScriptCore/runtime/RegExp.cpp
r242699 r243408 172 172 Base::finishCreation(vm); 173 173 Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm.stackLimit()); 174 if (!isValid()) 174 if (!isValid()) { 175 175 m_state = ParseError; 176 else { 177 m_numSubpatterns = pattern.m_numSubpatterns; 178 m_captureGroupNames.swap(pattern.m_captureGroupNames); 179 m_namedGroupToParenIndex.swap(pattern.m_namedGroupToParenIndex); 176 return; 177 } 178 179 m_numSubpatterns = pattern.m_numSubpatterns; 180 if (!pattern.m_captureGroupNames.isEmpty() || !pattern.m_namedGroupToParenIndex.isEmpty()) { 181 m_rareData = std::make_unique<RareData>(); 182 m_rareData->m_captureGroupNames.swap(pattern.m_captureGroupNames); 183 m_rareData->m_namedGroupToParenIndex.swap(pattern.m_namedGroupToParenIndex); 180 184 } 181 185 } … … 195 199 size_t regexDataSize = thisObject->m_regExpBytecode ? thisObject->m_regExpBytecode->estimatedSizeInBytes() : 0; 196 200 #if ENABLE(YARR_JIT) 197 regexDataSize += thisObject->m_regExpJITCode.size(); 201 if (auto* jitCode = thisObject->m_regExpJITCode.get()) 202 regexDataSize += jitCode->size(); 198 203 #endif 199 204 return Base::estimatedSize(cell, vm) + regexDataSize; … … 238 243 void RegExp::compile(VM* vm, Yarr::YarrCharSize charSize) 239 244 { 240 ConcurrentJSLocker locker(m_lock);245 auto locker = holdLock(cellLock()); 241 246 242 247 Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm->stackLimit()); … … 259 264 #endif 260 265 ) { 261 Yarr::jitCompile(pattern, m_patternString, charSize, vm, m_regExpJITCode); 262 if (!m_regExpJITCode.failureReason()) { 266 auto& jitCode = ensureRegExpJITCode(); 267 Yarr::jitCompile(pattern, m_patternString, charSize, vm, jitCode); 268 if (!jitCode.failureReason()) { 263 269 m_state = JITCode; 264 270 return; … … 284 290 VM& vm, const String& s, unsigned startOffset, int& position, Vector<int>& ovector) 285 291 { 286 ConcurrentJSLocker locker(m_lock);292 auto locker = holdLock(cellLock()); 287 293 288 294 if (!hasCodeFor(s.is8Bit() ? Yarr::Char8 : Yarr::Char16)) … … 295 301 void RegExp::compileMatchOnly(VM* vm, Yarr::YarrCharSize charSize) 296 302 { 297 ConcurrentJSLocker locker(m_lock);303 auto locker = holdLock(cellLock()); 298 304 299 305 Yarr::YarrPattern pattern(m_patternString, m_flags, m_constructionErrorCode, vm->stackLimit()); … … 316 322 #endif 317 323 ) { 318 Yarr::jitCompile(pattern, m_patternString, charSize, vm, m_regExpJITCode, Yarr::MatchOnly); 319 if (!m_regExpJITCode.failureReason()) { 324 auto& jitCode = ensureRegExpJITCode(); 325 Yarr::jitCompile(pattern, m_patternString, charSize, vm, jitCode, Yarr::MatchOnly); 326 if (!jitCode.failureReason()) { 320 327 m_state = JITCode; 321 328 return; … … 340 347 bool RegExp::matchConcurrently(VM& vm, const String& s, unsigned startOffset, MatchResult& result) 341 348 { 342 ConcurrentJSLocker locker(m_lock);349 auto locker = holdLock(cellLock()); 343 350 344 351 if (!hasMatchOnlyCodeFor(s.is8Bit() ? Yarr::Char8 : Yarr::Char16)) … … 351 358 void RegExp::deleteCode() 352 359 { 353 ConcurrentJSLocker locker(m_lock);360 auto locker = holdLock(cellLock()); 354 361 355 362 if (!hasCode()) … … 357 364 m_state = NotCompiled; 358 365 #if ENABLE(YARR_JIT) 359 m_regExpJITCode.clear(); 366 if (m_regExpJITCode) 367 m_regExpJITCode->clear(); 360 368 #endif 361 369 m_regExpBytecode = nullptr; … … 427 435 428 436 #if ENABLE(YARR_JIT) 429 Yarr::YarrCodeBlock& codeBlock = m_regExpJITCode;430 431 437 const size_t jitAddrSize = 20; 432 char jit8BitMatchOnlyAddr[jitAddrSize]; 433 char jit16BitMatchOnlyAddr[jitAddrSize]; 434 char jit8BitMatchAddr[jitAddrSize]; 435 char jit16BitMatchAddr[jitAddrSize]; 436 if (m_state == ByteCode) { 438 char jit8BitMatchOnlyAddr[jitAddrSize] { }; 439 char jit16BitMatchOnlyAddr[jitAddrSize] { }; 440 char jit8BitMatchAddr[jitAddrSize] { }; 441 char jit16BitMatchAddr[jitAddrSize] { }; 442 switch (m_state) { 443 case ParseError: 444 case NotCompiled: 445 break; 446 case ByteCode: 437 447 snprintf(jit8BitMatchOnlyAddr, jitAddrSize, "fallback "); 438 448 snprintf(jit16BitMatchOnlyAddr, jitAddrSize, "---- "); 439 449 snprintf(jit8BitMatchAddr, jitAddrSize, "fallback "); 440 450 snprintf(jit16BitMatchAddr, jitAddrSize, "---- "); 441 } else { 451 break; 452 case JITCode: { 453 Yarr::YarrCodeBlock& codeBlock = *m_regExpJITCode.get(); 442 454 snprintf(jit8BitMatchOnlyAddr, jitAddrSize, "0x%014lx", reinterpret_cast<uintptr_t>(codeBlock.get8BitMatchOnlyAddr())); 443 455 snprintf(jit16BitMatchOnlyAddr, jitAddrSize, "0x%014lx", reinterpret_cast<uintptr_t>(codeBlock.get16BitMatchOnlyAddr())); 444 456 snprintf(jit8BitMatchAddr, jitAddrSize, "0x%014lx", reinterpret_cast<uintptr_t>(codeBlock.get8BitMatchAddr())); 445 457 snprintf(jit16BitMatchAddr, jitAddrSize, "0x%014lx", reinterpret_cast<uintptr_t>(codeBlock.get16BitMatchAddr())); 458 break; 459 } 446 460 } 447 461 #else -
trunk/Source/JavaScriptCore/runtime/RegExp.h
r242955 r243408 89 89 bool hasNamedCaptures() 90 90 { 91 return !m_captureGroupNames.isEmpty();91 return m_rareData && !m_rareData->m_captureGroupNames.isEmpty(); 92 92 } 93 93 94 94 String getCaptureGroupName(unsigned i) 95 95 { 96 if (!i || m_captureGroupNames.size() <= i)96 if (!i || !m_rareData || m_rareData->m_captureGroupNames.size() <= i) 97 97 return String(); 98 return m_captureGroupNames[i]; 98 ASSERT(m_rareData); 99 return m_rareData->m_captureGroupNames[i]; 99 100 } 100 101 101 102 unsigned subpatternForName(String groupName) 102 103 { 103 auto it = m_namedGroupToParenIndex.find(groupName); 104 if (it == m_namedGroupToParenIndex.end()) 104 if (!m_rareData) 105 return 0; 106 auto it = m_rareData->m_namedGroupToParenIndex.find(groupName); 107 if (it == m_rareData->m_namedGroupToParenIndex.end()) 105 108 return 0; 106 109 return it->value; … … 158 161 #endif 159 162 163 #if ENABLE(YARR_JIT) 164 Yarr::YarrCodeBlock& ensureRegExpJITCode() 165 { 166 if (!m_regExpJITCode) 167 m_regExpJITCode = std::make_unique<Yarr::YarrCodeBlock>(); 168 return *m_regExpJITCode.get(); 169 } 170 #endif 171 172 struct RareData { 173 WTF_MAKE_STRUCT_FAST_ALLOCATED; 174 Vector<String> m_captureGroupNames; 175 HashMap<String, unsigned> m_namedGroupToParenIndex; 176 }; 177 160 178 String m_patternString; 161 179 RegExpState m_state { NotCompiled }; 162 180 OptionSet<Yarr::Flags> m_flags; 163 ConcurrentJSLock m_lock;164 181 Yarr::ErrorCode m_constructionErrorCode { Yarr::ErrorCode::NoError }; 165 182 unsigned m_numSubpatterns { 0 }; 166 Vector<String> m_captureGroupNames;167 HashMap<String, unsigned> m_namedGroupToParenIndex;168 183 std::unique_ptr<Yarr::BytecodePattern> m_regExpBytecode; 184 #if ENABLE(YARR_JIT) 185 std::unique_ptr<Yarr::YarrCodeBlock> m_regExpJITCode; 186 #endif 187 std::unique_ptr<RareData> m_rareData; 169 188 #if ENABLE(REGEXP_TRACING) 170 189 double m_rtMatchOnlyTotalSubjectStringLen { 0.0 }; … … 175 194 unsigned m_rtMatchFoundCount { 0 }; 176 195 #endif 177 178 #if ENABLE(YARR_JIT)179 Yarr::YarrCodeBlock m_regExpJITCode;180 #endif181 196 }; 182 197 -
trunk/Source/JavaScriptCore/runtime/RegExpInlines.h
r237763 r243408 74 74 if (m_state != JITCode) 75 75 return true; 76 if ((charSize == Yarr::Char8) && (m_regExpJITCode.has8BitCode())) 77 return true; 78 if ((charSize == Yarr::Char16) && (m_regExpJITCode.has16BitCode())) 76 ASSERT(m_regExpJITCode); 77 if ((charSize == Yarr::Char8) && (m_regExpJITCode->has8BitCode())) 78 return true; 79 if ((charSize == Yarr::Char16) && (m_regExpJITCode->has16BitCode())) 79 80 return true; 80 81 #else … … 157 158 if (m_state == JITCode) { 158 159 { 160 ASSERT(m_regExpJITCode); 159 161 #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS) 160 PatternContextBufferHolder patternContextBufferHolder(vm, m_regExpJITCode .usesPatternContextBuffer());162 PatternContextBufferHolder patternContextBufferHolder(vm, m_regExpJITCode->usesPatternContextBuffer()); 161 163 162 164 #define EXTRA_JIT_PARAMS , patternContextBufferHolder.buffer(), patternContextBufferHolder.size() … … 166 168 167 169 if (s.is8Bit()) 168 result = m_regExpJITCode .execute(s.characters8(), startOffset, s.length(), offsetVector EXTRA_JIT_PARAMS).start;170 result = m_regExpJITCode->execute(s.characters8(), startOffset, s.length(), offsetVector EXTRA_JIT_PARAMS).start; 169 171 else 170 result = m_regExpJITCode .execute(s.characters16(), startOffset, s.length(), offsetVector EXTRA_JIT_PARAMS).start;172 result = m_regExpJITCode->execute(s.characters16(), startOffset, s.length(), offsetVector EXTRA_JIT_PARAMS).start; 171 173 172 174 #undef EXTRA_JIT_PARAMS … … 231 233 if (m_state != JITCode) 232 234 return true; 233 if ((charSize == Yarr::Char8) && (m_regExpJITCode.has8BitCodeMatchOnly())) 234 return true; 235 if ((charSize == Yarr::Char16) && (m_regExpJITCode.has16BitCodeMatchOnly())) 235 ASSERT(m_regExpJITCode); 236 if ((charSize == Yarr::Char8) && (m_regExpJITCode->has8BitCodeMatchOnly())) 237 return true; 238 if ((charSize == Yarr::Char16) && (m_regExpJITCode->has16BitCodeMatchOnly())) 236 239 return true; 237 240 #else … … 278 281 if (m_state == JITCode) { 279 282 { 283 ASSERT(m_regExpJITCode); 280 284 #if ENABLE(YARR_JIT_ALL_PARENS_EXPRESSIONS) 281 PatternContextBufferHolder patternContextBufferHolder(vm, m_regExpJITCode .usesPatternContextBuffer());285 PatternContextBufferHolder patternContextBufferHolder(vm, m_regExpJITCode->usesPatternContextBuffer()); 282 286 283 287 #define EXTRA_JIT_PARAMS , patternContextBufferHolder.buffer(), patternContextBufferHolder.size() … … 287 291 288 292 if (s.is8Bit()) 289 result = m_regExpJITCode .execute(s.characters8(), startOffset, s.length() EXTRA_JIT_PARAMS);293 result = m_regExpJITCode->execute(s.characters8(), startOffset, s.length() EXTRA_JIT_PARAMS); 290 294 else 291 result = m_regExpJITCode .execute(s.characters16(), startOffset, s.length() EXTRA_JIT_PARAMS);295 result = m_regExpJITCode->execute(s.characters16(), startOffset, s.length() EXTRA_JIT_PARAMS); 292 296 293 297 #undef EXTRA_JIT_PARAMS
Note:
See TracChangeset
for help on using the changeset viewer.