<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[160983] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/160983">160983</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2013-12-22 16:45:25 -0800 (Sun, 22 Dec 2013)</dd>
</dl>

<h3>Log Message</h3>
<pre>Create a skeleton for CSS Selector code generation
https://bugs.webkit.org/show_bug.cgi?id=126044

Source/JavaScriptCore: 

Reviewed by Antti Koivisto and Gavin Barraclough.

* assembler/LinkBuffer.h:
Add a new owner UID for code compiled for CSS.
Export the symbols needed to link code from WebCore.

Source/WebCore: 

Patch by Benjamin Poulain &lt;bpoulain@apple.com&gt; on 2013-12-22
Reviewed by Antti Koivisto and Gavin Barraclough.

Add CSSCompiler, which provides the basic infrastructure to compile
CSS Selectors on x86_64.

Compilation happens in two phases.
1) The various matching and relation of each CSSSelector is aggregated into units
   matching a single element: SelectorFragment.
   SelectorFragment also knows about the relations between different fragments,
   and contains all the information to generate the code for a particular element.
2) The compiler then goes over the fragments, and generate code based on the information
   of each fragment.

It the current state, SelectorCompiler only compiles the tag matching selectors and
any of the relation between selectors.

Depending on the relation and position of a fragment, failure on traversal or matching
does not necessarily causes the complete selector. A failure can cause matching to
resume from the parent or the sibling of a previously visisted node.
The implementation of this is done through the BacktrackingAction. In case of failure,
the next starting state is setup and the program counter jumps back to the appropriate
starting point.

When backtracking, the method used to save the starting point depends on the type
of backtracking.
The child/parent relation (&quot;&gt;&quot;) is very common so it uses an additional register to keep
the next starting point (m_descendantBacktrackingStart).
The indirect sibling relation (&quot;~&quot;) is much less common and uses the stack to save
the next starting point.

