b53c16f98b597c98815840c7c00d3fcc27b0eebd
[WebKit-https.git] / Source / JavaScriptCore / dfg / DFGSSALoweringPhase.cpp
1 /*
2  * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "DFGSSALoweringPhase.h"
28
29 #if ENABLE(DFG_JIT)
30
31 #include "DFGBasicBlockInlines.h"
32 #include "DFGGraph.h"
33 #include "DFGInsertionSet.h"
34 #include "DFGPhase.h"
35 #include "JSCInlines.h"
36
37 namespace JSC { namespace DFG {
38
39 class SSALoweringPhase : public Phase {
40     static const bool verbose = false;
41     
42 public:
43     SSALoweringPhase(Graph& graph)
44         : Phase(graph, "SSA lowering")
45         , m_insertionSet(graph)
46     {
47     }
48     
49     bool run()
50     {
51         RELEASE_ASSERT(m_graph.m_form == SSA);
52         
53         for (BlockIndex blockIndex = m_graph.numBlocks(); blockIndex--;) {
54             m_block = m_graph.block(blockIndex);
55             if (!m_block)
56                 continue;
57             for (m_nodeIndex = 0; m_nodeIndex < m_block->size(); ++m_nodeIndex) {
58                 m_node = m_block->at(m_nodeIndex);
59                 handleNode();
60             }
61             m_insertionSet.execute(m_block);
62         }
63
64         return true;
65     }
66
67 private:
68     void handleNode()
69     {
70         switch (m_node->op()) {
71         case GetByVal:
72         case HasIndexedProperty:
73             lowerBoundsCheck(m_node->child1(), m_node->child2(), m_node->child3());
74             break;
75             
76         case PutByVal:
77         case PutByValDirect: {
78             Edge base = m_graph.varArgChild(m_node, 0);
79             Edge index = m_graph.varArgChild(m_node, 1);
80             Edge storage = m_graph.varArgChild(m_node, 3);
81             if (lowerBoundsCheck(base, index, storage))
82                 break;
83             
84             if (m_node->arrayMode().typedArrayType() != NotTypedArray && m_node->arrayMode().isOutOfBounds()) {
85                 Node* length = m_insertionSet.insertNode(
86                     m_nodeIndex, SpecInt32, GetArrayLength, m_node->origin,
87                     OpInfo(m_node->arrayMode().asWord()), base, storage);
88                 
89                 m_graph.varArgChild(m_node, 4) = Edge(length, KnownInt32Use);
90                 break;
91             }
92             break;
93         }
94             
95         default:
96             break;
97         }
98     }
99     
100     bool lowerBoundsCheck(Edge base, Edge index, Edge storage)
101     {
102         if (!m_node->arrayMode().permitsBoundsCheckLowering())
103             return false;
104         
105         if (!m_node->arrayMode().lengthNeedsStorage())
106             storage = Edge();
107         
108         Node* length = m_insertionSet.insertNode(
109             m_nodeIndex, SpecInt32, GetArrayLength, m_node->origin,
110             OpInfo(m_node->arrayMode().asWord()), base, storage);
111         m_insertionSet.insertNode(
112             m_nodeIndex, SpecInt32, CheckInBounds, m_node->origin,
113             index, Edge(length, KnownInt32Use));
114         return true;
115     }
116     
117     InsertionSet m_insertionSet;
118     BasicBlock* m_block;
119     unsigned m_nodeIndex;
120     Node* m_node;
121 };
122
123 bool performSSALowering(Graph& graph)
124 {
125     return runPhase<SSALoweringPhase>(graph);
126 }
127
128 } } // namespace JSC::DFG
129
130 #endif // ENABLE(DFG_JIT)
131