Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: 5ca1f041c34a41f09ce222106852ee411a67e77a
      
https://github.com/WebKit/WebKit/commit/5ca1f041c34a41f09ce222106852ee411a67e77a
  Author: Sosuke Suzuki <[email protected]>
  Date:   2026-10-13 (Tue, 13 Oct 2026)

  Changed paths:
    A JSTests/microbenchmarks/json-stringify-substring.js
    A JSTests/microbenchmarks/string-replace-regexp-substring-no-match.js
    A JSTests/stress/json-stringify-substring-rope.js
    A JSTests/stress/string-replace-regexp-substring-rope.js
    M Source/JavaScriptCore/dfg/DFGOperations.cpp
    M Source/JavaScriptCore/runtime/JSONObject.cpp
    M Source/JavaScriptCore/runtime/JSString.h
    M Source/JavaScriptCore/runtime/StringPrototype.cpp
    M Source/JavaScriptCore/runtime/StringPrototypeInlines.h

  Log Message:
  -----------
  [JSC] RegExp `String#replace` and `JSON.stringify` should not resolve 
substring ropes
https://bugs.webkit.org/show_bug.cgi?id=327129

Reviewed by Yusuke Suzuki.

`String#replace` with a RegExp and the fast path of `JSON.stringify` resolved a
substring rope before reading it. That allocates a StringImpl which is thrown
away when nothing matches, or once the characters are copied.

This patch reads the characters through a StringView, as `RegExp#exec` and
`RegExp#test` already do. The replace helpers take a StringView and resolve the
string only where the result shares the buffer of the subject. `JSON.stringify`
uses the new JSString::tryGetView, which is view() without throwing on OOM.

StringView::operator[] does not return 0 past the end as String's does, so the
empty-match step checks the index before reading the next code unit.

                                                Baseline                  
Patched

    json-stringify-substring                  155.3919+-2.0925     ^    
115.0069+-2.9840        ^ definitely 1.3512x faster
    string-replace-regexp-substring-no-match   57.7822+-0.4284     ^     
37.3056+-0.8526        ^ definitely 1.5489x faster

Tests: JSTests/microbenchmarks/json-stringify-substring.js
       JSTests/microbenchmarks/string-replace-regexp-substring-no-match.js
       JSTests/stress/json-stringify-substring-rope.js
       JSTests/stress/string-replace-regexp-substring-rope.js

* JSTests/microbenchmarks/json-stringify-substring.js: Added.
(test):
(string_appeared_here.repeat):
* JSTests/microbenchmarks/string-replace-regexp-substring-no-match.js: Added.
(test):
(const.re.const.replacer):
* JSTests/stress/json-stringify-substring-rope.js: Added.
(shouldBe):
(check):
(stringify):
(let.expected.bases.map):
* JSTests/stress/string-replace-regexp-substring-rope.js: Added.
(shouldBe):
(replace):
(check):
(let.escape):
(removeGlobal):
(removeFirst):
(removeAll):
(replaceWithString):
(replaceWithFunction):
* Source/JavaScriptCore/dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/runtime/JSONObject.cpp:
(JSC::bufferMode>::append):
* Source/JavaScriptCore/runtime/JSString.h:
(JSC::JSString::tryGetView const):
* Source/JavaScriptCore/runtime/StringPrototype.cpp:
(JSC::replaceUsingRegExpSearch):
* Source/JavaScriptCore/runtime/StringPrototypeInlines.h:
(JSC::jsSpliceSubstringsWithSeparators):
(JSC::jsSpliceSubstringsWithSeparator):
(JSC::jsSpliceSubstrings):
(JSC::removeAllUsingRegExpSearch):
(JSC::tryTrimSpaces):
(JSC::replaceAllWithStringUsingRegExpSearchNoBackreferences):
(JSC::replaceAllWithStringUsingRegExpSearch):
(JSC::replaceOneWithStringUsingRegExpSearch):

Canonical link: https://commits.webkit.org/323545@main



To unsubscribe from these emails, change your notification settings at 
https://github.com/WebKit/WebKit/settings/notifications

Reply via email to