[JSC] Check TypeInfo first before calling getCallData when we would like to check...
authorutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 May 2018 07:05:27 +0000 (07:05 +0000)
committerutatane.tea@gmail.com <utatane.tea@gmail.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 16 May 2018 07:05:27 +0000 (07:05 +0000)
commit207d844900dc77d6824be25bd22c9cfcad93a8ee
tree3fcff25af12f30803e4fc5b3caa6c71b47cd7d00
parent67cddb863176545e199d8d34dc30ec8e301e2b0e
[JSC] Check TypeInfo first before calling getCallData when we would like to check whether given object is a function
https://bugs.webkit.org/show_bug.cgi?id=185601

Reviewed by Saam Barati.

Source/JavaScriptCore:

Rename TypeOfShouldCallGetCallData to OverridesGetCallData. And check OverridesGetCallData
before calling getCallData when we would like to check whether a given object is callable
since getCallData is a virtual call. When we call the object anyway, directly calling getCallData
is fine. But if we would like to check whether the object is callable, we can have non
callable objects frequently. In that case, we should not call getCallData if we can avoid it.

To do this cleanly, we refactor JSValue::{isFunction,isCallable}. We add JSCell::{isFunction,isCallable}
and JSValue ones call into these functions. Inside JSCell::{isFunction,isCallable}, we perform
OverridesGetCallData checking before calling getCallData.

We found that this virtual call exists in JSON.stringify's critial path. Checking
OverridesGetCallData improves Kraken/json-stringify-tinderbox by 2-4%.

                                       baseline                  patched

    json-stringify-tinderbox        38.807+-0.350      ^      37.216+-0.337         ^ definitely 1.0427x faster

In addition to that, we also add OverridesGetCallData flag to JSFunction while we keep JSFunctionType checking fast path
since major cases are covered by this fast JSFunctionType checking.

* API/JSCallbackObject.h:
* dfg/DFGAbstractInterpreterInlines.h:
(JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects):
* dfg/DFGOperations.cpp:
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::compileIsObjectOrNull):
(JSC::DFG::SpeculativeJIT::compileIsFunction):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::isExoticForTypeof):
* jit/AssemblyHelpers.h:
(JSC::AssemblyHelpers::emitTypeOf):
* runtime/ExceptionHelpers.cpp:
(JSC::createError):
(JSC::createInvalidFunctionApplyParameterError):
* runtime/FunctionPrototype.cpp:
(JSC::functionProtoFuncToString):
* runtime/InternalFunction.h:
* runtime/JSCJSValue.h:
* runtime/JSCJSValueInlines.h:
(JSC::JSValue::isFunction const):
(JSC::JSValue::isCallable const):
* runtime/JSCell.h:
* runtime/JSCellInlines.h:
(JSC::JSCell::isFunction):
ALWAYS_INLINE works well for my environment.
(JSC::JSCell::isCallable):
* runtime/JSFunction.h:
* runtime/JSONObject.cpp:
(JSC::Stringifier::toJSON):
(JSC::Stringifier::toJSONImpl):
(JSC::Stringifier::appendStringifiedValue):
* runtime/JSObjectInlines.h:
(JSC::createListFromArrayLike):
* runtime/JSTypeInfo.h:
(JSC::TypeInfo::overridesGetCallData const):
(JSC::TypeInfo::typeOfShouldCallGetCallData const): Deleted.
* runtime/Operations.cpp:
(JSC::jsTypeStringForValue):
(JSC::jsIsObjectTypeOrNull):
* runtime/ProxyObject.h:
* runtime/RuntimeType.cpp:
(JSC::runtimeTypeForValue):
* runtime/RuntimeType.h:
* runtime/Structure.cpp:
(JSC::Structure::Structure):
* runtime/TypeProfilerLog.cpp:
(JSC::TypeProfilerLog::TypeProfilerLog):
(JSC::TypeProfilerLog::processLogEntries):
* runtime/TypeProfilerLog.h:
* runtime/VM.cpp:
(JSC::VM::enableTypeProfiler):
* tools/JSDollarVM.cpp:
(JSC::functionFindTypeForExpression):
(JSC::functionReturnTypeFor):
(JSC::functionHasBasicBlockExecuted):
(JSC::functionBasicBlockExecutionCount):
* wasm/js/JSWebAssemblyHelpers.h:
(JSC::getWasmBufferFromValue):
* wasm/js/JSWebAssemblyInstance.cpp:
(JSC::JSWebAssemblyInstance::create):
* wasm/js/WebAssemblyFunction.cpp:
(JSC::callWebAssemblyFunction):
* wasm/js/WebAssemblyInstanceConstructor.cpp:
(JSC::constructJSWebAssemblyInstance):
* wasm/js/WebAssemblyModuleRecord.cpp:
(JSC::WebAssemblyModuleRecord::link):
* wasm/js/WebAssemblyPrototype.cpp:
(JSC::webAssemblyInstantiateFunc):
(JSC::webAssemblyInstantiateStreamingInternal):
* wasm/js/WebAssemblyWrapperFunction.cpp:
(JSC::WebAssemblyWrapperFunction::finishCreation):

