Changeset 259747 in webkit
- Timestamp:
- Apr 8, 2020, 1:01:39 PM (6 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 11 edited
-
ChangeLog (modified) (1 diff)
-
runtime/RegExp.cpp (modified) (4 diffs)
-
runtime/RegExp.h (modified) (2 diffs)
-
runtime/RegExpGlobalData.h (modified) (1 diff)
-
runtime/RegExpGlobalDataInlines.h (modified) (2 diffs)
-
runtime/RegExpInlines.h (modified) (5 diffs)
-
runtime/RegExpMatchesArray.h (modified) (1 diff)
-
runtime/RegExpObjectInlines.h (modified) (5 diffs)
-
runtime/RegExpPrototype.cpp (modified) (10 diffs)
-
runtime/StringPrototype.cpp (modified) (3 diffs)
-
testRegExp.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/ChangeLog
r259744 r259747 1 2020-04-08 Yusuke Suzuki <ysuzuki@apple.com> 2 3 [JSC] Threading JSGlobalObject in RegExp::match properly 4 https://bugs.webkit.org/show_bug.cgi?id=210174 5 6 Reviewed by Saam Barati. 7 8 We thread JSGlobalObject* properly in RegExp::match instead of accessing VM::topCallFrame, which is too hacky. 9 10 * runtime/RegExp.cpp: 11 (JSC::RegExp::match): 12 (JSC::RegExp::matchConcurrently): 13 * runtime/RegExp.h: 14 * runtime/RegExpGlobalData.h: 15 * runtime/RegExpGlobalDataInlines.h: 16 (JSC::RegExpGlobalData::performMatch): 17 * runtime/RegExpInlines.h: 18 (JSC::RegExp::matchInline): 19 * runtime/RegExpMatchesArray.h: 20 (JSC::createRegExpMatchesArray): 21 * runtime/RegExpObjectInlines.h: 22 (JSC::RegExpObject::matchInline): 23 (JSC::collectMatches): 24 * runtime/RegExpPrototype.cpp: 25 (JSC::regExpProtoFuncSearchFast): 26 (JSC::genericSplit): 27 (JSC::regExpProtoFuncSplitFast): 28 * runtime/StringPrototype.cpp: 29 (JSC::removeUsingRegExpSearch): 30 (JSC::replaceUsingRegExpSearch): 31 * testRegExp.cpp: 32 (testOneRegExp): 33 (runFromFiles): 34 1 35 2020-04-08 Devin Rousso <drousso@apple.com> 2 36 -
trunk/Source/JavaScriptCore/runtime/RegExp.cpp
r259092 r259747 287 287 } 288 288 289 int RegExp::match( VM& vm, const String& s, unsigned startOffset, Vector<int>& ovector)290 { 291 return matchInline( vm, s, startOffset, ovector);289 int RegExp::match(JSGlobalObject* globalObject, const String& s, unsigned startOffset, Vector<int>& ovector) 290 { 291 return matchInline(globalObject, globalObject->vm(), s, startOffset, ovector); 292 292 } 293 293 … … 300 300 return false; 301 301 302 position = matchInline<Vector<int>&, Yarr::MatchFrom::CompilerThread>( vm, s, startOffset, ovector);302 position = matchInline<Vector<int>&, Yarr::MatchFrom::CompilerThread>(nullptr, vm, s, startOffset, ovector); 303 303 if (m_state == ParseError) 304 304 return false; … … 351 351 } 352 352 353 MatchResult RegExp::match( VM& vm, const String& s, unsigned startOffset)354 { 355 return matchInline( vm, s, startOffset);353 MatchResult RegExp::match(JSGlobalObject* globalObject, const String& s, unsigned startOffset) 354 { 355 return matchInline(globalObject, globalObject->vm(), s, startOffset); 356 356 } 357 357 … … 363 363 return false; 364 364 365 result = matchInline<Yarr::MatchFrom::CompilerThread>( vm, s, startOffset);365 result = matchInline<Yarr::MatchFrom::CompilerThread>(nullptr, vm, s, startOffset); 366 366 return true; 367 367 } -
trunk/Source/JavaScriptCore/runtime/RegExp.h
r259092 r259747 77 77 } 78 78 79 JS_EXPORT_PRIVATE int match( VM&, const String&, unsigned startOffset, Vector<int>& ovector);79 JS_EXPORT_PRIVATE int match(JSGlobalObject*, const String&, unsigned startOffset, Vector<int>& ovector); 80 80 81 81 // Returns false if we couldn't run the regular expression for any reason. 82 82 bool matchConcurrently(VM&, const String&, unsigned startOffset, int& position, Vector<int>& ovector); 83 83 84 JS_EXPORT_PRIVATE MatchResult match( VM&, const String&, unsigned startOffset);84 JS_EXPORT_PRIVATE MatchResult match(JSGlobalObject*, const String&, unsigned startOffset); 85 85 86 86 bool matchConcurrently(VM&, const String&, unsigned startOffset, MatchResult&); … … 88 88 // Call these versions of the match functions if you're desperate for performance. 89 89 template<typename VectorType, Yarr::MatchFrom thread = Yarr::MatchFrom::VMThread> 90 int matchInline( VM&, const String&, unsigned startOffset, VectorType& ovector);90 int matchInline(JSGlobalObject* nullOrGlobalObject, VM&, const String&, unsigned startOffset, VectorType& ovector); 91 91 template<Yarr::MatchFrom thread = Yarr::MatchFrom::VMThread> 92 MatchResult matchInline( VM&, const String&, unsigned startOffset);92 MatchResult matchInline(JSGlobalObject* nullOrGlobalObject, VM&, const String&, unsigned startOffset); 93 93 94 94 unsigned numSubpatterns() const { return m_numSubpatterns; } -
trunk/Source/JavaScriptCore/runtime/RegExpGlobalData.h
r251425 r259747 49 49 JSValue getRightContext(JSGlobalObject*); 50 50 51 MatchResult performMatch( VM&,JSGlobalObject*, RegExp*, JSString*, const String&, int startOffset, int** ovector);52 MatchResult performMatch( VM&,JSGlobalObject*, RegExp*, JSString*, const String&, int startOffset);51 MatchResult performMatch(JSGlobalObject*, RegExp*, JSString*, const String&, int startOffset, int** ovector); 52 MatchResult performMatch(JSGlobalObject*, RegExp*, JSString*, const String&, int startOffset); 53 53 void recordMatch(VM&, JSGlobalObject*, RegExp*, JSString*, const MatchResult&); 54 54 -
trunk/Source/JavaScriptCore/runtime/RegExpGlobalDataInlines.h
r251425 r259747 40 40 e.g., RegExp.lastMatch and RegExp.leftParen. 41 41 */ 42 ALWAYS_INLINE MatchResult RegExpGlobalData::performMatch( VM& vm,JSGlobalObject* owner, RegExp* regExp, JSString* string, const String& input, int startOffset, int** ovector)42 ALWAYS_INLINE MatchResult RegExpGlobalData::performMatch(JSGlobalObject* owner, RegExp* regExp, JSString* string, const String& input, int startOffset, int** ovector) 43 43 { 44 int position = regExp->match(vm, input, startOffset, m_ovector); 44 ASSERT(owner); 45 VM& vm = owner->vm(); 46 auto scope = DECLARE_THROW_SCOPE(vm); 47 int position = regExp->match(owner, input, startOffset, m_ovector); 48 RETURN_IF_EXCEPTION(scope, MatchResult::failed()); 45 49 46 50 if (ovector) … … 60 64 } 61 65 62 ALWAYS_INLINE MatchResult RegExpGlobalData::performMatch( VM& vm,JSGlobalObject* owner, RegExp* regExp, JSString* string, const String& input, int startOffset)66 ALWAYS_INLINE MatchResult RegExpGlobalData::performMatch(JSGlobalObject* owner, RegExp* regExp, JSString* string, const String& input, int startOffset) 63 67 { 64 MatchResult result = regExp->match(vm, input, startOffset); 68 ASSERT(owner); 69 VM& vm = owner->vm(); 70 auto scope = DECLARE_THROW_SCOPE(vm); 71 MatchResult result = regExp->match(owner, input, startOffset); 72 RETURN_IF_EXCEPTION(scope, MatchResult::failed()); 65 73 if (result) 66 74 m_cachedResult.record(vm, owner, regExp, string, result); -
trunk/Source/JavaScriptCore/runtime/RegExpInlines.h
r259092 r259747 99 99 100 100 template<typename VectorType, Yarr::MatchFrom matchFrom> 101 ALWAYS_INLINE int RegExp::matchInline( VM& vm, const String& s, unsigned startOffset, VectorType& ovector)101 ALWAYS_INLINE int RegExp::matchInline(JSGlobalObject* nullOrGlobalObject, VM& vm, const String& s, unsigned startOffset, VectorType& ovector) 102 102 { 103 103 #if ENABLE(REGEXP_TRACING) … … 109 109 110 110 auto throwError = [&] { 111 auto throwScope = DECLARE_THROW_SCOPE(vm); 112 // FIXME: Revisit JSGlobalObject. 113 // https://bugs.webkit.org/show_bug.cgi?id=203204 114 JSGlobalObject* globalObject = vm.topCallFrame->lexicalGlobalObject(vm); 115 throwScope.throwException(globalObject, errorToThrow(globalObject)); 111 if (matchFrom == Yarr::MatchFrom::CompilerThread) 112 return -1; 113 if (nullOrGlobalObject) { 114 auto throwScope = DECLARE_THROW_SCOPE(vm); 115 throwScope.throwException(nullOrGlobalObject, errorToThrow(nullOrGlobalObject)); 116 } 116 117 if (!hasHardError(m_constructionErrorCode)) 117 118 reset(); … … 142 143 // JIT'ed code couldn't handle expression, so punt back to the interpreter. 143 144 byteCodeCompileIfNecessary(&vm); 144 if (m_state == ParseError) { 145 if (matchFrom == Yarr::MatchFrom::CompilerThread) 146 return -1; 145 if (m_state == ParseError) 147 146 return throwError(); 148 }149 147 result = Yarr::interpret(m_regExpBytecode.get(), s, startOffset, reinterpret_cast<unsigned*>(offsetVector)); 150 148 } … … 233 231 234 232 template<Yarr::MatchFrom matchFrom> 235 ALWAYS_INLINE MatchResult RegExp::matchInline( VM& vm, const String& s, unsigned startOffset)233 ALWAYS_INLINE MatchResult RegExp::matchInline(JSGlobalObject* nullOrGlobalObject, VM& vm, const String& s, unsigned startOffset) 236 234 { 237 235 #if ENABLE(REGEXP_TRACING) … … 243 241 244 242 auto throwError = [&] { 245 auto throwScope = DECLARE_THROW_SCOPE(vm); 246 // FIXME: Revisit JSGlobalObject. 247 // https://bugs.webkit.org/show_bug.cgi?id=203204 248 JSGlobalObject* globalObject = vm.topCallFrame->lexicalGlobalObject(vm); 249 throwScope.throwException(globalObject, errorToThrow(globalObject)); 243 if (matchFrom == Yarr::MatchFrom::CompilerThread) 244 return MatchResult::failed(); 245 if (nullOrGlobalObject) { 246 auto throwScope = DECLARE_THROW_SCOPE(vm); 247 throwScope.throwException(nullOrGlobalObject, errorToThrow(nullOrGlobalObject)); 248 } 250 249 if (!hasHardError(m_constructionErrorCode)) 251 250 reset(); -
trunk/Source/JavaScriptCore/runtime/RegExpMatchesArray.h
r252374 r259747 68 68 69 69 Vector<int, 32> subpatternResults; 70 int position = regExp->matchInline( vm, inputValue, startOffset, subpatternResults);70 int position = regExp->matchInline(globalObject, vm, inputValue, startOffset, subpatternResults); 71 71 if (position == -1) { 72 72 result = MatchResult::failed(); -
trunk/Source/JavaScriptCore/runtime/RegExpObjectInlines.h
r259246 r259747 107 107 if (!regExp->global() && !regExp->sticky()) { 108 108 scope.release(); 109 return globalObject->regExpGlobalData().performMatch( vm,globalObject, regExp, string, input, 0);109 return globalObject->regExpGlobalData().performMatch(globalObject, regExp, string, input, 0); 110 110 } 111 111 … … 118 118 } 119 119 120 MatchResult result = globalObject->regExpGlobalData().performMatch( vm,globalObject, regExp, string, input, lastIndex);120 MatchResult result = globalObject->regExpGlobalData().performMatch(globalObject, regExp, string, input, lastIndex); 121 121 RETURN_IF_EXCEPTION(scope, { }); 122 122 scope.release(); … … 146 146 auto scope = DECLARE_THROW_SCOPE(vm); 147 147 148 MatchResult result = globalObject->regExpGlobalData().performMatch( vm,globalObject, regExp, string, s, 0);148 MatchResult result = globalObject->regExpGlobalData().performMatch(globalObject, regExp, string, s, 0); 149 149 RETURN_IF_EXCEPTION(scope, { }); 150 150 if (!result) … … 168 168 if (!length) 169 169 end = fixEnd(end); 170 result = globalObject->regExpGlobalData().performMatch( vm,globalObject, regExp, string, s, end);170 result = globalObject->regExpGlobalData().performMatch(globalObject, regExp, string, s, end); 171 171 if (UNLIKELY(scope.exception())) { 172 172 hasException = true; … … 196 196 // OOM! On the other hand, if this loop concludes that the result is small enough, 197 197 // then the iterate() loop below will overwrite the cached result anyway. 198 result = globalObject->regExpGlobalData().performMatch( vm,globalObject, regExp, string, s, end);198 result = globalObject->regExpGlobalData().performMatch(globalObject, regExp, string, s, end); 199 199 RETURN_IF_EXCEPTION(scope, { }); 200 200 } while (result); -
trunk/Source/JavaScriptCore/runtime/RegExpPrototype.cpp
r259547 r259747 487 487 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 488 488 489 MatchResult result = globalObject->regExpGlobalData().performMatch( vm,globalObject, regExp, string, s, 0);489 MatchResult result = globalObject->regExpGlobalData().performMatch(globalObject, regExp, string, s, 0); 490 490 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 491 491 return JSValue::encode(result ? jsNumber(result.start) : jsNumber(-1)); … … 506 506 template<typename ControlFunc, typename PushFunc> 507 507 void genericSplit( 508 VM& vm, RegExp* regexp, const String& input, unsigned inputSize, unsigned& position,508 JSGlobalObject* globalObject, RegExp* regexp, const String& input, unsigned inputSize, unsigned& position, 509 509 unsigned& matchPosition, bool regExpIsSticky, bool regExpIsUnicode, 510 510 const ControlFunc& control, const PushFunc& push) 511 511 { 512 VM& vm = globalObject->vm(); 513 auto scope = DECLARE_THROW_SCOPE(vm); 512 514 Vector<int> ovector; 513 515 514 516 while (matchPosition < inputSize) { 515 if (control() == AbortSplit) 516 return; 517 { 518 auto result = control(); 519 RETURN_IF_EXCEPTION(scope, void()); 520 if (result == AbortSplit) 521 return; 522 } 517 523 518 524 ovector.shrink(0); … … 520 526 // a. Perform ? Set(splitter, "lastIndex", q, true). 521 527 // b. Let z be ? RegExpExec(splitter, S). 522 int mpos = regexp->match(vm, input, matchPosition, ovector); 528 int mpos = regexp->match(globalObject, input, matchPosition, ovector); 529 RETURN_IF_EXCEPTION(scope, void()); 523 530 524 531 // c. If z is null, let q be AdvanceStringIndex(S, q, unicodeMatching). … … 556 563 // 1. Let T be a String value equal to the substring of S consisting of the elements at indices p (inclusive) through q (exclusive). 557 564 // 2. Perform ! CreateDataProperty(A, ! ToString(lengthA), T). 558 if (push(true, position, matchPosition - position) == AbortSplit) 559 return; 565 { 566 auto result = push(true, position, matchPosition - position); 567 RETURN_IF_EXCEPTION(scope, void()); 568 if (result == AbortSplit) 569 return; 570 } 560 571 561 572 // 5. Let p be e. … … 570 581 // b. Perform ! CreateDataProperty(A, ! ToString(lengthA), nextCapture). 571 582 int sub = ovector[i * 2]; 572 if (push(sub >= 0, sub, ovector[i * 2 + 1] - sub) == AbortSplit) 583 auto result = push(sub >= 0, sub, ovector[i * 2 + 1] - sub); 584 RETURN_IF_EXCEPTION(scope, void()); 585 if (result == AbortSplit) 573 586 return; 574 587 } … … 631 644 // c. Perform ! CreateDataProperty(A, "0", S). 632 645 // d. Return A. 633 if (!regexp->match(vm, input, 0)) { 646 auto matchResult = regexp->match(globalObject, input, 0); 647 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 648 if (!matchResult) { 634 649 result->putDirectIndex(globalObject, 0, inputString); 635 650 RETURN_IF_EXCEPTION(scope, encodedJSValue()); … … 647 662 648 663 genericSplit( 649 vm, regexp, input, inputSize, position, matchPosition, regExpIsSticky, regExpIsUnicode,664 globalObject, regexp, input, inputSize, position, matchPosition, regExpIsSticky, regExpIsUnicode, 650 665 [&] () -> SplitControl { 651 666 if (resultLength >= maxSizeForDirectPath) … … 679 694 unsigned dryRunCount = 0; 680 695 genericSplit( 681 vm, regexp, input, inputSize, position, matchPosition, regExpIsSticky, regExpIsUnicode,696 globalObject, regexp, input, inputSize, position, matchPosition, regExpIsSticky, regExpIsUnicode, 682 697 [&] () -> SplitControl { 683 698 if (resultLength + dryRunCount > MAX_STORAGE_VECTOR_LENGTH) … … 691 706 return ContinueSplit; 692 707 }); 708 RETURN_IF_EXCEPTION(scope, encodedJSValue()); 693 709 694 710 if (resultLength + dryRunCount > MAX_STORAGE_VECTOR_LENGTH) { … … 702 718 703 719 genericSplit( 704 vm, regexp, input, inputSize, position, matchPosition, regExpIsSticky, regExpIsUnicode,720 globalObject, regexp, input, inputSize, position, matchPosition, regExpIsSticky, regExpIsUnicode, 705 721 [&] () -> SplitControl { 706 722 return ContinueSplit; -
trunk/Source/JavaScriptCore/runtime/StringPrototype.cpp
r259547 r259747 490 490 491 491 while (true) { 492 MatchResult result = globalObject->regExpGlobalData().performMatch( vm,globalObject, regExp, string, source, startPosition);492 MatchResult result = globalObject->regExpGlobalData().performMatch(globalObject, regExp, string, source, startPosition); 493 493 RETURN_IF_EXCEPTION(scope, nullptr); 494 494 if (!result) … … 561 561 while (true) { 562 562 int* ovector; 563 MatchResult result = globalObject->regExpGlobalData().performMatch( vm,globalObject, regExp, string, source, startPosition, &ovector);563 MatchResult result = globalObject->regExpGlobalData().performMatch(globalObject, regExp, string, source, startPosition, &ovector); 564 564 RETURN_IF_EXCEPTION(scope, nullptr); 565 565 if (!result) … … 621 621 do { 622 622 int* ovector; 623 MatchResult result = globalObject->regExpGlobalData().performMatch( vm,globalObject, regExp, string, source, startPosition, &ovector);623 MatchResult result = globalObject->regExpGlobalData().performMatch(globalObject, regExp, string, source, startPosition, &ovector); 624 624 RETURN_IF_EXCEPTION(scope, nullptr); 625 625 if (!result) -
trunk/Source/JavaScriptCore/testRegExp.cpp
r253443 r259747 189 189 } 190 190 191 static bool testOneRegExp( VM& vm, RegExp* regexp, RegExpTest* regExpTest, bool verbose, unsigned intlineNumber)191 static bool testOneRegExp(JSGlobalObject* globalObject, RegExp* regexp, RegExpTest* regExpTest, bool verbose, unsigned lineNumber) 192 192 { 193 193 bool result = true; 194 194 Vector<int> outVector; 195 195 outVector.resize(regExpTest->expectVector.size()); 196 int matchResult = regexp->match( vm, regExpTest->subject, regExpTest->offset, outVector);196 int matchResult = regexp->match(globalObject, regExpTest->subject, regExpTest->offset, outVector); 197 197 198 198 if (matchResult != regExpTest->result) { … … 466 466 if (regexp && regExpTest) { 467 467 ++tests; 468 if (!testOneRegExp( vm, regexp, regExpTest, verbose, lineNumber)) {468 if (!testOneRegExp(globalObject, regexp, regExpTest, verbose, lineNumber)) { 469 469 failures++; 470 470 printf("Failure on line %u\n", lineNumber);
Note:
See TracChangeset
for help on using the changeset viewer.