* WebCore.xcodeproj/project.pbxproj:
* cssjit/SelectorCompiler.cpp: Added.
(WebCore::SelectorCompiler::SelectorFragment::SelectorFragment):
(WebCore::SelectorCompiler::compileSelector):
(WebCore::SelectorCompiler::fragmentRelationForSelectorRelation):
(WebCore::SelectorCompiler::SelectorCodeGenerator::SelectorCodeGenerator):
(WebCore::SelectorCompiler::SelectorCodeGenerator::compile):
(WebCore::SelectorCompiler::updateChainStates):
(WebCore::SelectorCompiler::isFirstAncestor):
(WebCore::SelectorCompiler::isFirstAdjacent):
(WebCore::SelectorCompiler::isAfterChildRelation):
(WebCore::SelectorCompiler::solveBacktrackingAction):
(WebCore::SelectorCompiler::requiresAdjacentTail):
(WebCore::SelectorCompiler::requiresDescendantTail):
(WebCore::SelectorCompiler::SelectorCodeGenerator::computeBacktrackingInformation):
(WebCore::SelectorCompiler::testIsElementFlagOnNode):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateWalkToParentElement):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateParentElementTreeWalker):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateAncestorTreeWalker):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateWalkToPreviousAdjacent):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateDirectAdjacentTreeWalker):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateIndirectAdjacentTreeWalker):
(WebCore::SelectorCompiler::SelectorCodeGenerator::markParentElementIfResolvingStyle):
(WebCore::SelectorCompiler::SelectorCodeGenerator::linkFailures):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateAdjacentBacktrackingTail):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateDescendantBacktrackingTail):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateBacktrackingTailsIfNeeded):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementMatching):
(WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementHasTagName):
* cssjit/SelectorCompiler.h: Added.
(WebCore::SelectorCompilationStatus::SelectorCompilationStatus):
(WebCore::SelectorCompilationStatus::operator Status):
(WebCore::SelectorCompiler::simpleSelectorCheckerFunction):
(WebCore::SelectorCompiler::selectorCheckerFunctionWithCheckingContext):
* dom/Element.cpp:
(WebCore::Element::setChildrenAffectedByDirectAdjacentRules):
(WebCore::Element::setChildrenAffectedByForwardPositionalRules):
* dom/Element.h:
(WebCore::Element::tagQNameMemoryOffset):
(WebCore::Element::setChildrenAffectedByForwardPositionalRules):
* dom/Node.h:
(WebCore::Node::parentNodeMemoryOffset):
(WebCore::Node::previousSiblingMemoryOffset):
(WebCore::Node::nodeFlagsMemoryOffset):
(WebCore::Node::flagIsElement):
* dom/QualifiedName.h:
(WebCore::QualifiedName::QualifiedNameImpl::localNameMemoryOffset):
(WebCore::QualifiedName::QualifiedNameImpl::namespaceMemoryOffset):
(WebCore::QualifiedName::implMemoryOffset):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreassemblerLinkBufferh">trunk/Source/JavaScriptCore/assembler/LinkBuffer.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoredomElementcpp">trunk/Source/WebCore/dom/Element.cpp</a></li>
<li><a href="#trunkSourceWebCoredomElementh">trunk/Source/WebCore/dom/Element.h</a></li>
<li><a href="#trunkSourceWebCoredomNodeh">trunk/Source/WebCore/dom/Node.h</a></li>
<li><a href="#trunkSourceWebCoredomQualifiedNameh">trunk/Source/WebCore/dom/QualifiedName.h</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCorecssjitSelectorCompilercpp">trunk/Source/WebCore/cssjit/SelectorCompiler.cpp</a></li>
<li><a href="#trunkSourceWebCorecssjitSelectorCompilerh">trunk/Source/WebCore/cssjit/SelectorCompiler.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (160982 => 160983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2013-12-23 00:02:40 UTC (rev 160982)
+++ trunk/Source/JavaScriptCore/ChangeLog        2013-12-23 00:45:25 UTC (rev 160983)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2013-12-22  Benjamin Poulain  &lt;benjamin@webkit.org&gt;
+
+        Create a skeleton for CSS Selector code generation
+        https://bugs.webkit.org/show_bug.cgi?id=126044
+
+        Reviewed by Antti Koivisto and Gavin Barraclough.
+
+        * assembler/LinkBuffer.h:
+        Add a new owner UID for code compiled for CSS.
+        Export the symbols needed to link code from WebCore.
+
</ins><span class="cx"> 2013-12-19  Mark Hahnenberg  &lt;mhahnenberg@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Clean up DFG write barriers
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreassemblerLinkBufferh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/assembler/LinkBuffer.h (160982 => 160983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/assembler/LinkBuffer.h        2013-12-23 00:02:40 UTC (rev 160982)
+++ trunk/Source/JavaScriptCore/assembler/LinkBuffer.h        2013-12-23 00:45:25 UTC (rev 160983)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> 
</span><span class="cx"> #define GLOBAL_THUNK_ID reinterpret_cast&lt;void*&gt;(static_cast&lt;intptr_t&gt;(-1))
</span><span class="cx"> #define REGEXP_CODE_ID reinterpret_cast&lt;void*&gt;(static_cast&lt;intptr_t&gt;(-2))
</span><ins>+#define CSS_CODE_ID reinterpret_cast&lt;void*&gt;(static_cast&lt;intptr_t&gt;(-3))
</ins><span class="cx"> 
</span><span class="cx"> #include &quot;JITCompilationEffort.h&quot;
</span><span class="cx"> #include &quot;MacroAssembler.h&quot;
</span><span class="lines">@@ -231,8 +232,8 @@
</span><span class="cx">     // finalizeCodeWithoutDisassembly() directly if you have your own way of
</span><span class="cx">     // displaying disassembly.
</span><span class="cx">     
</span><del>-    CodeRef finalizeCodeWithoutDisassembly();
-    CodeRef finalizeCodeWithDisassembly(const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
</del><ins>+    JS_EXPORT_PRIVATE CodeRef finalizeCodeWithoutDisassembly();
+    JS_EXPORT_PRIVATE CodeRef finalizeCodeWithDisassembly(const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3);
</ins><span class="cx"> 
</span><span class="cx">     CodePtr trampolineAt(Label label)
</span><span class="cx">     {
</span><span class="lines">@@ -267,7 +268,7 @@
</span><span class="cx">     void allocate(size_t initialSize, void* ownerUID, JITCompilationEffort);
</span><span class="cx">     void shrink(size_t newSize);
</span><span class="cx"> 
</span><del>-    void linkCode(void* ownerUID, JITCompilationEffort);
</del><ins>+    JS_EXPORT_PRIVATE void linkCode(void* ownerUID, JITCompilationEffort);
</ins><span class="cx"> #if ENABLE(BRANCH_COMPACTION)
</span><span class="cx">     template &lt;typename InstructionType&gt;
</span><span class="cx">     void copyCompactAndLinkCode(void* ownerUID, JITCompilationEffort);
</span><span class="lines">@@ -319,10 +320,10 @@
</span><span class="cx"> // is true, so you can hide expensive disassembly-only computations inside there.
</span><span class="cx"> 
</span><span class="cx"> #define FINALIZE_CODE(linkBufferReference, dataLogFArgumentsForHeading)  \
</span><del>-    FINALIZE_CODE_IF(Options::showDisassembly(), linkBufferReference, dataLogFArgumentsForHeading)
</del><ins>+    FINALIZE_CODE_IF(JSC::Options::showDisassembly(), linkBufferReference, dataLogFArgumentsForHeading)
</ins><span class="cx"> 
</span><span class="cx"> #define FINALIZE_DFG_CODE(linkBufferReference, dataLogFArgumentsForHeading)  \
</span><del>-    FINALIZE_CODE_IF((Options::showDisassembly() || Options::showDFGDisassembly()), linkBufferReference, dataLogFArgumentsForHeading)
</del><ins>+    FINALIZE_CODE_IF((JSC::Options::showDisassembly() || Options::showDFGDisassembly()), linkBufferReference, dataLogFArgumentsForHeading)
</ins><span class="cx"> 
</span><span class="cx"> } // namespace JSC
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (160982 => 160983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2013-12-23 00:02:40 UTC (rev 160982)
+++ trunk/Source/WebCore/ChangeLog        2013-12-23 00:45:25 UTC (rev 160983)
</span><span class="lines">@@ -1,3 +1,88 @@
</span><ins>+2013-12-22  Benjamin Poulain  &lt;bpoulain@apple.com&gt;
+
+        Create a skeleton for CSS Selector code generation
+        https://bugs.webkit.org/show_bug.cgi?id=126044
+
+        Reviewed by Antti Koivisto and Gavin Barraclough.
+
+        Add CSSCompiler, which provides the basic infrastructure to compile
+        CSS Selectors on x86_64.
+
+        Compilation happens in two phases.
+        1) The various matching and relation of each CSSSelector is aggregated into units
+           matching a single element: SelectorFragment.
+           SelectorFragment also knows about the relations between different fragments,
+           and contains all the information to generate the code for a particular element.
+        2) The compiler then goes over the fragments, and generate code based on the information
+           of each fragment.
+
+        It the current state, SelectorCompiler only compiles the tag matching selectors and
+        any of the relation between selectors.
+
+        Depending on the relation and position of a fragment, failure on traversal or matching
+        does not necessarily causes the complete selector. A failure can cause matching to
+        resume from the parent or the sibling of a previously visisted node.
+        The implementation of this is done through the BacktrackingAction. In case of failure,
+        the next starting state is setup and the program counter jumps back to the appropriate
+        starting point.
+
+        When backtracking, the method used to save the starting point depends on the type
+        of backtracking.
+        The child/parent relation (&quot;&gt;&quot;) is very common so it uses an additional register to keep
+        the next starting point (m_descendantBacktrackingStart).
+        The indirect sibling relation (&quot;~&quot;) is much less common and uses the stack to save
+        the next starting point.
+
+        * WebCore.xcodeproj/project.pbxproj:
+        * cssjit/SelectorCompiler.cpp: Added.
+        (WebCore::SelectorCompiler::SelectorFragment::SelectorFragment):
+        (WebCore::SelectorCompiler::compileSelector):
+        (WebCore::SelectorCompiler::fragmentRelationForSelectorRelation):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::SelectorCodeGenerator):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::compile):
+        (WebCore::SelectorCompiler::updateChainStates):
+        (WebCore::SelectorCompiler::isFirstAncestor):
+        (WebCore::SelectorCompiler::isFirstAdjacent):
+        (WebCore::SelectorCompiler::isAfterChildRelation):
+        (WebCore::SelectorCompiler::solveBacktrackingAction):
+        (WebCore::SelectorCompiler::requiresAdjacentTail):
+        (WebCore::SelectorCompiler::requiresDescendantTail):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::computeBacktrackingInformation):
+        (WebCore::SelectorCompiler::testIsElementFlagOnNode):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateWalkToParentElement):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateParentElementTreeWalker):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateAncestorTreeWalker):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateWalkToPreviousAdjacent):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateDirectAdjacentTreeWalker):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateIndirectAdjacentTreeWalker):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::markParentElementIfResolvingStyle):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::linkFailures):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateAdjacentBacktrackingTail):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateDescendantBacktrackingTail):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateBacktrackingTailsIfNeeded):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementMatching):
+        (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementHasTagName):
+        * cssjit/SelectorCompiler.h: Added.
+        (WebCore::SelectorCompilationStatus::SelectorCompilationStatus):
+        (WebCore::SelectorCompilationStatus::operator Status):
+        (WebCore::SelectorCompiler::simpleSelectorCheckerFunction):
+        (WebCore::SelectorCompiler::selectorCheckerFunctionWithCheckingContext):
+        * dom/Element.cpp:
+        (WebCore::Element::setChildrenAffectedByDirectAdjacentRules):
+        (WebCore::Element::setChildrenAffectedByForwardPositionalRules):
+        * dom/Element.h:
+        (WebCore::Element::tagQNameMemoryOffset):
+        (WebCore::Element::setChildrenAffectedByForwardPositionalRules):
+        * dom/Node.h:
+        (WebCore::Node::parentNodeMemoryOffset):
+        (WebCore::Node::previousSiblingMemoryOffset):
+        (WebCore::Node::nodeFlagsMemoryOffset):
+        (WebCore::Node::flagIsElement):
+        * dom/QualifiedName.h:
+        (WebCore::QualifiedName::QualifiedNameImpl::localNameMemoryOffset):
+        (WebCore::QualifiedName::QualifiedNameImpl::namespaceMemoryOffset):
+        (WebCore::QualifiedName::implMemoryOffset):
+
</ins><span class="cx"> 2013-12-22  Mihnea Ovidenie  &lt;mihnea@adobe.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [CSSRegions] Crash when trying to select content from invalid region
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (160982 => 160983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2013-12-23 00:02:40 UTC (rev 160982)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2013-12-23 00:45:25 UTC (rev 160983)
</span><span class="lines">@@ -914,6 +914,8 @@
</span><span class="cx">                 26B9998F1803AE7200D01121 /* RegisterAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 26B9998E1803AE7200D01121 /* RegisterAllocator.h */; };
</span><span class="cx">                 26B999911803B3C900D01121 /* StackAllocator.h in Headers */ = {isa = PBXBuildFile; fileRef = 26B999901803B3C900D01121 /* StackAllocator.h */; };
</span><span class="cx">                 26B999931803B9D900D01121 /* FunctionCall.h in Headers */ = {isa = PBXBuildFile; fileRef = 26B999921803B9D900D01121 /* FunctionCall.h */; };
</span><ins>+                26B999961804D54200D01121 /* SelectorCompiler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26B999941804D54200D01121 /* SelectorCompiler.cpp */; };
+                26B999971804D54200D01121 /* SelectorCompiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 26B999951804D54200D01121 /* SelectorCompiler.h */; };
</ins><span class="cx">                 26C15CF61857E15D00F15C03 /* ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26C15CF41857E15D00F15C03 /* ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp */; };
</span><span class="cx">                 26C15CF71857E15E00F15C03 /* ResourceHandleCFURLConnectionDelegateWithOperationQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = 26C15CF51857E15D00F15C03 /* ResourceHandleCFURLConnectionDelegateWithOperationQueue.h */; };
</span><span class="cx">                 26C17A3E1491D2D400D12BA2 /* FileSystemIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 26C17A3C1491D2D400D12BA2 /* FileSystemIOS.h */; };
</span><span class="lines">@@ -7581,6 +7583,8 @@
</span><span class="cx">                 26B9998E1803AE7200D01121 /* RegisterAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterAllocator.h; path = cssjit/RegisterAllocator.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 26B999901803B3C900D01121 /* StackAllocator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StackAllocator.h; path = cssjit/StackAllocator.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 26B999921803B9D900D01121 /* FunctionCall.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FunctionCall.h; path = cssjit/FunctionCall.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                26B999941804D54200D01121 /* SelectorCompiler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SelectorCompiler.cpp; path = cssjit/SelectorCompiler.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                26B999951804D54200D01121 /* SelectorCompiler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SelectorCompiler.h; path = cssjit/SelectorCompiler.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 26C15CF41857E15D00F15C03 /* ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceHandleCFURLConnectionDelegateWithOperationQueue.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 26C15CF51857E15D00F15C03 /* ResourceHandleCFURLConnectionDelegateWithOperationQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceHandleCFURLConnectionDelegateWithOperationQueue.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 26C17A3C1491D2D400D12BA2 /* FileSystemIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FileSystemIOS.h; path = ios/FileSystemIOS.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -14688,6 +14692,8 @@
</span><span class="cx">                 26B9998D1803ADFA00D01121 /* cssjit */ = {
</span><span class="cx">                         isa = PBXGroup;
</span><span class="cx">                         children = (
</span><ins>+                                26B999941804D54200D01121 /* SelectorCompiler.cpp */,
+                                26B999951804D54200D01121 /* SelectorCompiler.h */,
</ins><span class="cx">                                 26B999921803B9D900D01121 /* FunctionCall.h */,
</span><span class="cx">                                 26B9998E1803AE7200D01121 /* RegisterAllocator.h */,
</span><span class="cx">                                 26B999901803B3C900D01121 /* StackAllocator.h */,
</span><span class="lines">@@ -22522,6 +22528,7 @@
</span><span class="cx">                                 070F549817F12F6B00169E04 /* MediaStreamConstraintsValidationClient.h in Headers */,
</span><span class="cx">                                 371F51A10D262FA000ECE0D5 /* CSSSegmentedFontFace.h in Headers */,
</span><span class="cx">                                 A80E73520A199C77007FB8C5 /* CSSSelector.h in Headers */,
</span><ins>+                                26B999971804D54200D01121 /* SelectorCompiler.h in Headers */,
</ins><span class="cx">                                 E4C1789B0EE6903800824D69 /* CSSSelectorList.h in Headers */,
</span><span class="cx">                                 A80E6CE80A1989CA007FB8C5 /* CSSShadowValue.h in Headers */,
</span><span class="cx">                                 A80E6E0F0A19911C007FB8C5 /* CSSStyleDeclaration.h in Headers */,
</span><span class="lines">@@ -26050,6 +26057,7 @@
</span><span class="cx">                                 A80E6D090A1989CA007FB8C5 /* CSSRuleList.cpp in Sources */,
</span><span class="cx">                                 371F51A20D262FA000ECE0D5 /* CSSSegmentedFontFace.cpp in Sources */,
</span><span class="cx">                                 A80E734F0A199C77007FB8C5 /* CSSSelector.cpp in Sources */,
</span><ins>+                                26B999961804D54200D01121 /* SelectorCompiler.cpp in Sources */,
</ins><span class="cx">                                 E4C1789A0EE6903800824D69 /* CSSSelectorList.cpp in Sources */,
</span><span class="cx">                                 A80E6CF40A1989CA007FB8C5 /* CSSShadowValue.cpp in Sources */,
</span><span class="cx">                                 A80E6CEF0A1989CA007FB8C5 /* CSSStyleRule.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCorecssjitSelectorCompilercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (0 => 160983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp                                (rev 0)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp        2013-12-23 00:45:25 UTC (rev 160983)
</span><span class="lines">@@ -0,0 +1,758 @@
</span><ins>+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;SelectorCompiler.h&quot;
+
+#if ENABLE(CSS_SELECTOR_JIT)
+
+#include &quot;CSSSelector.h&quot;
+#include &quot;Element.h&quot;
+#include &quot;FunctionCall.h&quot;
+#include &quot;NodeRenderStyle.h&quot;
+#include &quot;QualifiedName.h&quot;
+#include &quot;RegisterAllocator.h&quot;
+#include &quot;RenderElement.h&quot;
+#include &quot;RenderStyle.h&quot;
+#include &quot;StackAllocator.h&quot;
+#include &lt;JavaScriptCore/LinkBuffer.h&gt;
+#include &lt;JavaScriptCore/MacroAssembler.h&gt;
+#include &lt;JavaScriptCore/VM.h&gt;
+#include &lt;wtf/HashSet.h&gt;
+#include &lt;wtf/Vector.h&gt;
+
+namespace WebCore {
+namespace SelectorCompiler {
+
+#define CSS_SELECTOR_JIT_DEBUGGING 0
+
+enum class BacktrackingAction {
+    NoBacktracking,
+    JumpToDescendantEntryPoint,
+    JumpToIndirectAdjacentEntryPoint,
+    JumpToDescendantTreeWalkerEntryPoint,
+    JumpToDescendantTail,
+    JumpToClearAdjacentDescendantTail,
+    JumpToDirectAdjacentTail
+};
+
+struct BacktrackingFlag {
+    enum {
+        DescendantEntryPoint = 1,
+        IndirectAdjacentEntryPoint = 1 &lt;&lt; 1,
+        SaveDescendantBacktrackingStart = 1 &lt;&lt; 2,
+        SaveAdjacentBacktrackingStart = 1 &lt;&lt; 3,
+        DirectAdjacentTail = 1 &lt;&lt; 4,
+        DescendantTail = 1 &lt;&lt; 5,
+    };
+};
+
+enum class FragmentRelation {
+    Rightmost,
+    Descendant,
+    Child,
+    DirectAdjacent,
+    IndirectAdjacent
+};
+
+enum class FunctionType {
+    SimpleSelectorChecker,
+    SelectorCheckerWithCheckingContext
+};
+
+struct SelectorFragment {
+    SelectorFragment()
+        : traversalBacktrackingAction(BacktrackingAction::NoBacktracking)
+        , matchingBacktrackingAction(BacktrackingAction::NoBacktracking)
+        , backtrackingFlags(0)
+        , tagName(0)
+    {
+    }
+    FragmentRelation relationToLeftFragment;
+    FragmentRelation relationToRightFragment;
+
+    BacktrackingAction traversalBacktrackingAction;
+    BacktrackingAction matchingBacktrackingAction;
+    unsigned char backtrackingFlags;
+
+    const QualifiedName* tagName;
+};
+
+typedef JSC::MacroAssembler Assembler;
+
+class SelectorCodeGenerator {
+public:
+    SelectorCodeGenerator(const CSSSelector*);
+    SelectorCompilationStatus compile(JSC::VM*, JSC::MacroAssemblerCodeRef&amp;);
+
+private:
+#if CPU(X86_64)
+    static const Assembler::RegisterID returnRegister = JSC::X86Registers::eax;
+    static const Assembler::RegisterID elementAddressRegister = JSC::X86Registers::edi;
+    static const Assembler::RegisterID checkingContextRegister = JSC::X86Registers::esi;
+#endif
+
+    void computeBacktrackingInformation();
+
+    // Element relations tree walker.
+    void generateWalkToParentElement(Assembler::JumpList&amp; failureCases, Assembler::RegisterID targetRegister);
+    void generateParentElementTreeWalker(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp;);
+    void generateAncestorTreeWalker(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp;);
+
+    void generateWalkToPreviousAdjacent(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp;);
+    void generateDirectAdjacentTreeWalker(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp;);
+    void generateIndirectAdjacentTreeWalker(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp;);
+    void markParentElementIfResolvingStyle(JSC::FunctionPtr);
+
+    void linkFailures(Assembler::JumpList&amp; globalFailureCases, BacktrackingAction, Assembler::JumpList&amp; localFailureCases);
+    void generateAdjacentBacktrackingTail(StackAllocator&amp; adjacentTailStack);
+    void generateDescendantBacktrackingTail();
+    void generateBacktrackingTailsIfNeeded(const SelectorFragment&amp;);
+
+    // Element properties matchers.
+    void generateElementMatching(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp;);
+    void generateElementHasTagName(Assembler::JumpList&amp; failureCases, const QualifiedName&amp; nameToMatch);
+
+    Assembler m_assembler;
+    RegisterAllocator m_registerAllocator;
+    StackAllocator m_stackAllocator;
+    Vector&lt;std::pair&lt;Assembler::Call, JSC::FunctionPtr&gt;&gt; m_functionCalls;
+
+    FunctionType m_functionType;
+    Vector&lt;SelectorFragment, 8&gt; m_selectorFragments;
+
+    StackAllocator::StackReference m_checkingContextStackReference;
+
+    Assembler::Label m_descendantEntryPoint;
+    Assembler::Label m_indirectAdjacentEntryPoint;
+    Assembler::Label m_descendantTreeWalkerBacktrackingPoint;
+    Assembler::RegisterID m_descendantBacktrackingStart;
+    Assembler::JumpList m_descendantBacktrackingFailureCases;
+    StackAllocator::StackReference m_adjacentBacktrackingStart;
+    Assembler::JumpList m_adjacentBacktrackingFailureCases;
+    Assembler::JumpList m_clearAdjacentEntryPointDescendantFailureCases;
+
+#if CSS_SELECTOR_JIT_DEBUGGING
+    const CSSSelector* m_originalSelector;
+#endif
+};
+
+SelectorCompilationStatus compileSelector(const CSSSelector* lastSelector, JSC::VM* vm, JSC::MacroAssemblerCodeRef&amp; codeRef)
+{
+    if (!vm-&gt;canUseJIT())
+        return SelectorCompilationStatus::CannotCompile;
+    SelectorCodeGenerator codeGenerator(lastSelector);
+    return codeGenerator.compile(vm, codeRef);
+}
+
+static inline FragmentRelation fragmentRelationForSelectorRelation(CSSSelector::Relation relation)
+{
+    switch (relation) {
+    case CSSSelector::Descendant:
+        return FragmentRelation::Descendant;
+    case CSSSelector::Child:
+        return FragmentRelation::Child;
+    case CSSSelector::DirectAdjacent:
+        return FragmentRelation::DirectAdjacent;
+    case CSSSelector::IndirectAdjacent:
+        return FragmentRelation::IndirectAdjacent;
+    case CSSSelector::SubSelector:
+    case CSSSelector::ShadowDescendant:
+        ASSERT_NOT_REACHED();
+    }
+    ASSERT_NOT_REACHED();
+    return FragmentRelation::Descendant;
+}
+
+inline SelectorCodeGenerator::SelectorCodeGenerator(const CSSSelector* rootSelector)
+    : m_stackAllocator(m_assembler)
+    , m_functionType(FunctionType::SimpleSelectorChecker)
+#if CSS_SELECTOR_JIT_DEBUGGING
+    , m_originalSelector(rootSelector)
+#endif
+{
+#if CSS_SELECTOR_JIT_DEBUGGING
+    dataLogF(&quot;Compiling \&quot;%s\&quot;\n&quot;, m_originalSelector-&gt;selectorText().utf8().data());
+#endif
+
+    SelectorFragment fragment;
+    FragmentRelation relationToPreviousFragment = FragmentRelation::Rightmost;
+    for (const CSSSelector* selector = rootSelector; selector; selector = selector-&gt;tagHistory()) {
+        switch (selector-&gt;m_match) {
+        case CSSSelector::Tag:
+            ASSERT(!fragment.tagName);
+            fragment.tagName = &amp;(selector-&gt;tagQName());
+            break;
+        case CSSSelector::Unknown:
+        case CSSSelector::Id:
+        case CSSSelector::Class:
+        case CSSSelector::Exact:
+        case CSSSelector::Set:
+        case CSSSelector::List:
+        case CSSSelector::Hyphen:
+        case CSSSelector::PseudoClass:
+        case CSSSelector::PseudoElement:
+        case CSSSelector::Contain:
+        case CSSSelector::Begin:
+        case CSSSelector::End:
+        case CSSSelector::PagePseudoClass:
+            goto CannotHandleSelector;
+        }
+
+        CSSSelector::Relation relation = selector-&gt;relation();
+        if (relation == CSSSelector::SubSelector)
+            continue;
+
+        if (relation == CSSSelector::ShadowDescendant &amp;&amp; !selector-&gt;isLastInTagHistory())
+            goto CannotHandleSelector;
+
+        if (relation == CSSSelector::DirectAdjacent || relation == CSSSelector::IndirectAdjacent)
+            m_functionType = std::max(m_functionType, FunctionType::SelectorCheckerWithCheckingContext);
+
+        fragment.relationToLeftFragment = fragmentRelationForSelectorRelation(relation);
+        fragment.relationToRightFragment = relationToPreviousFragment;
+        relationToPreviousFragment = fragment.relationToLeftFragment;
+
+        m_selectorFragments.append(fragment);
+        fragment = SelectorFragment();
+    }
+
+    computeBacktrackingInformation();
+
+    return;
+
+CannotHandleSelector:
+    m_selectorFragments.clear();
+}
+
+inline SelectorCompilationStatus SelectorCodeGenerator::compile(JSC::VM* vm, JSC::MacroAssemblerCodeRef&amp; codeRef)
+{
+    if (m_selectorFragments.isEmpty())
+        return SelectorCompilationStatus::CannotCompile;
+
+    m_registerAllocator.allocateRegister(elementAddressRegister);
+
+    if (m_functionType == FunctionType::SelectorCheckerWithCheckingContext)
+        m_checkingContextStackReference = m_stackAllocator.push(checkingContextRegister);
+
+    Assembler::JumpList failureCases;
+
+    for (unsigned i = 0; i &lt; m_selectorFragments.size(); ++i) {
+        const SelectorFragment&amp; fragment = m_selectorFragments[i];
+        switch (fragment.relationToRightFragment) {
+        case FragmentRelation::Rightmost:
+            generateElementMatching(failureCases, fragment);
+            break;
+        case FragmentRelation::Descendant:
+            generateAncestorTreeWalker(failureCases, fragment);
+            break;
+        case FragmentRelation::Child:
+            generateParentElementTreeWalker(failureCases, fragment);
+            break;
+        case FragmentRelation::DirectAdjacent:
+            generateDirectAdjacentTreeWalker(failureCases, fragment);
+            break;
+        case FragmentRelation::IndirectAdjacent:
+            generateIndirectAdjacentTreeWalker(failureCases, fragment);
+            break;
+        }
+        generateBacktrackingTailsIfNeeded(fragment);
+    }
+
+    m_registerAllocator.deallocateRegister(elementAddressRegister);
+
+    if (m_functionType == FunctionType::SimpleSelectorChecker) {
+        // Success.
+        m_assembler.move(Assembler::TrustedImm32(1), returnRegister);
+        m_assembler.ret();
+
+        // Failure.
+        if (!failureCases.empty()) {
+            failureCases.link(&amp;m_assembler);
+            m_assembler.move(Assembler::TrustedImm32(0), returnRegister);
+            m_assembler.ret();
+        }
+    } else {
+        ASSERT(m_functionType == FunctionType::SelectorCheckerWithCheckingContext);
+
+        // Success.
+        m_assembler.move(Assembler::TrustedImm32(1), returnRegister);
+
+        StackAllocator successStack = m_stackAllocator;
+        StackAllocator failureStack = m_stackAllocator;
+
+        LocalRegister checkingContextRegister(m_registerAllocator);
+        successStack.pop(m_checkingContextStackReference, checkingContextRegister);
+
+        // Failure.
+        if (!failureCases.empty()) {
+            Assembler::Jump jumpToReturn = m_assembler.jump();
+
+            failureCases.link(&amp;m_assembler);
+            failureStack.discard();
+            m_assembler.move(Assembler::TrustedImm32(0), returnRegister);
+
+            jumpToReturn.link(&amp;m_assembler);
+        }
+
+        m_stackAllocator.merge(std::move(successStack), std::move(failureStack));
+
+        m_assembler.ret();
+    }
+
+    JSC::LinkBuffer linkBuffer(*vm, &amp;m_assembler, CSS_CODE_ID);
+    for (unsigned i = 0; i &lt; m_functionCalls.size(); i++)
+        linkBuffer.link(m_functionCalls[i].first, m_functionCalls[i].second);
+
+#if CSS_SELECTOR_JIT_DEBUGGING &amp;&amp; ASSERT_DISABLED
+    codeRef = linkBuffer.finalizeCodeWithDisassembly(&quot;CSS Selector JIT for \&quot;%s\&quot;&quot;, m_originalSelector-&gt;selectorText().utf8().data());
+#else
+    codeRef = FINALIZE_CODE(linkBuffer, (&quot;CSS Selector JIT&quot;));
+#endif
+
+    if (m_functionType == FunctionType::SimpleSelectorChecker)
+        return SelectorCompilationStatus::SimpleSelectorChecker;
+    return SelectorCompilationStatus::SelectorCheckerWithCheckingContext;
+}
+
+
+static inline void updateChainStates(const SelectorFragment&amp; fragment, bool&amp; hasDescendantRelationOnTheRight, unsigned&amp; ancestorPositionSinceDescendantRelation, bool&amp; hasIndirectAdjacentRelationOnTheRightOfDirectAdjacentChain, unsigned&amp; adjacentPositionSinceIndirectAdjacentTreeWalk)
+{
+    switch (fragment.relationToRightFragment) {
+    case FragmentRelation::Rightmost:
+        break;
+    case FragmentRelation::Descendant:
+        hasDescendantRelationOnTheRight = true;
+        ancestorPositionSinceDescendantRelation = 0;
+        hasIndirectAdjacentRelationOnTheRightOfDirectAdjacentChain = false;
+        break;
+    case FragmentRelation::Child:
+        ++ancestorPositionSinceDescendantRelation;
+        hasIndirectAdjacentRelationOnTheRightOfDirectAdjacentChain = false;
+        break;
+    case FragmentRelation::DirectAdjacent:
+        if (hasIndirectAdjacentRelationOnTheRightOfDirectAdjacentChain)
+            ++adjacentPositionSinceIndirectAdjacentTreeWalk;
+        break;
+    case FragmentRelation::IndirectAdjacent:
+        hasIndirectAdjacentRelationOnTheRightOfDirectAdjacentChain = true;
+        break;
+    }
+}
+
+static inline bool isFirstAncestor(unsigned ancestorPositionSinceDescendantRelation)
+{
+    return ancestorPositionSinceDescendantRelation == 1;
+}
+
+static inline bool isFirstAdjacent(unsigned ancestorPositionSinceDescendantRelation)
+{
+    return ancestorPositionSinceDescendantRelation == 1;
+}
+
+static inline bool isAfterChildRelation(unsigned ancestorPositionSinceDescendantRelation)
+{
+    return ancestorPositionSinceDescendantRelation &gt; 0;
+}
+
+static inline void solveBacktrackingAction(SelectorFragment&amp; fragment, bool hasDescendantRelationOnTheRight, unsigned ancestorPositionSinceDescendantRelation, bool hasIndirectAdjacentRelationOnTheRightOfDirectAdjacentChain, unsigned adjacentPositionSinceIndirectAdjacentTreeWalk)
+{
+    switch (fragment.relationToRightFragment) {
+    case FragmentRelation::Rightmost:
+    case FragmentRelation::Descendant:
+        break;
+    case FragmentRelation::Child:
+        // Failure to match the element should resume matching at the nearest ancestor/descendant entry point.
+        if (hasDescendantRelationOnTheRight) {
+            if (isFirstAncestor(ancestorPositionSinceDescendantRelation))
+                fragment.matchingBacktrackingAction = BacktrackingAction::JumpToDescendantEntryPoint;
+            else
+                fragment.matchingBacktrackingAction = BacktrackingAction::JumpToDescendantTail;
+        }
+        break;
+    case FragmentRelation::DirectAdjacent:
+        // Failure on traversal implies no other sibling traversal can match. Matching should resume at the
+        // nearest ancestor/descendant traversal.
+        if (hasDescendantRelationOnTheRight) {
+            if (!isAfterChildRelation(ancestorPositionSinceDescendantRelation))
+                fragment.traversalBacktrackingAction = BacktrackingAction::JumpToDescendantTreeWalkerEntryPoint;
+            else {
+                if (!hasIndirectAdjacentRelationOnTheRightOfDirectAdjacentChain || isFirstAdjacent(adjacentPositionSinceIndirectAdjacentTreeWalk))
+                    fragment.traversalBacktrackingAction = BacktrackingAction::JumpToDescendantTail;
+                else
+                    fragment.traversalBacktrackingAction = BacktrackingAction::JumpToClearAdjacentDescendantTail;
+            }
+        }
+
+        // If the rightmost relation is a indirect adjacent, matching sould resume from there.
+        // Otherwise, we resume from the latest ancestor/descendant if any.
+        if (hasIndirectAdjacentRelationOnTheRightOfDirectAdjacentChain) {
+            if (isFirstAdjacent(adjacentPositionSinceIndirectAdjacentTreeWalk))
+                fragment.matchingBacktrackingAction = BacktrackingAction::JumpToIndirectAdjacentEntryPoint;
+            else
+                fragment.matchingBacktrackingAction = BacktrackingAction::JumpToDirectAdjacentTail;
+        } else if (hasDescendantRelationOnTheRight) {
+            if (isAfterChildRelation(ancestorPositionSinceDescendantRelation))
+                fragment.matchingBacktrackingAction = BacktrackingAction::JumpToDescendantTail;
+            else if (hasDescendantRelationOnTheRight)
+                fragment.matchingBacktrackingAction = BacktrackingAction::JumpToDescendantTreeWalkerEntryPoint;
+        }
+        break;
+    case FragmentRelation::IndirectAdjacent:
+        // Failure on traversal implies no other sibling matching will succeed. Matching can resume
+        // from the latest ancestor/descendant.
+        if (hasDescendantRelationOnTheRight) {
+            if (isAfterChildRelation(ancestorPositionSinceDescendantRelation))
+                fragment.traversalBacktrackingAction = BacktrackingAction::JumpToDescendantTail;
+            else
+                fragment.traversalBacktrackingAction = BacktrackingAction::JumpToDescendantTreeWalkerEntryPoint;
+        }
+        break;
+    }
+}
+
+static bool requiresAdjacentTail(const SelectorFragment&amp; fragment)
+{
+    ASSERT(fragment.traversalBacktrackingAction != BacktrackingAction::JumpToDirectAdjacentTail);
+    return fragment.matchingBacktrackingAction == BacktrackingAction::JumpToDirectAdjacentTail;
+}
+
+static bool requiresDescendantTail(const SelectorFragment&amp; fragment)
+{
+    return fragment.matchingBacktrackingAction == BacktrackingAction::JumpToDescendantTail || fragment.traversalBacktrackingAction == BacktrackingAction::JumpToDescendantTail;
+}
+
+void SelectorCodeGenerator::computeBacktrackingInformation()
+{
+    bool hasDescendantRelationOnTheRight = false;
+    unsigned ancestorPositionSinceDescendantRelation = 0;
+    bool hasIndirectAdjacentRelationOnTheRightOfDirectAdjacentChain = false;
+    unsigned adjacentPositionSinceIndirectAdjacentTreeWalk = 0;
+
+    bool needsAdjacentTail = false;
+    bool needsDescendantTail = false;
+
+    for (unsigned i = 0; i &lt; m_selectorFragments.size(); ++i) {
+        SelectorFragment&amp; fragment = m_selectorFragments[i];
+
+        updateChainStates(fragment, hasDescendantRelationOnTheRight, ancestorPositionSinceDescendantRelation, hasIndirectAdjacentRelationOnTheRightOfDirectAdjacentChain, adjacentPositionSinceIndirectAdjacentTreeWalk);
+
+        solveBacktrackingAction(fragment, hasDescendantRelationOnTheRight, ancestorPositionSinceDescendantRelation, hasIndirectAdjacentRelationOnTheRightOfDirectAdjacentChain, adjacentPositionSinceIndirectAdjacentTreeWalk);
+
+        needsAdjacentTail |= requiresAdjacentTail(fragment);
+        needsDescendantTail |= requiresDescendantTail(fragment);
+
+        // Add code generation flags.
+        if (fragment.relationToLeftFragment != FragmentRelation::Descendant &amp;&amp; fragment.relationToRightFragment == FragmentRelation::Descendant)
+            fragment.backtrackingFlags |= BacktrackingFlag::DescendantEntryPoint;
+        if (fragment.relationToLeftFragment == FragmentRelation::DirectAdjacent &amp;&amp; fragment.relationToRightFragment == FragmentRelation::IndirectAdjacent)
+            fragment.backtrackingFlags |= BacktrackingFlag::IndirectAdjacentEntryPoint;
+        if (fragment.relationToLeftFragment != FragmentRelation::Descendant &amp;&amp; fragment.relationToRightFragment == FragmentRelation::Child &amp;&amp; isFirstAncestor(ancestorPositionSinceDescendantRelation))
+            fragment.backtrackingFlags |= BacktrackingFlag::SaveDescendantBacktrackingStart;
+        if (fragment.relationToLeftFragment == FragmentRelation::DirectAdjacent &amp;&amp; fragment.relationToRightFragment == FragmentRelation::DirectAdjacent &amp;&amp; isFirstAdjacent(adjacentPositionSinceIndirectAdjacentTreeWalk))
+            fragment.backtrackingFlags |= BacktrackingFlag::SaveAdjacentBacktrackingStart;
+        if (fragment.relationToLeftFragment != FragmentRelation::DirectAdjacent &amp;&amp; needsAdjacentTail) {
+            ASSERT(fragment.relationToRightFragment == FragmentRelation::DirectAdjacent);
+            fragment.backtrackingFlags |= BacktrackingFlag::DirectAdjacentTail;
+            needsAdjacentTail = false;
+        }
+        if (fragment.relationToLeftFragment == FragmentRelation::Descendant &amp;&amp; needsDescendantTail) {
+            fragment.backtrackingFlags |= BacktrackingFlag::DescendantTail;
+            needsDescendantTail = false;
+        }
+    }
+}
+
+static inline Assembler::Jump testIsElementFlagOnNode(Assembler::ResultCondition condition, Assembler&amp; assembler, Assembler::RegisterID nodeAddress)
+{
+    return assembler.branchTest32(condition, Assembler::Address(nodeAddress, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagIsElement()));
+}
+
+void SelectorCodeGenerator::generateWalkToParentElement(Assembler::JumpList&amp; failureCases, Assembler::RegisterID targetRegister)
+{
+    //    ContainerNode* parent = parentNode()
+    //    if (!parent || !parent-&gt;isElementNode())
+    //         failure
+    m_assembler.loadPtr(Assembler::Address(elementAddressRegister, Node::parentNodeMemoryOffset()), targetRegister);
+    failureCases.append(m_assembler.branchTestPtr(Assembler::Zero, targetRegister));
+    failureCases.append(testIsElementFlagOnNode(Assembler::Zero, m_assembler, targetRegister));
+}
+
+void SelectorCodeGenerator::generateParentElementTreeWalker(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp; fragment)
+{
+    Assembler::JumpList traversalFailureCases;
+    generateWalkToParentElement(traversalFailureCases, elementAddressRegister);
+    linkFailures(failureCases, fragment.traversalBacktrackingAction, traversalFailureCases);
+
+    Assembler::JumpList matchingFailureCases;
+    generateElementMatching(matchingFailureCases, fragment);
+    linkFailures(failureCases, fragment.matchingBacktrackingAction, matchingFailureCases);
+
+    if (fragment.backtrackingFlags &amp; BacktrackingFlag::SaveDescendantBacktrackingStart) {
+        m_descendantBacktrackingStart = m_registerAllocator.allocateRegister();
+        m_assembler.move(elementAddressRegister, m_descendantBacktrackingStart);
+    }
+}
+
+void SelectorCodeGenerator::generateAncestorTreeWalker(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp; fragment)
+{
+    // Loop over the ancestors until one of them matches the fragment.
+    Assembler::Label loopStart(m_assembler.label());
+
+    if (fragment.backtrackingFlags &amp; BacktrackingFlag::DescendantEntryPoint)
+        m_descendantTreeWalkerBacktrackingPoint = m_assembler.label();
+
+    generateWalkToParentElement(failureCases, elementAddressRegister);
+
+    if (fragment.backtrackingFlags &amp; BacktrackingFlag::DescendantEntryPoint)
+        m_descendantEntryPoint = m_assembler.label();
+
+    Assembler::JumpList tagMatchingLocalFailureCases;
+    generateElementMatching(tagMatchingLocalFailureCases, fragment);
+    tagMatchingLocalFailureCases.linkTo(loopStart, &amp;m_assembler);
+}
+
+void SelectorCodeGenerator::generateWalkToPreviousAdjacent(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp; fragment)
+{
+    //    do {
+    //        previousSibling = previousSibling-&gt;previousSibling();
+    //        if (!previousSibling)
+    //            failure!
+    //    while (!previousSibling-&gt;isElement());
+    Assembler::RegisterID previousSibling;
+    bool useTailOnTraversalFailure = fragment.traversalBacktrackingAction &gt;= BacktrackingAction::JumpToDescendantTail;
+    if (!useTailOnTraversalFailure) {
+        // If the current fragment is not dependant on a previously saved elementAddressRegister, a fast recover
+        // from a failure would resume with elementAddressRegister.
+        // When walking to the previous sibling, the failure can be that previousSibling is null. We cannot backtrack
+        // with a null elementAddressRegister so we do the traversal on a copy.
+        previousSibling = m_registerAllocator.allocateRegister();
+        m_assembler.move(elementAddressRegister, previousSibling);
+    } else
+        previousSibling = elementAddressRegister;
+
+    Assembler::Label loopStart = m_assembler.label();
+    m_assembler.loadPtr(Assembler::Address(previousSibling, Node::previousSiblingMemoryOffset()), previousSibling);
+    failureCases.append(m_assembler.branchTestPtr(Assembler::Zero, previousSibling));
+    testIsElementFlagOnNode(Assembler::Zero, m_assembler, previousSibling).linkTo(loopStart, &amp;m_assembler);
+
+    // On success, move previousSibling over to elementAddressRegister if we could not work on elementAddressRegister directly.
+    if (!useTailOnTraversalFailure) {
+        m_assembler.move(previousSibling, elementAddressRegister);
+        m_registerAllocator.deallocateRegister(previousSibling);
+    }
+}
+
+void SelectorCodeGenerator::generateDirectAdjacentTreeWalker(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp; fragment)
+{
+    markParentElementIfResolvingStyle(Element::setChildrenAffectedByDirectAdjacentRules);
+
+    Assembler::JumpList traversalFailureCases;
+    generateWalkToPreviousAdjacent(traversalFailureCases, fragment);
+    linkFailures(failureCases, fragment.traversalBacktrackingAction, traversalFailureCases);
+
+    Assembler::JumpList matchingFailureCases;
+    generateElementMatching(matchingFailureCases, fragment);
+    linkFailures(failureCases, fragment.matchingBacktrackingAction, matchingFailureCases);
+
+    if (fragment.backtrackingFlags &amp; BacktrackingFlag::SaveAdjacentBacktrackingStart)
+        m_adjacentBacktrackingStart = m_stackAllocator.push(elementAddressRegister);
+}
+
+void SelectorCodeGenerator::generateIndirectAdjacentTreeWalker(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp; fragment)
+{
+    markParentElementIfResolvingStyle(Element::setChildrenAffectedByForwardPositionalRules);
+
+    Assembler::Label loopStart(m_assembler.label());
+
+    Assembler::JumpList traversalFailureCases;
+    generateWalkToPreviousAdjacent(traversalFailureCases, fragment);
+    linkFailures(failureCases, fragment.traversalBacktrackingAction, traversalFailureCases);
+
+    if (fragment.backtrackingFlags &amp; BacktrackingFlag::IndirectAdjacentEntryPoint)
+        m_indirectAdjacentEntryPoint = m_assembler.label();
+
+    Assembler::JumpList localFailureCases;
+    generateElementMatching(localFailureCases, fragment);
+    localFailureCases.linkTo(loopStart, &amp;m_assembler);
+}
+
+void SelectorCodeGenerator::markParentElementIfResolvingStyle(JSC::FunctionPtr markingFunction)
+{
+    //     if (checkingContext.resolvingMode == ResolvingStyle) {
+    //         Element* parent = element-&gt;parentNode();
+    //         markingFunction(parent);
+    //     }
+    Assembler::JumpList failedToGetParent;
+    Assembler::Jump notResolvingStyle;
+    {
+        // Get the checking context.
+        unsigned offsetToCheckingContext = m_stackAllocator.offsetToStackReference(m_checkingContextStackReference);
+        LocalRegister checkingContext(m_registerAllocator);
+        m_assembler.loadPtr(Assembler::Address(Assembler::stackPointerRegister, offsetToCheckingContext), checkingContext);
+
+        // If we not resolving style, skip the whole marking.
+        notResolvingStyle = m_assembler.branch8(Assembler::NotEqual, Assembler::Address(checkingContext, OBJECT_OFFSETOF(CheckingContext, resolvingMode)), Assembler::TrustedImm32(SelectorChecker::ResolvingStyle));
+    }
+
+    // Get the parent element in a temporary register.
+    Assembler::RegisterID parentElement = m_registerAllocator.allocateRegister();
+    generateWalkToParentElement(failedToGetParent, parentElement);
+
+    // Return the register parentElement just before the function call since we don't need it to be preserved
+    // on the stack.
+    m_registerAllocator.deallocateRegister(parentElement);
+
+    // Invoke the marking function on the parent element.
+    FunctionCall functionCall(m_assembler, m_registerAllocator, m_stackAllocator, m_functionCalls);
+    functionCall.setFunctionAddress(markingFunction);
+    functionCall.setFirstArgument(parentElement);
+    functionCall.call();
+
+    notResolvingStyle.link(&amp;m_assembler);
+    failedToGetParent.link(&amp;m_assembler);
+}
+
+
+void SelectorCodeGenerator::linkFailures(Assembler::JumpList&amp; globalFailureCases, BacktrackingAction backtrackingAction, Assembler::JumpList&amp; localFailureCases)
+{
+    switch (backtrackingAction) {
+    case BacktrackingAction::NoBacktracking:
+        globalFailureCases.append(localFailureCases);
+        break;
+    case BacktrackingAction::JumpToDescendantEntryPoint:
+        localFailureCases.linkTo(m_descendantEntryPoint, &amp;m_assembler);
+        break;
+    case BacktrackingAction::JumpToDescendantTreeWalkerEntryPoint:
+        localFailureCases.linkTo(m_descendantTreeWalkerBacktrackingPoint, &amp;m_assembler);
+        break;
+    case BacktrackingAction::JumpToDescendantTail:
+        m_descendantBacktrackingFailureCases.append(localFailureCases);
+        break;
+    case BacktrackingAction::JumpToIndirectAdjacentEntryPoint:
+        localFailureCases.linkTo(m_indirectAdjacentEntryPoint, &amp;m_assembler);
+        break;
+    case BacktrackingAction::JumpToDirectAdjacentTail:
+        m_adjacentBacktrackingFailureCases.append(localFailureCases);
+        break;
+    case BacktrackingAction::JumpToClearAdjacentDescendantTail:
+        m_clearAdjacentEntryPointDescendantFailureCases.append(localFailureCases);
+        break;
+    }
+}
+
+void SelectorCodeGenerator::generateAdjacentBacktrackingTail(StackAllocator&amp; adjacentTailStack)
+{
+    m_adjacentBacktrackingFailureCases.link(&amp;m_assembler);
+    m_adjacentBacktrackingFailureCases.clear();
+    adjacentTailStack.pop(m_adjacentBacktrackingStart, elementAddressRegister);
+    m_assembler.jump(m_indirectAdjacentEntryPoint);
+}
+
+void SelectorCodeGenerator::generateDescendantBacktrackingTail()
+{
+    m_descendantBacktrackingFailureCases.link(&amp;m_assembler);
+    m_descendantBacktrackingFailureCases.clear();
+    m_assembler.move(m_descendantBacktrackingStart, elementAddressRegister);
+    m_registerAllocator.deallocateRegister(m_descendantBacktrackingStart);
+    m_assembler.jump(m_descendantEntryPoint);
+}
+
+void SelectorCodeGenerator::generateBacktrackingTailsIfNeeded(const SelectorFragment&amp; fragment)
+{
+    if (fragment.backtrackingFlags &amp; BacktrackingFlag::DirectAdjacentTail &amp;&amp; fragment.backtrackingFlags &amp; BacktrackingFlag::DescendantTail) {
+        StackAllocator successStack = m_stackAllocator;
+        StackAllocator adjacentTailStack = m_stackAllocator;
+        StackAllocator descendantTailStack = m_stackAllocator;
+
+        successStack.popAndDiscard(m_adjacentBacktrackingStart);
+
+        Assembler::Jump normalCase = m_assembler.jump();
+
+        generateAdjacentBacktrackingTail(adjacentTailStack);
+
+        m_clearAdjacentEntryPointDescendantFailureCases.link(&amp;m_assembler);
+        m_clearAdjacentEntryPointDescendantFailureCases.clear();
+        descendantTailStack.popAndDiscard(m_adjacentBacktrackingStart);
+
+        generateDescendantBacktrackingTail();
+
+        normalCase.link(&amp;m_assembler);
+
+        m_stackAllocator.merge(std::move(successStack), std::move(adjacentTailStack), std::move(descendantTailStack));
+    } else if (fragment.backtrackingFlags &amp; BacktrackingFlag::DirectAdjacentTail) {
+        StackAllocator successStack = m_stackAllocator;
+        StackAllocator adjacentTailStack = m_stackAllocator;
+
+        successStack.popAndDiscard(m_adjacentBacktrackingStart);
+
+        Assembler::Jump normalCase = m_assembler.jump();
+        generateAdjacentBacktrackingTail(adjacentTailStack);
+        normalCase.link(&amp;m_assembler);
+
+        m_stackAllocator.merge(std::move(successStack), std::move(adjacentTailStack));
+    } else if (fragment.backtrackingFlags &amp; BacktrackingFlag::DescendantTail) {
+        Assembler::Jump normalCase = m_assembler.jump();
+        generateDescendantBacktrackingTail();
+        normalCase.link(&amp;m_assembler);
+    }
+}
+
+void SelectorCodeGenerator::generateElementMatching(Assembler::JumpList&amp; failureCases, const SelectorFragment&amp; fragment)
+{
+    if (fragment.tagName)
+        generateElementHasTagName(failureCases, *(fragment.tagName));
+}
+
+inline void SelectorCodeGenerator::generateElementHasTagName(Assembler::JumpList&amp; failureCases, const QualifiedName&amp; nameToMatch)
+{
+    if (nameToMatch == anyQName())
+        return;
+
+    // Load the QualifiedNameImpl from the input.
+    LocalRegister qualifiedNameImpl(m_registerAllocator);
+    m_assembler.loadPtr(Assembler::Address(elementAddressRegister, Element::tagQNameMemoryOffset() + QualifiedName::implMemoryOffset()), qualifiedNameImpl);
+
+    const AtomicString&amp; selectorNamespaceURI = nameToMatch.namespaceURI();
+    if (selectorNamespaceURI != starAtom) {
+        // Generate namespaceURI == element-&gt;namespaceURI().
+        LocalRegister constantRegister(m_registerAllocator);
+        m_assembler.move(Assembler::TrustedImmPtr(selectorNamespaceURI.impl()), constantRegister);
+        failureCases.append(m_assembler.branchPtr(Assembler::NotEqual, Assembler::Address(qualifiedNameImpl, QualifiedName::QualifiedNameImpl::namespaceMemoryOffset()), constantRegister));
+    }
+
+    const AtomicString&amp; selectorLocalName = nameToMatch.localName();
+    if (selectorLocalName != starAtom) {
+        // Generate localName == element-&gt;localName().
+        LocalRegister constantRegister(m_registerAllocator);
+        m_assembler.move(Assembler::TrustedImmPtr(selectorLocalName.impl()), constantRegister);
+        failureCases.append(m_assembler.branchPtr(Assembler::NotEqual, Assembler::Address(qualifiedNameImpl, QualifiedName::QualifiedNameImpl::localNameMemoryOffset()), constantRegister));
+    }
+}
+
+}; // namespace SelectorCompiler.
+}; // namespace WebCore.
+
+#endif // ENABLE(CSS_SELECTOR_JIT)
</ins></span></pre></div>
<a id="trunkSourceWebCorecssjitSelectorCompilerh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/cssjit/SelectorCompiler.h (0 => 160983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/cssjit/SelectorCompiler.h                                (rev 0)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.h        2013-12-23 00:45:25 UTC (rev 160983)
</span><span class="lines">@@ -0,0 +1,96 @@
</span><ins>+/*
+ * Copyright (C) 2013 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SelectorCompiler_h
+#define SelectorCompiler_h
+
+#if ENABLE(CSS_SELECTOR_JIT)
+
+#include &quot;SelectorChecker.h&quot;
+
+namespace JSC {
+class MacroAssemblerCodeRef;
+class VM;
+}
+
+namespace WebCore {
+
+class CSSSelector;
+class Element;
+class RenderStyle;
+
+class SelectorCompilationStatus {
+public:
+    enum Status {
+        NotCompiled,
+        CannotCompile,
+        SimpleSelectorChecker,
+        SelectorCheckerWithCheckingContext
+    };
+
+    SelectorCompilationStatus()
+        : m_status(NotCompiled)
+    { }
+
+    SelectorCompilationStatus(Status status)
+        : m_status(status)
+    { }
+
+    operator Status() const { return m_status; }
+
+private:
+    Status m_status;
+};
+
+namespace SelectorCompiler {
+
+struct CheckingContext {
+    SelectorChecker::Mode resolvingMode;
+    RenderStyle* elementStyle;
+};
+
+typedef unsigned (*SimpleSelectorChecker)(Element*);
+typedef unsigned (*SelectorCheckerWithCheckingContext)(Element*, const CheckingContext*);
+SelectorCompilationStatus compileSelector(const CSSSelector*, JSC::VM*, JSC::MacroAssemblerCodeRef&amp; outputCodeRef);
+
+inline SimpleSelectorChecker simpleSelectorCheckerFunction(void* executableAddress, SelectorCompilationStatus compilationStatus)
+{
+    ASSERT_UNUSED(compilationStatus, compilationStatus == SelectorCompilationStatus::SimpleSelectorChecker);
+    return reinterpret_cast&lt;SimpleSelectorChecker&gt;(executableAddress);
+}
+
+inline SelectorCheckerWithCheckingContext selectorCheckerFunctionWithCheckingContext(void* executableAddress, SelectorCompilationStatus compilationStatus)
+{
+    ASSERT_UNUSED(compilationStatus, compilationStatus == SelectorCompilationStatus::SelectorCheckerWithCheckingContext);
+    return reinterpret_cast&lt;SelectorCheckerWithCheckingContext&gt;(executableAddress);
+}
+
+
+} // namespace SelectorCompiler
+} // namespace WebCore
+
+#endif // ENABLE(CSS_SELECTOR_JIT)
+
+#endif // SelectorCompiler_h
</ins></span></pre></div>
<a id="trunkSourceWebCoredomElementcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.cpp (160982 => 160983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.cpp        2013-12-23 00:02:40 UTC (rev 160982)
+++ trunk/Source/WebCore/dom/Element.cpp        2013-12-23 00:45:25 UTC (rev 160983)
</span><span class="lines">@@ -2177,11 +2177,16 @@
</span><span class="cx">         ensureElementRareData().setChildrenAffectedByDrag(value);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void Element::setChildrenAffectedByForwardPositionalRules()
</del><ins>+void Element::setChildrenAffectedByDirectAdjacentRules(Element* element)
</ins><span class="cx"> {
</span><del>-    ensureElementRareData().setChildrenAffectedByForwardPositionalRules(true);
</del><ins>+    element-&gt;setChildrenAffectedByDirectAdjacentRules();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void Element::setChildrenAffectedByForwardPositionalRules(Element* element)
+{
+    element-&gt;ensureElementRareData().setChildrenAffectedByForwardPositionalRules(true);
+}
+
</ins><span class="cx"> void Element::setChildrenAffectedByBackwardPositionalRules()
</span><span class="cx"> {
</span><span class="cx">     ensureElementRareData().setChildrenAffectedByBackwardPositionalRules(true);
</span></span></pre></div>
<a id="trunkSourceWebCoredomElementh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Element.h (160982 => 160983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Element.h        2013-12-23 00:02:40 UTC (rev 160982)
+++ trunk/Source/WebCore/dom/Element.h        2013-12-23 00:45:25 UTC (rev 160983)
</span><span class="lines">@@ -248,6 +248,9 @@
</span><span class="cx">     virtual CSSStyleDeclaration* style();
</span><span class="cx"> 
</span><span class="cx">     const QualifiedName&amp; tagQName() const { return m_tagName; }
</span><ins>+#if ENABLE(CSS_SELECTOR_JIT)
+    static ptrdiff_t tagQNameMemoryOffset() { return OBJECT_OFFSETOF(Element, m_tagName); }
+#endif // ENABLE(CSS_SELECTOR_JIT)
</ins><span class="cx">     String tagName() const { return nodeName(); }
</span><span class="cx">     bool hasTagName(const QualifiedName&amp; tagName) const { return m_tagName.matches(tagName); }
</span><span class="cx">     
</span><span class="lines">@@ -363,8 +366,10 @@
</span><span class="cx">     void setChildrenAffectedByDrag(bool);
</span><span class="cx">     void setChildrenAffectedByFirstChildRules() { setFlag(ChildrenAffectedByFirstChildRulesFlag); }
</span><span class="cx">     void setChildrenAffectedByLastChildRules() { setFlag(ChildrenAffectedByLastChildRulesFlag); }
</span><ins>+    static void setChildrenAffectedByDirectAdjacentRules(Element*);
</ins><span class="cx">     void setChildrenAffectedByDirectAdjacentRules() { setFlag(ChildrenAffectedByDirectAdjacentRulesFlag); }
</span><del>-    void setChildrenAffectedByForwardPositionalRules();
</del><ins>+    static void setChildrenAffectedByForwardPositionalRules(Element*);
+    void setChildrenAffectedByForwardPositionalRules() { setChildrenAffectedByForwardPositionalRules(this); }
</ins><span class="cx">     void setChildrenAffectedByBackwardPositionalRules();
</span><span class="cx">     void setChildIndex(unsigned);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoredomNodeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/Node.h (160982 => 160983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/Node.h        2013-12-23 00:02:40 UTC (rev 160982)
+++ trunk/Source/WebCore/dom/Node.h        2013-12-23 00:45:25 UTC (rev 160983)
</span><span class="lines">@@ -165,8 +165,10 @@
</span><span class="cx">     virtual void setNodeValue(const String&amp;, ExceptionCode&amp;);
</span><span class="cx">     virtual NodeType nodeType() const = 0;
</span><span class="cx">     ContainerNode* parentNode() const;
</span><ins>+    static ptrdiff_t parentNodeMemoryOffset() { return OBJECT_OFFSETOF(Node, m_parentNode); }
</ins><span class="cx">     Element* parentElement() const;
</span><span class="cx">     Node* previousSibling() const { return m_previous; }
</span><ins>+    static ptrdiff_t previousSiblingMemoryOffset() { return OBJECT_OFFSETOF(Node, m_previous); }
</ins><span class="cx">     Node* nextSibling() const { return m_next; }
</span><span class="cx">     PassRefPtr&lt;NodeList&gt; childNodes();
</span><span class="cx">     Node* firstChild() const;
</span><span class="lines">@@ -558,6 +560,11 @@
</span><span class="cx"> 
</span><span class="cx">     void markAncestorsWithChildNeedsStyleRecalc();
</span><span class="cx"> 
</span><ins>+#if ENABLE(CSS_SELECTOR_JIT)
+    static ptrdiff_t nodeFlagsMemoryOffset() { return OBJECT_OFFSETOF(Node, m_nodeFlags); }
+    static uint8_t flagIsElement() { return IsElementFlag; }
+#endif // ENABLE(CSS_SELECTOR_JIT)
+
</ins><span class="cx"> protected:
</span><span class="cx">     enum NodeFlags {
</span><span class="cx">         IsTextFlag = 1,
</span></span></pre></div>
<a id="trunkSourceWebCoredomQualifiedNameh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/dom/QualifiedName.h (160982 => 160983)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/dom/QualifiedName.h        2013-12-23 00:02:40 UTC (rev 160982)
+++ trunk/Source/WebCore/dom/QualifiedName.h        2013-12-23 00:45:25 UTC (rev 160983)
</span><span class="lines">@@ -54,6 +54,11 @@
</span><span class="cx">         const AtomicString m_namespace;
</span><span class="cx">         mutable AtomicString m_localNameUpper;
</span><span class="cx"> 
</span><ins>+#if ENABLE(CSS_SELECTOR_JIT)
+        static ptrdiff_t localNameMemoryOffset() { return OBJECT_OFFSETOF(QualifiedNameImpl, m_localName); }
+        static ptrdiff_t namespaceMemoryOffset() { return OBJECT_OFFSETOF(QualifiedNameImpl, m_namespace); }
+#endif // ENABLE(CSS_SELECTOR_JIT)
+
</ins><span class="cx">     private:
</span><span class="cx">         QualifiedNameImpl(const AtomicString&amp; prefix, const AtomicString&amp; localName, const AtomicString&amp; namespaceURI)
</span><span class="cx">             : m_existingHash(0)
</span><span class="lines">@@ -96,6 +101,9 @@
</span><span class="cx">     String toString() const;
</span><span class="cx"> 
</span><span class="cx">     QualifiedNameImpl* impl() const { return m_impl; }
</span><ins>+#if ENABLE(CSS_SELECTOR_JIT)
+    static ptrdiff_t implMemoryOffset() { return OBJECT_OFFSETOF(QualifiedName, m_impl); }
+#endif // ENABLE(CSS_SELECTOR_JIT)
</ins><span class="cx">     
</span><span class="cx">     // Init routine for globals
</span><span class="cx">     static void init();
</span></span></pre>
</div>
</div>

</body>
</html>