Changeset 219317 in webkit


Ignore:
Timestamp:
Jul 10, 2017 5:29:36 PM (7 years ago)
Author:
sbarati@apple.com
Message:

Allocation sinking phase should consider a CheckStructure that would fail as an escape
https://bugs.webkit.org/show_bug.cgi?id=174321
<rdar://problem/32604963>

Reviewed by Filip Pizlo.

When the allocation sinking phase was generating stores to materialize
objects in a cycle with each other, it would assume that each materialized
object had a valid, non empty, set of structures. This is an OK assumption for
the phase to make because how do you materialize an object with no structure?

The abstract interpretation part of the phase will model what's in the heap.
However, it would sometimes model that a CheckStructure would fail. The phase
did nothing special for this; it just stored the empty set of structures for
its representation of a particular allocation. However, what the phase proved
in such a scenario is that, had the CheckStructure executed, it would have exited.

This patch treats such CheckStructures and MultiGetByOffsets as escape points.
This will cause the allocation in question to be materialized just before
the CheckStructure, and then at execution time, the CheckStructure will exit.

I wasn't able to write a test case for this. However, I was able to reproduce
this crash by manually editing the IR. I've opened a separate bug to help us
create a testing framework for writing tests for hard to reproduce bugs like this:
https://bugs.webkit.org/show_bug.cgi?id=174322

  • dfg/DFGObjectAllocationSinkingPhase.cpp:
Location:
trunk/Source/JavaScriptCore
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r219316 r219317  
     12017-07-10  Saam Barati  <sbarati@apple.com>
     2
     3        Allocation sinking phase should consider a CheckStructure that would fail as an escape
     4        https://bugs.webkit.org/show_bug.cgi?id=174321
     5        <rdar://problem/32604963>
     6
     7        Reviewed by Filip Pizlo.
     8
     9        When the allocation sinking phase was generating stores to materialize
     10        objects in a cycle with each other, it would assume that each materialized
     11        object had a valid, non empty, set of structures. This is an OK assumption for
     12        the phase to make because how do you materialize an object with no structure?
     13       
     14        The abstract interpretation part of the phase will model what's in the heap.
     15        However, it would sometimes model that a CheckStructure would fail. The phase
     16        did nothing special for this; it just stored the empty set of structures for
     17        its representation of a particular allocation. However, what the phase proved
     18        in such a scenario is that, had the CheckStructure executed, it would have exited.
     19       
     20        This patch treats such CheckStructures and MultiGetByOffsets as escape points.
     21        This will cause the allocation in question to be materialized just before
     22        the CheckStructure, and then at execution time, the CheckStructure will exit.
     23       
     24        I wasn't able to write a test case for this. However, I was able to reproduce
     25        this crash by manually editing the IR. I've opened a separate bug to help us
     26        create a testing framework for writing tests for hard to reproduce bugs like this:
     27        https://bugs.webkit.org/show_bug.cgi?id=174322
     28
     29        * dfg/DFGObjectAllocationSinkingPhase.cpp:
     30
    1312017-07-10  Devin Rousso  <drousso@apple.com>
    232
  • trunk/Source/JavaScriptCore/dfg/DFGObjectAllocationSinkingPhase.cpp

    r219192 r219317  
    219219        ASSERT(hasStructures());
    220220        m_structures.filter(structures);
     221        RELEASE_ASSERT(!m_structures.isEmpty());
    221222        return *this;
    222223    }
     
    903904            Allocation* allocation = m_heap.onlyLocalAllocation(node->child1().node());
    904905            if (allocation && allocation->isObjectAllocation()) {
    905                 allocation->filterStructures(node->structureSet());
     906                RegisteredStructureSet filteredStructures = allocation->structures();
     907                filteredStructures.filter(node->structureSet());
     908                if (filteredStructures.isEmpty()) {
     909                    // FIXME: Write a test for this:
     910                    // https://bugs.webkit.org/show_bug.cgi?id=174322
     911                    m_heap.escape(node->child1().node());
     912                    break;
     913                }
     914                allocation->setStructures(filteredStructures);
    906915                if (Node* value = heapResolve(PromotedHeapLocation(allocation->identifier(), StructurePLoc)))
    907916                    node->convertToCheckStructureImmediate(value);
     
    947956                    }
    948957                }
    949                 if (hasInvalidStructures) {
     958                if (hasInvalidStructures || validStructures.isEmpty()) {
    950959                    m_heap.escape(node->child1().node());
    951960                    break;
Note: See TracChangeset for help on using the changeset viewer.