<!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>[197342] releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore</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/197342">197342</a></dd>
<dt>Author</dt> <dd>carlosgc@webkit.org</dd>
<dt>Date</dt> <dd>2016-02-29 03:30:47 -0800 (Mon, 29 Feb 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merge <a href="http://trac.webkit.org/projects/webkit/changeset/197299">r197299</a> - FTL should lower its abstract heaps to B3 heap ranges
https://bugs.webkit.org/show_bug.cgi?id=154782

Reviewed by Saam Barati.

The FTL can describe the abstract heaps (points-to sets) that a memory operation will
affect. The abstract heaps are arranged as a hierarchy. We used to transform this into
TBAA hierarchies in LLVM, but we never got around to wiring this up to B3's equivalent
notion - the HeapRange. That's what this patch fixes.

B3 has a minimalistic alias analysis. It represents abstract heaps using unsigned 32-bit
integers. There are 1&lt;&lt;32 abstract heaps. The B3 client can describe what an operation
affects by specifying a heap range: a begin...end pair that says that the operation
affects all abstract heaps H such that begin &lt;= H &lt; end.

This peculiar scheme was a deliberate attempt to distill what the abstract heap
hierarchy is all about. We can assign begin...end numbers to abstract heaps so that:

- A heap's end is greater than its begin.
- A heap's begin is greater than or equal to its parent's begin.
- A heap's end is less than or equal to its parent's end.

This is easy to do using a recursive traversal of the abstract heap hierarchy. I almost
went for the iterative traversal, which is a splendid algorithm, but it's totally
unnecessary here since we tightly control the height of the heap hierarchy.

Because abstract heaps are produced on-the-fly by FTL lowering, due to the fact that we
generate new ones for field names and constant indices we encounter, we can't actually
decorate the B3 instructions we create in lowering until all lowering is done. Adding a
new abstract heap to the hierarchy after ranges were already computed would require
updating the ranges of any heaps &quot;to the right&quot; of that heap in the hierarchy. This
patch solves that problem by recording the associations between abstract heaps and their
intended roles in the generated IR, and then decorating all of the relevant B3 values
after we compute the ranges of the hierarchy after lowering.

This is perf-neutral. I was hoping for a small speed-up, but I could not detect a
speed-up on any benchmark. That's not too surprising. We already have very precise CSE
in the DFG, so there aren't many opportunities left for the B3 CSE and it may have
already been getting the big ones even without alias analysis.

Even without a speed-up, this patch is valuable because it makes it easier to implement
other optimizations, like store elimination.

* b3/B3HeapRange.h:
(JSC::B3::HeapRange::HeapRange):
* ftl/FTLAbstractHeap.cpp:
(JSC::FTL::AbstractHeap::AbstractHeap):
(JSC::FTL::AbstractHeap::changeParent):
(JSC::FTL::AbstractHeap::compute):
(JSC::FTL::AbstractHeap::shallowDump):
(JSC::FTL::AbstractHeap::dump):
(JSC::FTL::AbstractHeap::deepDump):
(JSC::FTL::AbstractHeap::badRangeError):
(JSC::FTL::IndexedAbstractHeap::IndexedAbstractHeap):
(JSC::FTL::IndexedAbstractHeap::baseIndex):
(JSC::FTL::IndexedAbstractHeap::atSlow):
(JSC::FTL::IndexedAbstractHeap::initialize):
(JSC::FTL::AbstractHeap::decorateInstruction): Deleted.
(JSC::FTL::AbstractField::dump): Deleted.
* ftl/FTLAbstractHeap.h:
(JSC::FTL::AbstractHeap::AbstractHeap):
(JSC::FTL::AbstractHeap::isInitialized):
(JSC::FTL::AbstractHeap::initialize):
(JSC::FTL::AbstractHeap::parent):
(JSC::FTL::AbstractHeap::heapName):
(JSC::FTL::AbstractHeap::range):
(JSC::FTL::AbstractHeap::offset):
(JSC::FTL::IndexedAbstractHeap::atAnyIndex):
(JSC::FTL::IndexedAbstractHeap::at):
(JSC::FTL::IndexedAbstractHeap::operator[]):
(JSC::FTL::IndexedAbstractHeap::returnInitialized):
(JSC::FTL::IndexedAbstractHeap::WithoutZeroOrOneHashTraits::constructDeletedValue):
(JSC::FTL::IndexedAbstractHeap::WithoutZeroOrOneHashTraits::isDeletedValue):
(JSC::FTL::AbstractHeap::changeParent): Deleted.
(JSC::FTL::AbstractField::AbstractField): Deleted.
(JSC::FTL::AbstractField::initialize): Deleted.
(JSC::FTL::AbstractField::offset): Deleted.
* ftl/FTLAbstractHeapRepository.cpp:
(JSC::FTL::AbstractHeapRepository::AbstractHeapRepository):
(JSC::FTL::AbstractHeapRepository::~AbstractHeapRepository):
(JSC::FTL::AbstractHeapRepository::decorateMemory):
(JSC::FTL::AbstractHeapRepository::decorateCCallRead):
(JSC::FTL::AbstractHeapRepository::decorateCCallWrite):
(JSC::FTL::AbstractHeapRepository::decoratePatchpointRead):
(JSC::FTL::AbstractHeapRepository::decoratePatchpointWrite):
(JSC::FTL::AbstractHeapRepository::computeRangesAndDecorateInstructions):
* ftl/FTLAbstractHeapRepository.h:
(JSC::FTL::AbstractHeapRepository::forArrayType):
(JSC::FTL::AbstractHeapRepository::HeapForValue::HeapForValue):
* ftl/FTLLowerDFGToB3.cpp:
(JSC::FTL::DFG::LowerDFGToB3::lower):
* ftl/FTLOutput.cpp:
(JSC::FTL::Output::load):
(JSC::FTL::Output::load8SignExt32):
(JSC::FTL::Output::load8ZeroExt32):
(JSC::FTL::Output::load16SignExt32):
(JSC::FTL::Output::load16ZeroExt32):
(JSC::FTL::Output::store):
(JSC::FTL::Output::store32As8):
(JSC::FTL::Output::store32As16):
(JSC::FTL::Output::baseIndex):
* ftl/FTLOutput.h:
(JSC::FTL::Output::address):
(JSC::FTL::Output::absolute):
(JSC::FTL::Output::load8SignExt32):
(JSC::FTL::Output::load8ZeroExt32):
(JSC::FTL::Output::load16SignExt32):
(JSC::FTL::Output::load16ZeroExt32):
(JSC::FTL::Output::load32):
(JSC::FTL::Output::load64):
(JSC::FTL::Output::loadPtr):
(JSC::FTL::Output::loadDouble):
(JSC::FTL::Output::store32):
(JSC::FTL::Output::store64):
(JSC::FTL::Output::storePtr):
(JSC::FTL::Output::storeDouble):
(JSC::FTL::Output::ascribeRange):
(JSC::FTL::Output::nonNegative32):
(JSC::FTL::Output::load32NonNegative):
(JSC::FTL::Output::equal):
(JSC::FTL::Output::notEqual):
* ftl/FTLTypedPointer.h:
(JSC::FTL::TypedPointer::operator!):
(JSC::FTL::TypedPointer::heap):
(JSC::FTL::TypedPointer::value):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreChangeLog">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3HeapRangeh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3HeapRange.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLAbstractHeapcpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeap.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLAbstractHeaph">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeap.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLAbstractHeapRepositorycpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLAbstractHeapRepositoryh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLLowerDFGToB3cpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLOutputcpp">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLOutput.cpp</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLOutputh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLOutput.h</a></li>
<li><a href="#releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLTypedPointerh">releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLTypedPointer.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ChangeLog (197341 => 197342)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ChangeLog        2016-02-29 11:21:28 UTC (rev 197341)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ChangeLog        2016-02-29 11:30:47 UTC (rev 197342)
</span><span class="lines">@@ -1,3 +1,131 @@
</span><ins>+2016-02-27  Filip Pizlo  &lt;fpizlo@apple.com&gt;
+
+        FTL should lower its abstract heaps to B3 heap ranges
+        https://bugs.webkit.org/show_bug.cgi?id=154782
+
+        Reviewed by Saam Barati.
+
+        The FTL can describe the abstract heaps (points-to sets) that a memory operation will
+        affect. The abstract heaps are arranged as a hierarchy. We used to transform this into
+        TBAA hierarchies in LLVM, but we never got around to wiring this up to B3's equivalent
+        notion - the HeapRange. That's what this patch fixes.
+
+        B3 has a minimalistic alias analysis. It represents abstract heaps using unsigned 32-bit
+        integers. There are 1&lt;&lt;32 abstract heaps. The B3 client can describe what an operation
+        affects by specifying a heap range: a begin...end pair that says that the operation
+        affects all abstract heaps H such that begin &lt;= H &lt; end.
+
+        This peculiar scheme was a deliberate attempt to distill what the abstract heap
+        hierarchy is all about. We can assign begin...end numbers to abstract heaps so that:
+
+        - A heap's end is greater than its begin.
+        - A heap's begin is greater than or equal to its parent's begin.
+        - A heap's end is less than or equal to its parent's end.
+
+        This is easy to do using a recursive traversal of the abstract heap hierarchy. I almost
+        went for the iterative traversal, which is a splendid algorithm, but it's totally
+        unnecessary here since we tightly control the height of the heap hierarchy.
+
+        Because abstract heaps are produced on-the-fly by FTL lowering, due to the fact that we
+        generate new ones for field names and constant indices we encounter, we can't actually
+        decorate the B3 instructions we create in lowering until all lowering is done. Adding a
+        new abstract heap to the hierarchy after ranges were already computed would require
+        updating the ranges of any heaps &quot;to the right&quot; of that heap in the hierarchy. This
+        patch solves that problem by recording the associations between abstract heaps and their
+        intended roles in the generated IR, and then decorating all of the relevant B3 values
+        after we compute the ranges of the hierarchy after lowering.
+
+        This is perf-neutral. I was hoping for a small speed-up, but I could not detect a
+        speed-up on any benchmark. That's not too surprising. We already have very precise CSE
+        in the DFG, so there aren't many opportunities left for the B3 CSE and it may have
+        already been getting the big ones even without alias analysis.
+
+        Even without a speed-up, this patch is valuable because it makes it easier to implement
+        other optimizations, like store elimination.
+
+        * b3/B3HeapRange.h:
+        (JSC::B3::HeapRange::HeapRange):
+        * ftl/FTLAbstractHeap.cpp:
+        (JSC::FTL::AbstractHeap::AbstractHeap):
+        (JSC::FTL::AbstractHeap::changeParent):
+        (JSC::FTL::AbstractHeap::compute):
+        (JSC::FTL::AbstractHeap::shallowDump):
+        (JSC::FTL::AbstractHeap::dump):
+        (JSC::FTL::AbstractHeap::deepDump):
+        (JSC::FTL::AbstractHeap::badRangeError):
+        (JSC::FTL::IndexedAbstractHeap::IndexedAbstractHeap):
+        (JSC::FTL::IndexedAbstractHeap::baseIndex):
+        (JSC::FTL::IndexedAbstractHeap::atSlow):
+        (JSC::FTL::IndexedAbstractHeap::initialize):
+        (JSC::FTL::AbstractHeap::decorateInstruction): Deleted.
+        (JSC::FTL::AbstractField::dump): Deleted.
+        * ftl/FTLAbstractHeap.h:
+        (JSC::FTL::AbstractHeap::AbstractHeap):
+        (JSC::FTL::AbstractHeap::isInitialized):
+        (JSC::FTL::AbstractHeap::initialize):
+        (JSC::FTL::AbstractHeap::parent):
+        (JSC::FTL::AbstractHeap::heapName):
+        (JSC::FTL::AbstractHeap::range):
+        (JSC::FTL::AbstractHeap::offset):
+        (JSC::FTL::IndexedAbstractHeap::atAnyIndex):
+        (JSC::FTL::IndexedAbstractHeap::at):
+        (JSC::FTL::IndexedAbstractHeap::operator[]):
+        (JSC::FTL::IndexedAbstractHeap::returnInitialized):
+        (JSC::FTL::IndexedAbstractHeap::WithoutZeroOrOneHashTraits::constructDeletedValue):
+        (JSC::FTL::IndexedAbstractHeap::WithoutZeroOrOneHashTraits::isDeletedValue):
+        (JSC::FTL::AbstractHeap::changeParent): Deleted.
+        (JSC::FTL::AbstractField::AbstractField): Deleted.
+        (JSC::FTL::AbstractField::initialize): Deleted.
+        (JSC::FTL::AbstractField::offset): Deleted.
+        * ftl/FTLAbstractHeapRepository.cpp:
+        (JSC::FTL::AbstractHeapRepository::AbstractHeapRepository):
+        (JSC::FTL::AbstractHeapRepository::~AbstractHeapRepository):
+        (JSC::FTL::AbstractHeapRepository::decorateMemory):
+        (JSC::FTL::AbstractHeapRepository::decorateCCallRead):
+        (JSC::FTL::AbstractHeapRepository::decorateCCallWrite):
+        (JSC::FTL::AbstractHeapRepository::decoratePatchpointRead):
+        (JSC::FTL::AbstractHeapRepository::decoratePatchpointWrite):
+        (JSC::FTL::AbstractHeapRepository::computeRangesAndDecorateInstructions):
+        * ftl/FTLAbstractHeapRepository.h:
+        (JSC::FTL::AbstractHeapRepository::forArrayType):
+        (JSC::FTL::AbstractHeapRepository::HeapForValue::HeapForValue):
+        * ftl/FTLLowerDFGToB3.cpp:
+        (JSC::FTL::DFG::LowerDFGToB3::lower):
+        * ftl/FTLOutput.cpp:
+        (JSC::FTL::Output::load):
+        (JSC::FTL::Output::load8SignExt32):
+        (JSC::FTL::Output::load8ZeroExt32):
+        (JSC::FTL::Output::load16SignExt32):
+        (JSC::FTL::Output::load16ZeroExt32):
+        (JSC::FTL::Output::store):
+        (JSC::FTL::Output::store32As8):
+        (JSC::FTL::Output::store32As16):
+        (JSC::FTL::Output::baseIndex):
+        * ftl/FTLOutput.h:
+        (JSC::FTL::Output::address):
+        (JSC::FTL::Output::absolute):
+        (JSC::FTL::Output::load8SignExt32):
+        (JSC::FTL::Output::load8ZeroExt32):
+        (JSC::FTL::Output::load16SignExt32):
+        (JSC::FTL::Output::load16ZeroExt32):
+        (JSC::FTL::Output::load32):
+        (JSC::FTL::Output::load64):
+        (JSC::FTL::Output::loadPtr):
+        (JSC::FTL::Output::loadDouble):
+        (JSC::FTL::Output::store32):
+        (JSC::FTL::Output::store64):
+        (JSC::FTL::Output::storePtr):
+        (JSC::FTL::Output::storeDouble):
+        (JSC::FTL::Output::ascribeRange):
+        (JSC::FTL::Output::nonNegative32):
+        (JSC::FTL::Output::load32NonNegative):
+        (JSC::FTL::Output::equal):
+        (JSC::FTL::Output::notEqual):
+        * ftl/FTLTypedPointer.h:
+        (JSC::FTL::TypedPointer::operator!):
+        (JSC::FTL::TypedPointer::heap):
+        (JSC::FTL::TypedPointer::value):
+
</ins><span class="cx"> 2016-02-27  Oliver Hunt  &lt;oliver@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         CLoop build fix.
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreb3B3HeapRangeh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3HeapRange.h (197341 => 197342)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3HeapRange.h        2016-02-29 11:21:28 UTC (rev 197341)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/b3/B3HeapRange.h        2016-02-29 11:30:47 UTC (rev 197342)
</span><span class="lines">@@ -37,6 +37,12 @@
</span><span class="cx"> // Alias analysis in B3 is done by checking if two integer ranges overlap. This is powerful enough
</span><span class="cx"> // to be used for TBAA-style alias analysis used by the DFG, FTL, and LLVM: you just turn each node
</span><span class="cx"> // in the tree of abstract heaps into a pre/post range.
</span><ins>+//
+// Note that the 'begin' is inclusive, while the 'end' is exclusive. These two ranges are non-
+// overlapping:
+//
+//     rangeA = 0...8
+//     rangeB = 8...16
</ins><span class="cx"> 
</span><span class="cx"> class HeapRange {
</span><span class="cx"> public:
</span><span class="lines">@@ -48,6 +54,13 @@
</span><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    explicit HeapRange(unsigned value)
+        : m_begin(value)
+        , m_end(value + 1)
+    {
+        ASSERT(m_end &gt;= m_begin);
+    }
+
</ins><span class="cx">     HeapRange(unsigned begin, unsigned end)
</span><span class="cx">         : m_begin(begin)
</span><span class="cx">         , m_end(end)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLAbstractHeapcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeap.cpp (197341 => 197342)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeap.cpp        2016-02-29 11:21:28 UTC (rev 197341)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeap.cpp        2016-02-29 11:30:47 UTC (rev 197342)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -38,26 +38,98 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx"> 
</span><del>-void AbstractHeap::decorateInstruction(LValue instruction, const AbstractHeapRepository&amp; repository) const
</del><ins>+using namespace B3;
+
+AbstractHeap::AbstractHeap(AbstractHeap* parent, const char* heapName, ptrdiff_t offset)
+    : m_offset(offset)
+    , m_heapName(heapName)
</ins><span class="cx"> {
</span><del>-    UNUSED_PARAM(instruction);
-    UNUSED_PARAM(repository);
</del><ins>+    changeParent(parent);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void AbstractHeap::changeParent(AbstractHeap* parent)
+{
+    if (m_parent) {
+        bool result = m_parent-&gt;m_children.removeFirst(this);
+        RELEASE_ASSERT(result);
+    }
+
+    m_parent = parent;
+
+    if (parent) {
+        ASSERT(!m_parent-&gt;m_children.contains(this));
+        m_parent-&gt;m_children.append(this);
+    }
+}
+
+void AbstractHeap::compute(unsigned begin)
+{
+    // This recursively computes the ranges of the tree. This solves the following constraints
+    // in linear time:
+    //
+    // - A node's end is greater than its begin.
+    // - A node's begin is greater than or equal to its parent's begin.
+    // - A node's end is less than or equal to its parent's end.
+    // - The ranges are as small as possible.
+    //
+    // It's OK to recurse because we keep the depth of our abstract heap hierarchy fairly sane.
+    // I think that it gets 4 deep at most.
+
+    if (m_children.isEmpty()) {
+        // Must special-case leaves so that they use just one slot on the number line.
+        m_range = HeapRange(begin);
+        return;
+    }
+
+    unsigned current = begin;
+    for (AbstractHeap* child : m_children) {
+        child-&gt;compute(current);
+        current = child-&gt;range().end();
+    }
+
+    m_range = HeapRange(begin, current);
+}
+
+void AbstractHeap::shallowDump(PrintStream&amp; out) const
+{
+    out.print(heapName(), &quot;(&quot;, m_offset, &quot;)&quot;);
+    if (m_range)
+        out.print(&quot;&lt;&quot;, m_range, &quot;&gt;&quot;);
+}
+
</ins><span class="cx"> void AbstractHeap::dump(PrintStream&amp; out) const
</span><span class="cx"> {
</span><del>-    out.print(heapName());
</del><ins>+    shallowDump(out);
</ins><span class="cx">     if (m_parent)
</span><span class="cx">         out.print(&quot;-&gt;&quot;, *m_parent);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void AbstractField::dump(PrintStream&amp; out) const
</del><ins>+void AbstractHeap::deepDump(PrintStream&amp; out, unsigned indent) const
</ins><span class="cx"> {
</span><del>-    out.print(heapName(), &quot;(&quot;, m_offset, &quot;)&quot;);
-    if (parent())
-        out.print(&quot;-&gt;&quot;, *parent());
</del><ins>+    auto printIndent = [&amp;] () {
+        for (unsigned i = indent; i--;)
+            out.print(&quot;    &quot;);
+    };
+
+    printIndent();
+    shallowDump(out);
+
+    if (m_children.isEmpty()) {
+        out.print(&quot;\n&quot;);
+        return;
+    }
+
+    out.print(&quot;:\n&quot;);
+    for (AbstractHeap* child : m_children)
+        child-&gt;deepDump(out, indent + 1);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void AbstractHeap::badRangeError() const
+{
+    dataLog(&quot;Heap does not have range: &quot;, *this, &quot;\n&quot;);
+    RELEASE_ASSERT_NOT_REACHED();
+}
+
</ins><span class="cx"> IndexedAbstractHeap::IndexedAbstractHeap(AbstractHeap* parent, const char* heapName, ptrdiff_t offset, size_t elementSize)
</span><span class="cx">     : m_heapForAnyIndex(parent, heapName)
</span><span class="cx">     , m_heapNameLength(strlen(heapName))
</span><span class="lines">@@ -80,23 +152,23 @@
</span><span class="cx">     return TypedPointer(atAnyIndex(), out.addPtr(result, m_offset + offset));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-const AbstractField&amp; IndexedAbstractHeap::atSlow(ptrdiff_t index)
</del><ins>+const AbstractHeap&amp; IndexedAbstractHeap::atSlow(ptrdiff_t index)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(static_cast&lt;size_t&gt;(index) &gt;= m_smallIndices.size());
</span><span class="cx">     
</span><span class="cx">     if (UNLIKELY(!m_largeIndices))
</span><span class="cx">         m_largeIndices = std::make_unique&lt;MapType&gt;();
</span><span class="cx"> 
</span><del>-    std::unique_ptr&lt;AbstractField&gt;&amp; field = m_largeIndices-&gt;add(index, nullptr).iterator-&gt;value;
</del><ins>+    std::unique_ptr&lt;AbstractHeap&gt;&amp; field = m_largeIndices-&gt;add(index, nullptr).iterator-&gt;value;
</ins><span class="cx">     if (!field) {
</span><del>-        field = std::make_unique&lt;AbstractField&gt;();
</del><ins>+        field = std::make_unique&lt;AbstractHeap&gt;();
</ins><span class="cx">         initialize(*field, index);
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     return *field;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void IndexedAbstractHeap::initialize(AbstractField&amp; field, ptrdiff_t signedIndex)
</del><ins>+void IndexedAbstractHeap::initialize(AbstractHeap&amp; field, ptrdiff_t signedIndex)
</ins><span class="cx"> {
</span><span class="cx">     // Build up a name of the form:
</span><span class="cx">     //
</span><span class="lines">@@ -115,9 +187,10 @@
</span><span class="cx">     //
</span><span class="cx">     //    Blah_neg_A
</span><span class="cx">     //
</span><del>-    // This used to be important because we used to use the string to distinguish the types. This is
-    // not relevant anymore, and this code will be removed eventually.
-    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=154319
</del><ins>+    // This naming convention comes from our previous use of LLVM. It's not clear that we need
+    // it anymore, though it is sort of nifty. Basically, B3 doesn't need string names for
+    // abstract heaps, but the fact that we have a reasonably efficient way to always name the
+    // heaps will probably come in handy for debugging.
</ins><span class="cx">     
</span><span class="cx">     static const char* negSplit = &quot;_neg_&quot;;
</span><span class="cx">     static const char* posSplit = &quot;_&quot;;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLAbstractHeaph"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeap.h (197341 => 197342)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeap.h        2016-02-29 11:21:28 UTC (rev 197341)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeap.h        2016-02-29 11:30:47 UTC (rev 197342)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013, 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;B3HeapRange.h&quot;
</ins><span class="cx"> #include &quot;FTLAbbreviatedTypes.h&quot;
</span><span class="cx"> #include &quot;JSCJSValue.h&quot;
</span><span class="cx"> #include &lt;array&gt;
</span><span class="lines">@@ -39,10 +40,6 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx"> 
</span><del>-// This is here because we used to generate LLVM's TBAA. In the future we will want to generate
-// B3 HeapRanges instead.
-// FIXME: https://bugs.webkit.org/show_bug.cgi?id=154319
-
</del><span class="cx"> class AbstractHeapRepository;
</span><span class="cx"> class Output;
</span><span class="cx"> class TypedPointer;
</span><span class="lines">@@ -51,35 +48,29 @@
</span><span class="cx">     WTF_MAKE_NONCOPYABLE(AbstractHeap); WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><span class="cx">     AbstractHeap()
</span><del>-        : m_parent(0)
-        , m_heapName(0)
</del><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    AbstractHeap(AbstractHeap* parent, const char* heapName)
-        : m_parent(parent)
-        , m_heapName(heapName)
-    {
-    }
-    
</del><ins>+    AbstractHeap(AbstractHeap* parent, const char* heapName, ptrdiff_t offset = 0);
+
</ins><span class="cx">     bool isInitialized() const { return !!m_heapName; }
</span><span class="cx">     
</span><del>-    void initialize(AbstractHeap* parent, const char* heapName)
</del><ins>+    void initialize(AbstractHeap* parent, const char* heapName, ptrdiff_t offset = 0)
</ins><span class="cx">     {
</span><del>-        m_parent = parent;
</del><ins>+        changeParent(parent);
</ins><span class="cx">         m_heapName = heapName;
</span><ins>+        m_offset = offset;
</ins><span class="cx">     }
</span><span class="cx">     
</span><del>-    void changeParent(AbstractHeap* parent)
-    {
-        m_parent = parent;
-    }
</del><ins>+    void changeParent(AbstractHeap* parent);
</ins><span class="cx"> 
</span><span class="cx">     AbstractHeap* parent() const
</span><span class="cx">     {
</span><span class="cx">         ASSERT(isInitialized());
</span><span class="cx">         return m_parent;
</span><span class="cx">     }
</span><ins>+
+    const Vector&lt;AbstractHeap*&gt;&amp; children() const;
</ins><span class="cx">     
</span><span class="cx">     const char* heapName() const
</span><span class="cx">     {
</span><span class="lines">@@ -87,47 +78,44 @@
</span><span class="cx">         return m_heapName;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    void decorateInstruction(LValue instruction, const AbstractHeapRepository&amp;) const;
-
-    void dump(PrintStream&amp;) const;
-
-private:
-    friend class AbstractHeapRepository;
-
-    AbstractHeap* m_parent;
-    const char* m_heapName;
-};
-
-// Think of &quot;AbstractField&quot; as being an &quot;AbstractHeapWithOffset&quot;. I would have named
-// it the latter except that I don't like typing that much.
-class AbstractField : public AbstractHeap {
-public:
-    AbstractField()
</del><ins>+    B3::HeapRange range() const
</ins><span class="cx">     {
</span><ins>+        // This will not have a valid value until after all lowering is done. Do associate an
+        // AbstractHeap with a B3::Value*, use AbstractHeapRepository::decorateXXX().
+        if (!m_range)
+            badRangeError();
+        
+        return m_range;
</ins><span class="cx">     }
</span><del>-    
-    AbstractField(AbstractHeap* parent, const char* heapName, ptrdiff_t offset)
-        : AbstractHeap(parent, heapName)
-        , m_offset(offset)
-    {
-    }
-    
-    void initialize(AbstractHeap* parent, const char* heapName, ptrdiff_t offset)
-    {
-        AbstractHeap::initialize(parent, heapName);
-        m_offset = offset;
-    }
-    
</del><ins>+
+    // WARNING: Not all abstract heaps have a meaningful offset.
</ins><span class="cx">     ptrdiff_t offset() const
</span><span class="cx">     {
</span><span class="cx">         ASSERT(isInitialized());
</span><span class="cx">         return m_offset;
</span><span class="cx">     }
</span><del>-    
</del><ins>+
+    void compute(unsigned begin = 0);
+
+    // Print information about just this heap.
+    void shallowDump(PrintStream&amp;) const;
+
+    // Print information about this heap and its ancestors. This is the default.
</ins><span class="cx">     void dump(PrintStream&amp;) const;
</span><span class="cx"> 
</span><ins>+    // Print information about this heap and its descendents. This is a multi-line dump.
+    void deepDump(PrintStream&amp;, unsigned indent = 0) const;
+
</ins><span class="cx"> private:
</span><del>-    ptrdiff_t m_offset;
</del><ins>+    friend class AbstractHeapRepository;
+
+    NO_RETURN_DUE_TO_CRASH void badRangeError() const;
+
+    AbstractHeap* m_parent { nullptr };
+    Vector&lt;AbstractHeap*&gt; m_children;
+    intptr_t m_offset { 0 };
+    B3::HeapRange m_range;
+    const char* m_heapName { nullptr };
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> class IndexedAbstractHeap {
</span><span class="lines">@@ -137,41 +125,41 @@
</span><span class="cx">     
</span><span class="cx">     const AbstractHeap&amp; atAnyIndex() const { return m_heapForAnyIndex; }
</span><span class="cx">     
</span><del>-    const AbstractField&amp; at(ptrdiff_t index)
</del><ins>+    const AbstractHeap&amp; at(ptrdiff_t index)
</ins><span class="cx">     {
</span><span class="cx">         if (static_cast&lt;size_t&gt;(index) &lt; m_smallIndices.size())
</span><span class="cx">             return returnInitialized(m_smallIndices[index], index);
</span><span class="cx">         return atSlow(index);
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    const AbstractField&amp; operator[](ptrdiff_t index) { return at(index); }
</del><ins>+    const AbstractHeap&amp; operator[](ptrdiff_t index) { return at(index); }
</ins><span class="cx">     
</span><span class="cx">     TypedPointer baseIndex(Output&amp; out, LValue base, LValue index, JSValue indexAsConstant = JSValue(), ptrdiff_t offset = 0);
</span><span class="cx">     
</span><span class="cx">     void dump(PrintStream&amp;) const;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    const AbstractField&amp; returnInitialized(AbstractField&amp; field, ptrdiff_t index)
</del><ins>+    const AbstractHeap&amp; returnInitialized(AbstractHeap&amp; field, ptrdiff_t index)
</ins><span class="cx">     {
</span><span class="cx">         if (UNLIKELY(!field.isInitialized()))
</span><span class="cx">             initialize(field, index);
</span><span class="cx">         return field;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    const AbstractField&amp; atSlow(ptrdiff_t index);
-    void initialize(AbstractField&amp; field, ptrdiff_t index);
</del><ins>+    const AbstractHeap&amp; atSlow(ptrdiff_t index);
+    void initialize(AbstractHeap&amp; field, ptrdiff_t index);
</ins><span class="cx"> 
</span><span class="cx">     AbstractHeap m_heapForAnyIndex;
</span><span class="cx">     size_t m_heapNameLength;
</span><span class="cx">     ptrdiff_t m_offset;
</span><span class="cx">     size_t m_elementSize;
</span><del>-    std::array&lt;AbstractField, 16&gt; m_smallIndices;
</del><ins>+    std::array&lt;AbstractHeap, 16&gt; m_smallIndices;
</ins><span class="cx">     
</span><span class="cx">     struct WithoutZeroOrOneHashTraits : WTF::GenericHashTraits&lt;ptrdiff_t&gt; {
</span><span class="cx">         static void constructDeletedValue(ptrdiff_t&amp; slot) { slot = 1; }
</span><span class="cx">         static bool isDeletedValue(ptrdiff_t value) { return value == 1; }
</span><span class="cx">     };
</span><del>-    typedef HashMap&lt;ptrdiff_t, std::unique_ptr&lt;AbstractField&gt;, WTF::IntHash&lt;ptrdiff_t&gt;, WithoutZeroOrOneHashTraits&gt; MapType;
</del><ins>+    typedef HashMap&lt;ptrdiff_t, std::unique_ptr&lt;AbstractHeap&gt;, WTF::IntHash&lt;ptrdiff_t&gt;, WithoutZeroOrOneHashTraits&gt; MapType;
</ins><span class="cx">     
</span><span class="cx">     std::unique_ptr&lt;MapType&gt; m_largeIndices;
</span><span class="cx">     Vector&lt;CString, 16&gt; m_largeIndexNames;
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLAbstractHeapRepositorycpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp (197341 => 197342)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp        2016-02-29 11:21:28 UTC (rev 197341)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.cpp        2016-02-29 11:30:47 UTC (rev 197342)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -28,7 +28,12 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;B3CCallValue.h&quot;
+#include &quot;B3MemoryValue.h&quot;
+#include &quot;B3PatchpointValue.h&quot;
+#include &quot;B3ValueInlines.h&quot;
</ins><span class="cx"> #include &quot;DirectArguments.h&quot;
</span><ins>+#include &quot;FTLState.h&quot;
</ins><span class="cx"> #include &quot;GetterSetter.h&quot;
</span><span class="cx"> #include &quot;JSEnvironmentRecord.h&quot;
</span><span class="cx"> #include &quot;JSPropertyNameEnumerator.h&quot;
</span><span class="lines">@@ -39,8 +44,10 @@
</span><span class="cx"> 
</span><span class="cx"> namespace JSC { namespace FTL {
</span><span class="cx"> 
</span><ins>+using namespace B3;
+
</ins><span class="cx"> AbstractHeapRepository::AbstractHeapRepository()
</span><del>-    : root(0, &quot;jscRoot&quot;)
</del><ins>+    : root(nullptr, &quot;jscRoot&quot;)
</ins><span class="cx"> 
</span><span class="cx"> #define ABSTRACT_HEAP_INITIALIZATION(name) , name(&amp;root, #name)
</span><span class="cx">     FOR_EACH_ABSTRACT_HEAP(ABSTRACT_HEAP_INITIALIZATION)
</span><span class="lines">@@ -80,6 +87,52 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void AbstractHeapRepository::decorateMemory(const AbstractHeap* heap, Value* value)
+{
+    m_heapForMemory.append(HeapForValue(heap, value));
+}
+
+void AbstractHeapRepository::decorateCCallRead(const AbstractHeap* heap, Value* value)
+{
+    m_heapForCCallRead.append(HeapForValue(heap, value));
+}
+
+void AbstractHeapRepository::decorateCCallWrite(const AbstractHeap* heap, Value* value)
+{
+    m_heapForCCallWrite.append(HeapForValue(heap, value));
+}
+
+void AbstractHeapRepository::decoratePatchpointRead(const AbstractHeap* heap, Value* value)
+{
+    m_heapForPatchpointRead.append(HeapForValue(heap, value));
+}
+
+void AbstractHeapRepository::decoratePatchpointWrite(const AbstractHeap* heap, Value* value)
+{
+    m_heapForPatchpointWrite.append(HeapForValue(heap, value));
+}
+
+void AbstractHeapRepository::computeRangesAndDecorateInstructions()
+{
+    root.compute();
+
+    if (verboseCompilationEnabled()) {
+        dataLog(&quot;Abstract Heap Repository:\n&quot;);
+        root.deepDump(WTF::dataFile());
+    }
+
+    for (HeapForValue entry : m_heapForMemory)
+        entry.value-&gt;as&lt;MemoryValue&gt;()-&gt;setRange(entry.heap-&gt;range());
+    for (HeapForValue entry : m_heapForCCallRead)
+        entry.value-&gt;as&lt;CCallValue&gt;()-&gt;effects.reads = entry.heap-&gt;range();
+    for (HeapForValue entry : m_heapForCCallWrite)
+        entry.value-&gt;as&lt;CCallValue&gt;()-&gt;effects.writes = entry.heap-&gt;range();
+    for (HeapForValue entry : m_heapForPatchpointRead)
+        entry.value-&gt;as&lt;CCallValue&gt;()-&gt;effects.reads = entry.heap-&gt;range();
+    for (HeapForValue entry : m_heapForPatchpointWrite)
+        entry.value-&gt;as&lt;CCallValue&gt;()-&gt;effects.writes = entry.heap-&gt;range();
+}
+
</ins><span class="cx"> } } // namespace JSC::FTL
</span><span class="cx"> 
</span><span class="cx"> #endif // ENABLE(FTL_JIT)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLAbstractHeapRepositoryh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h (197341 => 197342)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h        2016-02-29 11:21:28 UTC (rev 197341)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLAbstractHeapRepository.h        2016-02-29 11:30:47 UTC (rev 197342)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(FTL_JIT)
</span><span class="cx"> 
</span><ins>+#include &quot;B3Value.h&quot;
</ins><span class="cx"> #include &quot;DFGArrayMode.h&quot;
</span><span class="cx"> #include &quot;FTLAbstractHeap.h&quot;
</span><span class="cx"> #include &quot;IndexingType.h&quot;
</span><span class="lines">@@ -127,11 +128,11 @@
</span><span class="cx">     FOR_EACH_ABSTRACT_HEAP(ABSTRACT_HEAP_DECLARATION)
</span><span class="cx"> #undef ABSTRACT_HEAP_DECLARATION
</span><span class="cx"> 
</span><del>-#define ABSTRACT_FIELD_DECLARATION(name, offset) AbstractField name;
</del><ins>+#define ABSTRACT_FIELD_DECLARATION(name, offset) AbstractHeap name;
</ins><span class="cx">     FOR_EACH_ABSTRACT_FIELD(ABSTRACT_FIELD_DECLARATION)
</span><span class="cx"> #undef ABSTRACT_FIELD_DECLARATION
</span><span class="cx">     
</span><del>-    AbstractField&amp; JSCell_freeListNext;
</del><ins>+    AbstractHeap&amp; JSCell_freeListNext;
</ins><span class="cx">     
</span><span class="cx"> #define INDEXED_ABSTRACT_HEAP_DECLARATION(name, offset, size) IndexedAbstractHeap name;
</span><span class="cx">     FOR_EACH_INDEXED_ABSTRACT_HEAP(INDEXED_ABSTRACT_HEAP_DECLARATION)
</span><span class="lines">@@ -186,8 +187,36 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    void decorateMemory(const AbstractHeap*, B3::Value*);
+    void decorateCCallRead(const AbstractHeap*, B3::Value*);
+    void decorateCCallWrite(const AbstractHeap*, B3::Value*);
+    void decoratePatchpointRead(const AbstractHeap*, B3::Value*);
+    void decoratePatchpointWrite(const AbstractHeap*, B3::Value*);
+
+    void computeRangesAndDecorateInstructions();
+
</ins><span class="cx"> private:
</span><del>-    friend class AbstractHeap;
</del><ins>+
+    struct HeapForValue {
+        HeapForValue()
+        {
+        }
+
+        HeapForValue(const AbstractHeap* heap, B3::Value* value)
+            : heap(heap)
+            , value(value)
+        {
+        }
+        
+        const AbstractHeap* heap { nullptr };
+        B3::Value* value { nullptr };
+    };
+
+    Vector&lt;HeapForValue&gt; m_heapForMemory;
+    Vector&lt;HeapForValue&gt; m_heapForCCallRead;
+    Vector&lt;HeapForValue&gt; m_heapForCCallWrite;
+    Vector&lt;HeapForValue&gt; m_heapForPatchpointRead;
+    Vector&lt;HeapForValue&gt; m_heapForPatchpointWrite;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> } } // namespace JSC::FTL
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLLowerDFGToB3cpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp (197341 => 197342)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-02-29 11:21:28 UTC (rev 197341)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp        2016-02-29 11:30:47 UTC (rev 197342)
</span><span class="lines">@@ -279,6 +279,12 @@
</span><span class="cx">         for (DFG::BasicBlock* block : preOrder)
</span><span class="cx">             compileBlock(block);
</span><span class="cx"> 
</span><ins>+        // Make sure everything is decorated. This does a bunch of deferred decorating. This has
+        // to happen last because our abstract heaps are generated lazily. They have to be
+        // generated lazily because we have an infiniten number of numbered, indexed, and
+        // absolute heaps. We only become aware of the ones we actually mention while lowering.
+        m_heaps.computeRangesAndDecorateInstructions();
+
</ins><span class="cx">         // We create all Phi's up front, but we may then decide not to compile the basic block
</span><span class="cx">         // that would have contained one of them. So this creates orphans, which triggers B3
</span><span class="cx">         // validation failures. Calling this fixes the issue.
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLOutputcpp"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLOutput.cpp (197341 => 197342)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLOutput.cpp        2016-02-29 11:21:28 UTC (rev 197341)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLOutput.cpp        2016-02-29 11:30:47 UTC (rev 197342)
</span><span class="lines">@@ -102,7 +102,7 @@
</span><span class="cx"> LValue Output::load(TypedPointer pointer, LType type)
</span><span class="cx"> {
</span><span class="cx">     LValue load = m_block-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load, type, origin(), pointer.value());
</span><del>-    pointer.heap().decorateInstruction(load, *m_heaps);
</del><ins>+    m_heaps-&gt;decorateMemory(pointer.heap(), load);
</ins><span class="cx">     return load;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -153,47 +153,47 @@
</span><span class="cx"> LValue Output::load8SignExt32(TypedPointer pointer)
</span><span class="cx"> {
</span><span class="cx">     LValue load = m_block-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load8S, Int32, origin(), pointer.value());
</span><del>-    pointer.heap().decorateInstruction(load, *m_heaps);
</del><ins>+    m_heaps-&gt;decorateMemory(pointer.heap(), load);
</ins><span class="cx">     return load;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> LValue Output::load8ZeroExt32(TypedPointer pointer)
</span><span class="cx"> {
</span><span class="cx">     LValue load = m_block-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load8Z, Int32, origin(), pointer.value());
</span><del>-    pointer.heap().decorateInstruction(load, *m_heaps);
</del><ins>+    m_heaps-&gt;decorateMemory(pointer.heap(), load);
</ins><span class="cx">     return load;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> LValue Output::load16SignExt32(TypedPointer pointer)
</span><span class="cx"> {
</span><span class="cx">     LValue load = m_block-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load16S, Int32, origin(), pointer.value());
</span><del>-    pointer.heap().decorateInstruction(load, *m_heaps);
</del><ins>+    m_heaps-&gt;decorateMemory(pointer.heap(), load);
</ins><span class="cx">     return load;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> LValue Output::load16ZeroExt32(TypedPointer pointer)
</span><span class="cx"> {
</span><span class="cx">     LValue load = m_block-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Load16Z, Int32, origin(), pointer.value());
</span><del>-    pointer.heap().decorateInstruction(load, *m_heaps);
</del><ins>+    m_heaps-&gt;decorateMemory(pointer.heap(), load);
</ins><span class="cx">     return load;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Output::store(LValue value, TypedPointer pointer)
</span><span class="cx"> {
</span><span class="cx">     LValue store = m_block-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Store, origin(), value, pointer.value());
</span><del>-    pointer.heap().decorateInstruction(store, *m_heaps);
</del><ins>+    m_heaps-&gt;decorateMemory(pointer.heap(), store);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Output::store32As8(LValue value, TypedPointer pointer)
</span><span class="cx"> {
</span><span class="cx">     LValue store = m_block-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Store8, origin(), value, pointer.value());
</span><del>-    pointer.heap().decorateInstruction(store, *m_heaps);
</del><ins>+    m_heaps-&gt;decorateMemory(pointer.heap(), store);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void Output::store32As16(LValue value, TypedPointer pointer)
</span><span class="cx"> {
</span><span class="cx">     LValue store = m_block-&gt;appendNew&lt;MemoryValue&gt;(m_proc, Store16, origin(), value, pointer.value());
</span><del>-    pointer.heap().decorateInstruction(store, *m_heaps);
</del><ins>+    m_heaps-&gt;decorateMemory(pointer.heap(), store);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> LValue Output::baseIndex(LValue base, LValue index, Scale scale, ptrdiff_t offset)
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLOutputh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLOutput.h (197341 => 197342)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLOutput.h        2016-02-29 11:21:28 UTC (rev 197341)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLOutput.h        2016-02-29 11:30:47 UTC (rev 197342)
</span><span class="lines">@@ -289,7 +289,7 @@
</span><span class="cx">     // Construct an address by offsetting base by the amount specified by the field,
</span><span class="cx">     // and optionally an additional amount (use this with care), and then creating
</span><span class="cx">     // a TypedPointer with the given field as the heap.
</span><del>-    TypedPointer address(LValue base, const AbstractField&amp; field, ptrdiff_t offset = 0)
</del><ins>+    TypedPointer address(LValue base, const AbstractHeap&amp; field, ptrdiff_t offset = 0)
</ins><span class="cx">     {
</span><span class="cx">         return address(field, base, offset + field.offset());
</span><span class="cx">     }
</span><span class="lines">@@ -310,18 +310,18 @@
</span><span class="cx">         return TypedPointer(m_heaps-&gt;absolute[address], constIntPtr(address));
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    LValue load8SignExt32(LValue base, const AbstractField&amp; field) { return load8SignExt32(address(base, field)); }
-    LValue load8ZeroExt32(LValue base, const AbstractField&amp; field) { return load8ZeroExt32(address(base, field)); }
-    LValue load16SignExt32(LValue base, const AbstractField&amp; field) { return load16SignExt32(address(base, field)); }
-    LValue load16ZeroExt32(LValue base, const AbstractField&amp; field) { return load16ZeroExt32(address(base, field)); }
-    LValue load32(LValue base, const AbstractField&amp; field) { return load32(address(base, field)); }
-    LValue load64(LValue base, const AbstractField&amp; field) { return load64(address(base, field)); }
-    LValue loadPtr(LValue base, const AbstractField&amp; field) { return loadPtr(address(base, field)); }
-    LValue loadDouble(LValue base, const AbstractField&amp; field) { return loadDouble(address(base, field)); }
-    void store32(LValue value, LValue base, const AbstractField&amp; field) { store32(value, address(base, field)); }
-    void store64(LValue value, LValue base, const AbstractField&amp; field) { store64(value, address(base, field)); }
-    void storePtr(LValue value, LValue base, const AbstractField&amp; field) { storePtr(value, address(base, field)); }
-    void storeDouble(LValue value, LValue base, const AbstractField&amp; field) { storeDouble(value, address(base, field)); }
</del><ins>+    LValue load8SignExt32(LValue base, const AbstractHeap&amp; field) { return load8SignExt32(address(base, field)); }
+    LValue load8ZeroExt32(LValue base, const AbstractHeap&amp; field) { return load8ZeroExt32(address(base, field)); }
+    LValue load16SignExt32(LValue base, const AbstractHeap&amp; field) { return load16SignExt32(address(base, field)); }
+    LValue load16ZeroExt32(LValue base, const AbstractHeap&amp; field) { return load16ZeroExt32(address(base, field)); }
+    LValue load32(LValue base, const AbstractHeap&amp; field) { return load32(address(base, field)); }
+    LValue load64(LValue base, const AbstractHeap&amp; field) { return load64(address(base, field)); }
+    LValue loadPtr(LValue base, const AbstractHeap&amp; field) { return loadPtr(address(base, field)); }
+    LValue loadDouble(LValue base, const AbstractHeap&amp; field) { return loadDouble(address(base, field)); }
+    void store32(LValue value, LValue base, const AbstractHeap&amp; field) { store32(value, address(base, field)); }
+    void store64(LValue value, LValue base, const AbstractHeap&amp; field) { store64(value, address(base, field)); }
+    void storePtr(LValue value, LValue base, const AbstractHeap&amp; field) { storePtr(value, address(base, field)); }
+    void storeDouble(LValue value, LValue base, const AbstractHeap&amp; field) { storeDouble(value, address(base, field)); }
</ins><span class="cx"> 
</span><span class="cx">     // FIXME: Explore adding support for value range constraints to B3. Maybe it could be as simple as having
</span><span class="cx">     // a load instruction that guarantees that its result is non-negative.
</span><span class="lines">@@ -329,7 +329,7 @@
</span><span class="cx">     void ascribeRange(LValue, const ValueRange&amp;) { }
</span><span class="cx">     LValue nonNegative32(LValue loadInstruction) { return loadInstruction; }
</span><span class="cx">     LValue load32NonNegative(TypedPointer pointer) { return load32(pointer); }
</span><del>-    LValue load32NonNegative(LValue base, const AbstractField&amp; field) { return load32(base, field); }
</del><ins>+    LValue load32NonNegative(LValue base, const AbstractHeap&amp; field) { return load32(base, field); }
</ins><span class="cx"> 
</span><span class="cx">     LValue equal(LValue left, LValue right) { return m_block-&gt;appendNew&lt;B3::Value&gt;(m_proc, B3::Equal, origin(), left, right); }
</span><span class="cx">     LValue notEqual(LValue left, LValue right) { return m_block-&gt;appendNew&lt;B3::Value&gt;(m_proc, B3::NotEqual, origin(), left, right); }
</span></span></pre></div>
<a id="releasesWebKitGTKwebkit212SourceJavaScriptCoreftlFTLTypedPointerh"></a>
<div class="modfile"><h4>Modified: releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLTypedPointer.h (197341 => 197342)</h4>
<pre class="diff"><span>
<span class="info">--- releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLTypedPointer.h        2016-02-29 11:21:28 UTC (rev 197341)
+++ releases/WebKitGTK/webkit-2.12/Source/JavaScriptCore/ftl/FTLTypedPointer.h        2016-02-29 11:30:47 UTC (rev 197342)
</span><span class="lines">@@ -53,7 +53,7 @@
</span><span class="cx">         return !m_heap;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    const AbstractHeap&amp; heap() const { return *m_heap; }
</del><ins>+    const AbstractHeap* heap() const { return m_heap; }
</ins><span class="cx">     LValue value() const { return m_value; }
</span><span class="cx"> 
</span><span class="cx"> private:
</span></span></pre>
</div>
</div>

</body>
</html>