Source/WebCore:

No behavior change.

* Modules/plugins/QuickTimePluginReplacement.mm:
(WebCore::QuickTimePluginReplacement::ensureReplacementScriptInjected):
* bindings/js/JSCustomElementRegistryCustom.cpp:
(WebCore::getCustomElementCallback):
* bindings/js/JSDOMConstructorBase.h:
* bindings/js/JSDOMConvertCallbacks.h:
(WebCore::Converter<IDLCallbackFunction<T>>::convert):
* bindings/js/JSDOMPromise.cpp:
(WebCore::DOMPromise::whenSettled):
* bindings/js/ReadableStream.cpp:
(WebCore::ReadableStream::pipeTo):
(WebCore::ReadableStream::tee):
* bindings/js/ReadableStreamDefaultController.cpp:
(WebCore::ReadableStreamDefaultController::invoke):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateHeader):
(GenerateOverloadDispatcher):
* bindings/scripts/test/JS/JSTestObj.h:
* bindings/scripts/test/JS/JSTestPluginInterface.h:
* bridge/objc/objc_runtime.h:
* bridge/runtime_method.h:
* bridge/runtime_object.h:
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::ensureMediaControlsInjectedScript):
* testing/Internals.cpp:
(WebCore::Internals::parserMetaData):
(WebCore::Internals::cloneArrayBuffer):

Source/WebKit:

* WebProcess/Plugins/Netscape/JSNPObject.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@231839 268f45cc-cd09-0410-ab3c-d52691b4dbfc
52 files changed:
Source/JavaScriptCore/API/JSCallbackObject.h
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h
Source/JavaScriptCore/dfg/DFGOperations.cpp
Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
Source/JavaScriptCore/jit/AssemblyHelpers.h
Source/JavaScriptCore/runtime/ExceptionHelpers.cpp
Source/JavaScriptCore/runtime/FunctionPrototype.cpp
Source/JavaScriptCore/runtime/InternalFunction.h
Source/JavaScriptCore/runtime/JSCJSValue.h
Source/JavaScriptCore/runtime/JSCJSValueInlines.h
Source/JavaScriptCore/runtime/JSCell.h
Source/JavaScriptCore/runtime/JSCellInlines.h
Source/JavaScriptCore/runtime/JSFunction.h
Source/JavaScriptCore/runtime/JSONObject.cpp
Source/JavaScriptCore/runtime/JSObjectInlines.h
Source/JavaScriptCore/runtime/JSTypeInfo.h
Source/JavaScriptCore/runtime/Operations.cpp
Source/JavaScriptCore/runtime/ProxyObject.h
Source/JavaScriptCore/runtime/RuntimeType.cpp
Source/JavaScriptCore/runtime/RuntimeType.h
Source/JavaScriptCore/runtime/Structure.cpp
Source/JavaScriptCore/runtime/TypeProfilerLog.cpp
Source/JavaScriptCore/runtime/TypeProfilerLog.h
Source/JavaScriptCore/runtime/VM.cpp
Source/JavaScriptCore/tools/JSDollarVM.cpp
Source/JavaScriptCore/wasm/js/JSWebAssemblyHelpers.h
Source/JavaScriptCore/wasm/js/JSWebAssemblyInstance.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyFunction.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyInstanceConstructor.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyModuleRecord.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyPrototype.cpp
Source/JavaScriptCore/wasm/js/WebAssemblyWrapperFunction.cpp
Source/WebCore/ChangeLog
Source/WebCore/Modules/plugins/QuickTimePluginReplacement.mm
Source/WebCore/bindings/js/JSCustomElementRegistryCustom.cpp
Source/WebCore/bindings/js/JSDOMConstructorBase.h
Source/WebCore/bindings/js/JSDOMConvertCallbacks.h
Source/WebCore/bindings/js/JSDOMPromise.cpp
Source/WebCore/bindings/js/ReadableStream.cpp
Source/WebCore/bindings/js/ReadableStreamDefaultController.cpp
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/test/JS/JSTestObj.h
Source/WebCore/bindings/scripts/test/JS/JSTestPluginInterface.h
Source/WebCore/bridge/objc/objc_runtime.h
Source/WebCore/bridge/runtime_method.h
Source/WebCore/bridge/runtime_object.h
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/testing/Internals.cpp
Source/WebKit/ChangeLog
Source/WebKit/WebProcess/Plugins/Netscape/JSNPObject.h