[webkit-changes] [WebKit/WebKit] ac6109: [JSC] Optimize Number constructor calls further

Yusuke Suzuki noreply at github.com
Sun Jan 29 00:22:02 PST 2023


  Branch: refs/heads/main
  Home:   https://github.com/WebKit/WebKit
  Commit: ac61096b73818052b6035da906ac29f54a80ec93
      https://github.com/WebKit/WebKit/commit/ac61096b73818052b6035da906ac29f54a80ec93
  Author: Yusuke Suzuki <ysuzuki at apple.com>
  Date:   2023-01-29 (Sun, 29 Jan 2023)

  Changed paths:
    A JSTests/microbenchmarks/number-on-string.js
    M Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
    M Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp
    M Source/JavaScriptCore/dfg/DFGClobberize.h
    M Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp
    M Source/JavaScriptCore/dfg/DFGFixupPhase.cpp
    M Source/JavaScriptCore/dfg/DFGOperations.cpp
    M Source/JavaScriptCore/dfg/DFGOperations.h
    M Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp
    M Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp
    M Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
    M Source/JavaScriptCore/jit/JSInterfaceJIT.h
    M Source/JavaScriptCore/jit/SpecializedThunkJIT.h
    M Source/JavaScriptCore/jit/ThunkGenerators.cpp
    M Source/JavaScriptCore/jit/ThunkGenerators.h
    M Source/JavaScriptCore/runtime/Intrinsic.h
    M Source/JavaScriptCore/runtime/JSCJSValueInlines.h
    M Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp
    M Source/JavaScriptCore/runtime/NumberConstructor.cpp
    M Source/JavaScriptCore/runtime/NumberConstructor.h
    M Source/JavaScriptCore/runtime/VM.cpp

  Log Message:
  -----------
  [JSC] Optimize Number constructor calls further
https://bugs.webkit.org/show_bug.cgi?id=251309
rdar://104773086

Reviewed by Mark Lam.

It turned out that Number constructor call is super heavily used for two purposes,

1. To make String -> Number
2. To ensure the given input is Number. It is very frequently already a number.
3. To make BigInt -> Number

And this constructor is called even from LLInt etc. frequently.

We were using InternalFunction for NumberConstructor. On the other hand, JSFunction is
the fastest form for calls. The tradeoff is that, InternalFunction does not generate
a new JIT code, and it is great for a function which takes enough amount of time in C++
side, in this case, allocations! That's why we typically use InternalFunction for builtin
constructors. However, Number constructor can be used for just a call to convert an input
to a number, and in this case, C++ time is sufficiently small, and we care the performance
of calls itself. So, in this patch,

1. We change NumberConstructor from InternalFunction-based to JSFunction-based. Old days,
   probably, this is not supported. But to make JSPromiseConstructor work well, we already
   made it work. So let's do it, and make NumberConstructor call super fast.
2. We add NumberConstructorIntrinsic and add a thunk which returns quickly if an input is
   a number. This sufficiently covers a lot of cases in the wild.
3. We handle NumberConstructor calls onto String efficiently, and add DFG / FTL optimizations
   for that pattern.

Number constructor calls for String gets 20% faster on Baseline-only case (because of
InternalFunction -> JSFunction change). And we got 2x faster performance on FTL.

    DFG disabled.
                                 ToT                     Patched

    number-on-string       19.1253+-0.1344     ^     15.6378+-0.1594        ^ definitely 1.2230x faster

    DFG and FTL enabled.
                                 ToT                     Patched

    number-on-string        9.1768+-0.0289     ^      4.6237+-0.0249        ^ definitely 1.9847x faster

* JSTests/microbenchmarks/number-on-string.js: Added.
(shouldBe):
(test):
* Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* Source/JavaScriptCore/dfg/DFGByteCodeParser.cpp:
(JSC::DFG::ByteCodeParser::handleCallVariant):
(JSC::DFG::ByteCodeParser::handleIntrinsicCall):
(JSC::DFG::ByteCodeParser::handleTypedArrayConstructor):
(JSC::DFG::ByteCodeParser::handleConstantFunction):
(JSC::DFG::ByteCodeParser::handleConstantInternalFunction): Deleted.
* Source/JavaScriptCore/dfg/DFGClobberize.h:
(JSC::DFG::clobberize):
* Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:
(JSC::DFG::ConstantFoldingPhase::foldConstants):
* Source/JavaScriptCore/dfg/DFGFixupPhase.cpp:
(JSC::DFG::FixupPhase::fixupToNumberOrToNumericOrCallNumberConstructor):
* Source/JavaScriptCore/dfg/DFGOperations.cpp:
(JSC::DFG::JSC_DEFINE_JIT_OPERATION):
* Source/JavaScriptCore/dfg/DFGOperations.h:
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT32_64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/dfg/DFGSpeculativeJIT64.cpp:
(JSC::DFG::SpeculativeJIT::compile):
* Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::compileToNumber):
* Source/JavaScriptCore/jit/JSInterfaceJIT.h:
(JSC::JSInterfaceJIT::emitLoadJSValue):
* Source/JavaScriptCore/jit/SpecializedThunkJIT.h:
(JSC::SpecializedThunkJIT::loadJSArgument):
(JSC::SpecializedThunkJIT::returnJSValue):
* Source/JavaScriptCore/jit/ThunkGenerators.cpp:
(JSC::numberConstructorCallThunkGenerator):
* Source/JavaScriptCore/jit/ThunkGenerators.h:
* Source/JavaScriptCore/runtime/Intrinsic.h:
* Source/JavaScriptCore/runtime/JSCJSValueInlines.h:
(JSC::JSValue::toNumeric const):
* Source/JavaScriptCore/runtime/JSGlobalObjectFunctions.cpp:
(JSC::jsToNumber):
* Source/JavaScriptCore/runtime/NumberConstructor.cpp:
(JSC::NumberConstructor::NumberConstructor):
(JSC::NumberConstructor::create):
(JSC::NumberConstructor::finishCreation):
* Source/JavaScriptCore/runtime/NumberConstructor.h:
* Source/JavaScriptCore/runtime/VM.cpp:
(JSC::thunkGeneratorForIntrinsic):

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




More information about the webkit-changes mailing list