Changeset 208579 in webkit
- Timestamp:
- Nov 10, 2016, 10:08:18 PM (9 years ago)
- Location:
- trunk
- Files:
-
- 2 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r208576 r208579 1 2016-11-10 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [DOMJIT] Document#body should have DOMJIT patchpoint 4 https://bugs.webkit.org/show_bug.cgi?id=164627 5 6 Reviewed by Darin Adler. 7 8 * js/dom/domjit-accessor-document-body-expected.txt: Added. 9 * js/dom/domjit-accessor-document-body.html: Added. 10 1 11 2016-11-10 John Wilander <wilander@apple.com> 2 12 -
trunk/Source/WebCore/ChangeLog
r208578 r208579 1 2016-11-10 Yusuke Suzuki <utatane.tea@gmail.com> 2 3 [DOMJIT] Document#body should have DOMJIT patchpoint 4 https://bugs.webkit.org/show_bug.cgi?id=164627 5 6 Reviewed by Darin Adler. 7 8 This patch implements document.body accessor. To implement it, we need, 9 10 1. DOM traversing ability from ASM. 11 2. Checking HTMLElement. 12 3. Checking HTMLElement's localName. 13 14 The above features are already implemented in CSSJIT. 15 We extract some of utilities from CSSJIT to share them with DOMJIT. 16 17 Test: js/dom/domjit-accessor-document-body.html 18 19 * cssjit/SelectorCompiler.cpp: 20 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateWalkToParentElement): 21 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateWalkToNextAdjacentElement): 22 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateWalkToPreviousAdjacentElement): 23 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeMatching): 24 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeValueExactMatching): 25 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementAttributeFunctionCallValueMatching): 26 (WebCore::SelectorCompiler::jumpIfElementIsNotEmpty): 27 (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementHasTagName): 28 (WebCore::SelectorCompiler::testIsElementFlagOnNode): Deleted. 29 (WebCore::SelectorCompiler::testIsHTMLFlagOnNode): Deleted. 30 * dom/Document.idl: 31 * dom/Element.h: 32 * dom/QualifiedName.h: 33 * domjit/DOMJITAbstractHeapRepository.yaml: 34 * domjit/DOMJITHelpers.h: 35 (WebCore::DOMJIT::branchTestIsElementFlagOnNode): 36 (WebCore::DOMJIT::branchTestIsHTMLFlagOnNode): 37 * domjit/JSDocumentDOMJIT.cpp: 38 (WebCore::DocumentBodyDOMJIT::checkDOM): 39 (WebCore::loadLocalName): 40 (WebCore::DocumentBodyDOMJIT::callDOMGetter): 41 1 42 2016-11-10 John Wilander <wilander@apple.com> 2 43 -
trunk/Source/WebCore/cssjit/SelectorCompiler.cpp
r208267 r208579 2022 2022 } 2023 2023 2024 static inline Assembler::Jump testIsElementFlagOnNode(Assembler::ResultCondition condition, Assembler& assembler, Assembler::RegisterID nodeAddress)2025 {2026 return assembler.branchTest32(condition, Assembler::Address(nodeAddress, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagIsElement()));2027 }2028 2029 2024 void SelectorCodeGenerator::generateRightmostTreeWalker(Assembler::JumpList& failureCases, const SelectorFragment& fragment) 2030 2025 { … … 2044 2039 generateWalkToParentNode(targetRegister); 2045 2040 failureCases.append(m_assembler.branchTestPtr(Assembler::Zero, targetRegister)); 2046 failureCases.append( testIsElementFlagOnNode(Assembler::Zero, m_assembler, targetRegister));2041 failureCases.append(DOMJIT::branchTestIsElementFlagOnNode(m_assembler, Assembler::Zero, targetRegister)); 2047 2042 } 2048 2043 … … 2097 2092 m_assembler.loadPtr(Assembler::Address(workRegister, Node::nextSiblingMemoryOffset()), workRegister); 2098 2093 failureCases.append(m_assembler.branchTestPtr(Assembler::Zero, workRegister)); 2099 testIsElementFlagOnNode(Assembler::Zero, m_assembler, workRegister).linkTo(loopStart, &m_assembler);2094 DOMJIT::branchTestIsElementFlagOnNode(m_assembler, Assembler::Zero, workRegister).linkTo(loopStart, &m_assembler); 2100 2095 } 2101 2096 … … 2105 2100 m_assembler.loadPtr(Assembler::Address(workRegister, Node::previousSiblingMemoryOffset()), workRegister); 2106 2101 failureCases.append(m_assembler.branchTestPtr(Assembler::Zero, workRegister)); 2107 testIsElementFlagOnNode(Assembler::Zero, m_assembler, workRegister).linkTo(loopStart, &m_assembler);2102 DOMJIT::branchTestIsElementFlagOnNode(m_assembler, Assembler::Zero, workRegister).linkTo(loopStart, &m_assembler); 2108 2103 } 2109 2104 … … 2652 2647 } 2653 2648 2654 static inline Assembler::Jump testIsHTMLFlagOnNode(Assembler::ResultCondition condition, Assembler& assembler, Assembler::RegisterID nodeAddress)2655 {2656 return assembler.branchTest32(condition, Assembler::Address(nodeAddress, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagIsHTML()));2657 }2658 2659 2649 static inline bool canMatchStyleAttribute(const SelectorFragment& fragment) 2660 2650 { … … 2799 2789 else { 2800 2790 m_assembler.move(Assembler::TrustedImmPtr(canonicalLocalName), localNameToMatch); 2801 Assembler::Jump elementIsHTML = testIsHTMLFlagOnNode(Assembler::NonZero, m_assembler, elementAddressRegister);2791 Assembler::Jump elementIsHTML = DOMJIT::branchTestIsHTMLFlagOnNode(m_assembler, Assembler::NonZero, elementAddressRegister); 2802 2792 m_assembler.move(Assembler::TrustedImmPtr(localName), localNameToMatch); 2803 2793 elementIsHTML.link(&m_assembler); … … 2981 2971 // Taking the contrapositive, if we find the element is not HTML or is not in a HTML document, the condition above 2982 2972 // sould be sufficient and we can fail early. 2983 failureCases.append( testIsHTMLFlagOnNode(Assembler::Zero, m_assembler, elementAddressRegister));2973 failureCases.append(DOMJIT::branchTestIsHTMLFlagOnNode(m_assembler, Assembler::Zero, elementAddressRegister)); 2984 2974 2985 2975 { … … 3031 3021 case AttributeCaseSensitivity::HTMLLegacyCaseInsensitive: { 3032 3022 Assembler::JumpList shouldUseCaseSensitiveComparison; 3033 shouldUseCaseSensitiveComparison.append( testIsHTMLFlagOnNode(Assembler::Zero, m_assembler, elementAddressRegister));3023 shouldUseCaseSensitiveComparison.append(DOMJIT::branchTestIsHTMLFlagOnNode(m_assembler, Assembler::Zero, elementAddressRegister)); 3034 3024 { 3035 3025 LocalRegister scratchRegister(m_registerAllocator); … … 3117 3107 Assembler::Jump noMoreChildren = assembler.branchTestPtr(Assembler::Zero, currentChild); 3118 3108 3119 notEmptyCases.append( testIsElementFlagOnNode(Assembler::NonZero, assembler, currentChild));3109 notEmptyCases.append(DOMJIT::branchTestIsElementFlagOnNode(assembler, Assembler::NonZero, currentChild)); 3120 3110 3121 3111 { … … 3412 3402 } else { 3413 3403 Assembler::JumpList caseSensitiveCases; 3414 caseSensitiveCases.append( testIsHTMLFlagOnNode(Assembler::Zero, m_assembler, elementAddressRegister));3404 caseSensitiveCases.append(DOMJIT::branchTestIsHTMLFlagOnNode(m_assembler, Assembler::Zero, elementAddressRegister)); 3415 3405 { 3416 3406 LocalRegister document(m_registerAllocator); -
trunk/Source/WebCore/dom/Document.idl
r208144 r208579 102 102 [GetterMayThrowException, SetterMayThrowException] attribute USVString cookie; 103 103 104 [CEReactions, ImplementedAs=bodyOrFrameset, SetterMayThrowException] attribute HTMLElement? body;104 [CEReactions, DOMJIT, ImplementedAs=bodyOrFrameset, SetterMayThrowException] attribute HTMLElement? body; 105 105 106 106 readonly attribute HTMLHeadElement? head; -
trunk/Source/WebCore/dom/Element.h
r208347 r208579 203 203 204 204 const QualifiedName& tagQName() const { return m_tagName; } 205 #if ENABLE( CSS_SELECTOR_JIT)205 #if ENABLE(JIT) 206 206 static ptrdiff_t tagQNameMemoryOffset() { return OBJECT_OFFSETOF(Element, m_tagName); } 207 #endif // ENABLE( CSS_SELECTOR_JIT)207 #endif // ENABLE(JIT) 208 208 String tagName() const { return nodeName(); } 209 209 bool hasTagName(const QualifiedName& tagName) const { return m_tagName.matches(tagName); } -
trunk/Source/WebCore/dom/QualifiedName.h
r208179 r208579 54 54 mutable AtomicString m_localNameUpper; 55 55 56 #if ENABLE( CSS_SELECTOR_JIT)56 #if ENABLE(JIT) 57 57 static ptrdiff_t localNameMemoryOffset() { return OBJECT_OFFSETOF(QualifiedNameImpl, m_localName); } 58 58 static ptrdiff_t namespaceMemoryOffset() { return OBJECT_OFFSETOF(QualifiedNameImpl, m_namespace); } 59 #endif // ENABLE( CSS_SELECTOR_JIT)59 #endif // ENABLE(JIT) 60 60 61 61 private: … … 95 95 96 96 QualifiedNameImpl* impl() const { return m_impl.get(); } 97 #if ENABLE( CSS_SELECTOR_JIT)97 #if ENABLE(JIT) 98 98 static ptrdiff_t implMemoryOffset() { return OBJECT_OFFSETOF(QualifiedName, m_impl); } 99 #endif // ENABLE( CSS_SELECTOR_JIT)99 #endif // ENABLE(JIT) 100 100 101 101 // Init routine for globals -
trunk/Source/WebCore/domjit/DOMJITAbstractHeapRepository.yaml
r208320 r208579 10 10 Document: 11 11 - Document_documentElement 12 - Document_body -
trunk/Source/WebCore/domjit/DOMJITHelpers.h
r208412 r208579 28 28 29 29 #include "JSDOMWrapper.h" 30 #include " ScriptWrappable.h"30 #include "Node.h" 31 31 #include <domjit/DOMJITPatchpoint.h> 32 32 #include <domjit/DOMJITPatchpointParams.h> … … 176 176 void loadDocumentElement(MacroAssembler&, GPRReg document, GPRReg output); 177 177 178 inline CCallHelpers::Jump branchTestIsElementFlagOnNode(MacroAssembler& jit, CCallHelpers::ResultCondition condition, GPRReg nodeAddress) 179 { 180 return jit.branchTest32(condition, CCallHelpers::Address(nodeAddress, Node::nodeFlagsMemoryOffset()), CCallHelpers::TrustedImm32(Node::flagIsElement())); 181 } 182 183 inline CCallHelpers::Jump branchTestIsHTMLFlagOnNode(MacroAssembler& jit, CCallHelpers::ResultCondition condition, GPRReg nodeAddress) 184 { 185 return jit.branchTest32(condition, CCallHelpers::Address(nodeAddress, Node::nodeFlagsMemoryOffset()), CCallHelpers::TrustedImm32(Node::flagIsHTML())); 186 } 187 178 188 } } 179 189 -
trunk/Source/WebCore/domjit/JSDocumentDOMJIT.cpp
r208320 r208579 35 35 #include "JSDOMWrapper.h" 36 36 #include "JSElement.h" 37 #include "JSHTMLElement.h" 37 38 #include <domjit/DOMJITPatchpoint.h> 38 39 #include <domjit/DOMJITPatchpointParams.h> … … 74 75 } 75 76 77 Ref<JSC::DOMJIT::Patchpoint> DocumentBodyDOMJIT::checkDOM() 78 { 79 return DOMJIT::checkDOM<Document>(); 80 } 81 82 static void loadLocalName(CCallHelpers& jit, GPRReg htmlElement, GPRReg localNameImpl) 83 { 84 jit.loadPtr(CCallHelpers::Address(htmlElement, Element::tagQNameMemoryOffset() + QualifiedName::implMemoryOffset()), localNameImpl); 85 jit.loadPtr(CCallHelpers::Address(localNameImpl, QualifiedName::QualifiedNameImpl::localNameMemoryOffset()), localNameImpl); 86 } 87 88 Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> DocumentBodyDOMJIT::callDOMGetter() 89 { 90 Ref<JSC::DOMJIT::CallDOMGetterPatchpoint> patchpoint = JSC::DOMJIT::CallDOMGetterPatchpoint::create(); 91 patchpoint->numGPScratchRegisters = 2; 92 patchpoint->setGenerator([=](CCallHelpers& jit, JSC::DOMJIT::PatchpointParams& params) { 93 JSValueRegs result = params[0].jsValueRegs(); 94 GPRReg document = params[1].gpr(); 95 GPRReg globalObject = params[2].gpr(); 96 JSValue globalObjectValue = params[2].value(); 97 GPRReg scratch1 = params.gpScratch(0); 98 GPRReg scratch2 = params.gpScratch(1); 99 100 jit.loadPtr(CCallHelpers::Address(document, JSDocument::offsetOfWrapped()), scratch1); 101 DOMJIT::loadDocumentElement(jit, scratch1, scratch1); 102 103 CCallHelpers::JumpList nullCases; 104 CCallHelpers::JumpList successCases; 105 nullCases.append(jit.branchTestPtr(CCallHelpers::Zero, scratch1)); 106 nullCases.append(DOMJIT::branchTestIsHTMLFlagOnNode(jit, CCallHelpers::Zero, scratch1)); 107 // We ensured that the name of the given element is HTML qualified. 108 // It allows us to perform local name comparison! 109 loadLocalName(jit, scratch1, scratch2); 110 nullCases.append(jit.branchPtr(CCallHelpers::NotEqual, scratch2, CCallHelpers::TrustedImmPtr(HTMLNames::htmlTag.localName().impl()))); 111 112 RELEASE_ASSERT(!CAST_OFFSET(Node*, ContainerNode*)); 113 RELEASE_ASSERT(!CAST_OFFSET(Node*, Element*)); 114 RELEASE_ASSERT(!CAST_OFFSET(Node*, HTMLElement*)); 115 116 // Node* node = current.firstChild(); 117 // while (node && !is<HTMLElement>(*node)) 118 // node = node->nextSibling(); 119 // return downcast<HTMLElement>(node); 120 jit.loadPtr(CCallHelpers::Address(scratch1, ContainerNode::firstChildMemoryOffset()), scratch1); 121 122 CCallHelpers::Label loopStart = jit.label(); 123 nullCases.append(jit.branchTestPtr(CCallHelpers::Zero, scratch1)); 124 auto notHTMLElementCase = DOMJIT::branchTestIsHTMLFlagOnNode(jit, CCallHelpers::Zero, scratch1); 125 // We ensured that the name of the given element is HTML qualified. 126 // It allows us to perform local name comparison! 127 loadLocalName(jit, scratch1, scratch2); 128 successCases.append(jit.branchPtr(CCallHelpers::Equal, scratch2, CCallHelpers::TrustedImmPtr(HTMLNames::bodyTag.localName().impl()))); 129 successCases.append(jit.branchPtr(CCallHelpers::Equal, scratch2, CCallHelpers::TrustedImmPtr(HTMLNames::framesetTag.localName().impl()))); 130 131 notHTMLElementCase.link(&jit); 132 jit.loadPtr(CCallHelpers::Address(scratch1, Node::nextSiblingMemoryOffset()), scratch1); 133 jit.jump().linkTo(loopStart, &jit); 134 135 successCases.link(&jit); 136 DOMJIT::toWrapper<HTMLElement>(jit, params, scratch1, globalObject, result, DOMJIT::toWrapperSlow<HTMLElement>, globalObjectValue); 137 auto done = jit.jump(); 138 139 nullCases.link(&jit); 140 jit.moveValue(jsNull(), result); 141 done.link(&jit); 142 143 return CCallHelpers::JumpList(); 144 }); 145 patchpoint->effect = JSC::DOMJIT::Effect::forDef(DOMJIT::AbstractHeapRepository::Document_body); 146 return patchpoint; 147 } 148 76 149 } 77 150
Note:
See TracChangeset
for help on using the changeset viewer.