haikuwebkit/LayoutTests/js/dom/domjit-function-licm-expect...

9 lines
171 B
Plaintext
Raw Permalink Normal View History

[DOMJIT] Add DOMJIT::Signature https://bugs.webkit.org/show_bug.cgi?id=162980 Reviewed by Saam Barati and Sam Weinig. Source/JavaScriptCore: This patch introduces a new mechanism called DOMJIT::Signature. We can annotate the function with DOMJIT::Signature. DOMJIT::Signature has type information of that function. And it also maintains the effect of the function and the pointer to the unsafe function. The unsafe function means the function without type and argument count checks. By using these information, we can separate type and argument count checks from the function. And we can emit these things as DFG checks and convert the function call itself to CallDOM node. CallDOM node can call the unsafe function directly without any checks. Furthermore, this CallDOM node can represent its own clobberizing rules based on DOMJIT::Effect maintained by DOMJIT::Signature. It allows us to make opaque Call node to a CallDOM node that merely reads some part of heap. These changes (1) can drop duplicate type checks in DFG, (2) offer ability to move CallDOM node to somewhere, and (3) track more detailed heap reads and writes of CallDOM nodes. We first emit Call node with DOMJIT::Signature in DFGByteCodeParser. And in the fixup phase, we attempt to lower Call node to CallDOM node with checks & edge filters. This is because we do not know the type predictions in DFGByteCodeParser phase. If we always emit CallDOM node in DFGByteCodeParser, if we evaluate `div.getAttribute(true)` thingy, the Uncountable OSR exits repeatedly happen because AI figures out the abstract value is cleared. Currently, DOMJIT signature only allows the types that can reside in GPR. This is because the types of the unsafe function arguments are represented as the sequence of void*. In the future, we will extend to accept other types like float, double etc. We annotate several functions in Element. In particular, we annotate Element::getAttribute. This allows us to perform LICM in Dromaeo dom-attr test. In the Dromaeo dom-attr getAttribute test, we can see 32x improvement. (134974.8 v.s. 4203.4) * JavaScriptCore.xcodeproj/project.pbxproj: * bytecode/CallVariant.h: (JSC::CallVariant::functionExecutable): (JSC::CallVariant::nativeExecutable): (JSC::CallVariant::signatureFor): * bytecode/SpeculatedType.h: (JSC::isNotStringSpeculation): (JSC::isNotInt32Speculation): (JSC::isNotBooleanSpeculation): * dfg/DFGAbstractInterpreterInlines.h: (JSC::DFG::AbstractInterpreter<AbstractStateType>::executeEffects): * dfg/DFGByteCodeParser.cpp: (JSC::DFG::ByteCodeParser::addCall): (JSC::DFG::ByteCodeParser::handleCall): (JSC::DFG::ByteCodeParser::attemptToInlineCall): (JSC::DFG::ByteCodeParser::handleInlining): (JSC::DFG::ByteCodeParser::handleDOMJITCall): (JSC::DFG::ByteCodeParser::parseBlock): * dfg/DFGClobberize.h: (JSC::DFG::clobberize): * dfg/DFGDoesGC.cpp: (JSC::DFG::doesGC): * dfg/DFGFixupPhase.cpp: (JSC::DFG::FixupPhase::fixupNode): (JSC::DFG::FixupPhase::attemptToMakeCallDOM): (JSC::DFG::FixupPhase::fixupCheckDOM): (JSC::DFG::FixupPhase::fixupCallDOM): * dfg/DFGNode.cpp: (JSC::DFG::Node::convertToCallDOM): * dfg/DFGNode.h: (JSC::DFG::Node::hasHeapPrediction): (JSC::DFG::Node::shouldSpeculateNotInt32): (JSC::DFG::Node::shouldSpeculateNotBoolean): (JSC::DFG::Node::shouldSpeculateNotString): (JSC::DFG::Node::hasSignature): (JSC::DFG::Node::signature): * dfg/DFGNodeType.h: * dfg/DFGPredictionPropagationPhase.cpp: * dfg/DFGSafeToExecute.h: (JSC::DFG::safeToExecute): * dfg/DFGSpeculativeJIT.cpp: (JSC::DFG::SpeculativeJIT::compileCallDOM): * dfg/DFGSpeculativeJIT.h: (JSC::DFG::SpeculativeJIT::callOperation): * dfg/DFGSpeculativeJIT32_64.cpp: (JSC::DFG::SpeculativeJIT::compile): * dfg/DFGSpeculativeJIT64.cpp: (JSC::DFG::SpeculativeJIT::compile): * domjit/DOMJITEffect.h: (JSC::DOMJIT::Effect::Effect): (JSC::DOMJIT::Effect::forWrite): (JSC::DOMJIT::Effect::forRead): (JSC::DOMJIT::Effect::forReadWrite): (JSC::DOMJIT::Effect::forPure): (JSC::DOMJIT::Effect::forDef): (JSC::DOMJIT::Effect::mustGenerate): In clang, we cannot make this Effect constructor constexpr if we use Optional<HeapRange>. So we use HeapRange::top() for Nullopt def now. * domjit/DOMJITHeapRange.h: (JSC::DOMJIT::HeapRange::fromRaw): (JSC::DOMJIT::HeapRange::operator bool): (JSC::DOMJIT::HeapRange::operator==): (JSC::DOMJIT::HeapRange::operator!=): (JSC::DOMJIT::HeapRange::fromConstant): * domjit/DOMJITSignature.h: Copied from Source/JavaScriptCore/domjit/DOMJITEffect.h. (JSC::DOMJIT::Signature::Signature): (JSC::DOMJIT::Signature::argumentCount): (JSC::DOMJIT::Signature::checkDOM): * ftl/FTLCapabilities.cpp: (JSC::FTL::canCompile): * ftl/FTLLowerDFGToB3.cpp: (JSC::FTL::DFG::LowerDFGToB3::compileNode): (JSC::FTL::DFG::LowerDFGToB3::compileCallDOM): * jit/JITOperations.h: * jit/JITThunks.cpp: (JSC::JITThunks::hostFunctionStub): * jit/JITThunks.h: * runtime/JSBoundFunction.cpp: (JSC::JSBoundFunction::create): * runtime/JSCell.h: * runtime/JSFunction.cpp: (JSC::JSFunction::create): * runtime/JSFunction.h: * runtime/JSNativeStdFunction.cpp: (JSC::JSNativeStdFunction::create): * runtime/JSObject.cpp: (JSC::JSObject::putDirectNativeFunction): * runtime/JSObject.h: * runtime/Lookup.h: (JSC::HashTableValue::functionLength): (JSC::HashTableValue::signature): (JSC::reifyStaticProperty): * runtime/NativeExecutable.cpp: (JSC::NativeExecutable::create): (JSC::NativeExecutable::NativeExecutable): * runtime/NativeExecutable.h: * runtime/PropertySlot.h: * runtime/VM.cpp: (JSC::VM::getHostFunction): * runtime/VM.h: Source/WebCore: We introduce DOMJIT::Signature. This signature object is automatically generated by IDL code generator. It holds (1) types, (2) pointer to the unsafe function (the function without checks), and (3) the effect of the function. We use constexpr to initialize DOMJIT::Signature without invoking global constructors. Thus the content is embedded into the binary as the constant values. We also clean up the IDL code generator related to DOMJIT part. Instead of switching things inside IDL code generator, we use C++ template to dispatch things at compile time. This template meta programming is highly utilized in IDL these days. To make DOMJIT::Signature constexpr, we also need to define DOMJIT abstract heap things in the build time. To do so, we introduce a tiny Ruby script to calculate the range of abstract heaps. We can offer the abstract heap tree as YAML format and the script will produce a C++ header holding the calculated abstract heap ranges * CMakeLists.txt: * DerivedSources.make: * ForwardingHeaders/bytecode/SpeculatedType.h: Renamed from Source/WebCore/domjit/DOMJITAbstractHeapRepository.h. * ForwardingHeaders/domjit/DOMJITSignature.h: Renamed from Source/WebCore/domjit/DOMJITAbstractHeapRepository.cpp. * WebCore.xcodeproj/project.pbxproj: * bindings/js/JSDOMGlobalObject.h: * bindings/scripts/CodeGeneratorJS.pm: (GenerateHeader): (GeneratePropertiesHashTable): (GetUnsafeArgumentType): (GetArgumentTypeFilter): (GetResultTypeFilter): (GenerateImplementation): (UnsafeToNative): (GenerateHashTableValueArray): (ComputeFunctionSpecial): * bindings/scripts/IDLAttributes.txt: * bindings/scripts/test/JS/JSTestDOMJIT.cpp: (WebCore::BindingCaller<JSTestDOMJIT>::castForOperation): (WebCore::TestDOMJITAnyAttrDOMJIT::TestDOMJITAnyAttrDOMJIT): (WebCore::TestDOMJITBooleanAttrDOMJIT::TestDOMJITBooleanAttrDOMJIT): (WebCore::TestDOMJITByteAttrDOMJIT::TestDOMJITByteAttrDOMJIT): (WebCore::TestDOMJITOctetAttrDOMJIT::TestDOMJITOctetAttrDOMJIT): (WebCore::TestDOMJITShortAttrDOMJIT::TestDOMJITShortAttrDOMJIT): (WebCore::TestDOMJITUnsignedShortAttrDOMJIT::TestDOMJITUnsignedShortAttrDOMJIT): (WebCore::TestDOMJITLongAttrDOMJIT::TestDOMJITLongAttrDOMJIT): (WebCore::TestDOMJITUnsignedLongAttrDOMJIT::TestDOMJITUnsignedLongAttrDOMJIT): (WebCore::TestDOMJITLongLongAttrDOMJIT::TestDOMJITLongLongAttrDOMJIT): (WebCore::TestDOMJITUnsignedLongLongAttrDOMJIT::TestDOMJITUnsignedLongLongAttrDOMJIT): (WebCore::TestDOMJITFloatAttrDOMJIT::TestDOMJITFloatAttrDOMJIT): (WebCore::TestDOMJITUnrestrictedFloatAttrDOMJIT::TestDOMJITUnrestrictedFloatAttrDOMJIT): (WebCore::TestDOMJITDoubleAttrDOMJIT::TestDOMJITDoubleAttrDOMJIT): (WebCore::TestDOMJITUnrestrictedDoubleAttrDOMJIT::TestDOMJITUnrestrictedDoubleAttrDOMJIT): (WebCore::TestDOMJITDomStringAttrDOMJIT::TestDOMJITDomStringAttrDOMJIT): (WebCore::TestDOMJITByteStringAttrDOMJIT::TestDOMJITByteStringAttrDOMJIT): (WebCore::TestDOMJITUsvStringAttrDOMJIT::TestDOMJITUsvStringAttrDOMJIT): (WebCore::TestDOMJITNodeAttrDOMJIT::TestDOMJITNodeAttrDOMJIT): (WebCore::TestDOMJITBooleanNullableAttrDOMJIT::TestDOMJITBooleanNullableAttrDOMJIT): (WebCore::TestDOMJITByteNullableAttrDOMJIT::TestDOMJITByteNullableAttrDOMJIT): (WebCore::TestDOMJITOctetNullableAttrDOMJIT::TestDOMJITOctetNullableAttrDOMJIT): (WebCore::TestDOMJITShortNullableAttrDOMJIT::TestDOMJITShortNullableAttrDOMJIT): (WebCore::TestDOMJITUnsignedShortNullableAttrDOMJIT::TestDOMJITUnsignedShortNullableAttrDOMJIT): (WebCore::TestDOMJITLongNullableAttrDOMJIT::TestDOMJITLongNullableAttrDOMJIT): (WebCore::TestDOMJITUnsignedLongNullableAttrDOMJIT::TestDOMJITUnsignedLongNullableAttrDOMJIT): (WebCore::TestDOMJITLongLongNullableAttrDOMJIT::TestDOMJITLongLongNullableAttrDOMJIT): (WebCore::TestDOMJITUnsignedLongLongNullableAttrDOMJIT::TestDOMJITUnsignedLongLongNullableAttrDOMJIT): (WebCore::TestDOMJITFloatNullableAttrDOMJIT::TestDOMJITFloatNullableAttrDOMJIT): (WebCore::TestDOMJITUnrestrictedFloatNullableAttrDOMJIT::TestDOMJITUnrestrictedFloatNullableAttrDOMJIT): (WebCore::TestDOMJITDoubleNullableAttrDOMJIT::TestDOMJITDoubleNullableAttrDOMJIT): (WebCore::TestDOMJITUnrestrictedDoubleNullableAttrDOMJIT::TestDOMJITUnrestrictedDoubleNullableAttrDOMJIT): (WebCore::TestDOMJITDomStringNullableAttrDOMJIT::TestDOMJITDomStringNullableAttrDOMJIT): (WebCore::TestDOMJITByteStringNullableAttrDOMJIT::TestDOMJITByteStringNullableAttrDOMJIT): (WebCore::TestDOMJITUsvStringNullableAttrDOMJIT::TestDOMJITUsvStringNullableAttrDOMJIT): (WebCore::TestDOMJITNodeNullableAttrDOMJIT::TestDOMJITNodeNullableAttrDOMJIT): (WebCore::jsTestDOMJITPrototypeFunctionGetAttribute): (WebCore::jsTestDOMJITPrototypeFunctionGetAttributeCaller): (WebCore::unsafeJsTestDOMJITPrototypeFunctionGetAttribute): (WebCore::jsTestDOMJITPrototypeFunctionItem): (WebCore::jsTestDOMJITPrototypeFunctionItemCaller): (WebCore::unsafeJsTestDOMJITPrototypeFunctionItem): (WebCore::jsTestDOMJITPrototypeFunctionHasAttribute): (WebCore::jsTestDOMJITPrototypeFunctionHasAttributeCaller): (WebCore::unsafeJsTestDOMJITPrototypeFunctionHasAttribute): (WebCore::jsTestDOMJITPrototypeFunctionGetElementById): (WebCore::jsTestDOMJITPrototypeFunctionGetElementByIdCaller): (WebCore::unsafeJsTestDOMJITPrototypeFunctionGetElementById): (WebCore::jsTestDOMJITPrototypeFunctionGetElementsByName): (WebCore::jsTestDOMJITPrototypeFunctionGetElementsByNameCaller): (WebCore::unsafeJsTestDOMJITPrototypeFunctionGetElementsByName): * bindings/scripts/test/TestDOMJIT.idl: * dom/Element.idl: * domjit/DOMJITAbstractHeapRepository.yaml: Added. * domjit/DOMJITIDLConvert.h: Added. (WebCore::DOMJIT::DirectConverter<IDLDOMString>::directConvert<StringConversionConfiguration::Normal>): * domjit/DOMJITIDLType.h: Added. * domjit/DOMJITIDLTypeFilter.h: Added. * domjit/JSDocumentDOMJIT.cpp: (WebCore::DocumentDocumentElementDOMJIT::callDOMGetter): * domjit/JSNodeDOMJIT.cpp: (WebCore::NodeFirstChildDOMJIT::callDOMGetter): (WebCore::NodeLastChildDOMJIT::callDOMGetter): (WebCore::NodeNextSiblingDOMJIT::callDOMGetter): (WebCore::NodePreviousSiblingDOMJIT::callDOMGetter): (WebCore::NodeParentNodeDOMJIT::callDOMGetter): (WebCore::NodeOwnerDocumentDOMJIT::callDOMGetter): * domjit/generate-abstract-heap.rb: Added. LayoutTests: * js/dom/domjit-accessor-licm.html: * js/dom/domjit-function-effect-should-overlap-with-call-expected.txt: Added. * js/dom/domjit-function-effect-should-overlap-with-call.html: Added. * js/dom/domjit-function-expected.txt: Added. * js/dom/domjit-function-licm-expected.txt: Added. * js/dom/domjit-function-licm.html: Copied from LayoutTests/js/dom/domjit-accessor-licm.html. * js/dom/domjit-function-type-contradiction-expected.txt: Added. * js/dom/domjit-function-type-contradiction.html: Copied from LayoutTests/js/dom/domjit-accessor-licm.html. * js/dom/domjit-function-type-failure-expected.txt: Added. * js/dom/domjit-function-type-failure.html: Copied from LayoutTests/js/dom/domjit-accessor-licm.html. * js/dom/domjit-function.html: Added. Canonical link: https://commits.webkit.org/182079@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@208320 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2016-11-03 03:20:53 +00:00
Test DOMJIT function will be LICM-ed.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS successfullyParsed is true
TEST COMPLETE