| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
| 6 | 6 |
| 7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
| 8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
| 9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
| 10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
| (...skipping 1719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1730 environment()->Push(literal); | 1730 environment()->Push(literal); |
| 1731 environment()->Push(literal_index); | 1731 environment()->Push(literal_index); |
| 1732 | 1732 |
| 1733 // Create nodes to evaluate all the non-constant subexpressions and to store | 1733 // Create nodes to evaluate all the non-constant subexpressions and to store |
| 1734 // them into the newly cloned array. | 1734 // them into the newly cloned array. |
| 1735 for (int i = 0; i < expr->values()->length(); i++) { | 1735 for (int i = 0; i < expr->values()->length(); i++) { |
| 1736 Expression* subexpr = expr->values()->at(i); | 1736 Expression* subexpr = expr->values()->at(i); |
| 1737 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; | 1737 if (CompileTimeValue::IsCompileTimeValue(subexpr)) continue; |
| 1738 | 1738 |
| 1739 VisitForValue(subexpr); | 1739 VisitForValue(subexpr); |
| 1740 Node* frame_state_before = environment()->Checkpoint( |
| 1741 subexpr->id(), OutputFrameStateCombine::PokeAt(0)); |
| 1740 Node* value = environment()->Pop(); | 1742 Node* value = environment()->Pop(); |
| 1741 Node* index = jsgraph()->Constant(i); | 1743 Node* index = jsgraph()->Constant(i); |
| 1742 Node* store = BuildKeyedStore(literal, index, value); | 1744 Node* store = BuildKeyedStore(literal, index, value); |
| 1743 PrepareFrameState(store, expr->GetIdForElement(i)); | 1745 PrepareFrameStateAfterAndBefore(store, expr->GetIdForElement(i), |
| 1746 OutputFrameStateCombine::Ignore(), |
| 1747 frame_state_before); |
| 1744 } | 1748 } |
| 1745 | 1749 |
| 1746 environment()->Pop(); // Array literal index. | 1750 environment()->Pop(); // Array literal index. |
| 1747 ast_context()->ProduceValue(environment()->Pop()); | 1751 ast_context()->ProduceValue(environment()->Pop()); |
| 1748 } | 1752 } |
| 1749 | 1753 |
| 1750 | 1754 |
| 1751 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, | 1755 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, |
| 1752 BailoutId bailout_id) { | 1756 BailoutId bailout_id) { |
| 1753 DCHECK(expr->IsValidReferenceExpression()); | 1757 DCHECK(expr->IsValidReferenceExpression()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1774 break; | 1778 break; |
| 1775 } | 1779 } |
| 1776 case KEYED_PROPERTY: { | 1780 case KEYED_PROPERTY: { |
| 1777 environment()->Push(value); | 1781 environment()->Push(value); |
| 1778 VisitForValue(property->obj()); | 1782 VisitForValue(property->obj()); |
| 1779 VisitForValue(property->key()); | 1783 VisitForValue(property->key()); |
| 1780 Node* key = environment()->Pop(); | 1784 Node* key = environment()->Pop(); |
| 1781 Node* object = environment()->Pop(); | 1785 Node* object = environment()->Pop(); |
| 1782 value = environment()->Pop(); | 1786 value = environment()->Pop(); |
| 1783 Node* store = BuildKeyedStore(object, key, value); | 1787 Node* store = BuildKeyedStore(object, key, value); |
| 1784 PrepareFrameState(store, bailout_id); | 1788 // TODO(jarin) Provide a real frame state before. |
| 1789 PrepareFrameStateAfterAndBefore(store, bailout_id, |
| 1790 OutputFrameStateCombine::Ignore(), |
| 1791 jsgraph()->EmptyFrameState()); |
| 1785 break; | 1792 break; |
| 1786 } | 1793 } |
| 1787 } | 1794 } |
| 1788 } | 1795 } |
| 1789 | 1796 |
| 1790 | 1797 |
| 1791 void AstGraphBuilder::VisitAssignment(Assignment* expr) { | 1798 void AstGraphBuilder::VisitAssignment(Assignment* expr) { |
| 1792 DCHECK(expr->target()->IsValidReferenceExpression()); | 1799 DCHECK(expr->target()->IsValidReferenceExpression()); |
| 1793 | 1800 |
| 1794 // Left-hand side can only be a property, a global or a variable slot. | 1801 // Left-hand side can only be a property, a global or a variable slot. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1805 break; | 1812 break; |
| 1806 case KEYED_PROPERTY: { | 1813 case KEYED_PROPERTY: { |
| 1807 VisitForValue(property->obj()); | 1814 VisitForValue(property->obj()); |
| 1808 VisitForValue(property->key()); | 1815 VisitForValue(property->key()); |
| 1809 break; | 1816 break; |
| 1810 } | 1817 } |
| 1811 } | 1818 } |
| 1812 | 1819 |
| 1813 // Evaluate the value and potentially handle compound assignments by loading | 1820 // Evaluate the value and potentially handle compound assignments by loading |
| 1814 // the left-hand side value and performing a binary operation. | 1821 // the left-hand side value and performing a binary operation. |
| 1822 Node* frame_state_before_store = nullptr; |
| 1823 bool needs_frame_state_before = (assign_type == KEYED_PROPERTY); |
| 1815 if (expr->is_compound()) { | 1824 if (expr->is_compound()) { |
| 1816 Node* old_value = NULL; | 1825 Node* old_value = NULL; |
| 1817 switch (assign_type) { | 1826 switch (assign_type) { |
| 1818 case VARIABLE: { | 1827 case VARIABLE: { |
| 1819 VariableProxy* proxy = expr->target()->AsVariableProxy(); | 1828 VariableProxy* proxy = expr->target()->AsVariableProxy(); |
| 1820 VectorSlotPair pair = | 1829 VectorSlotPair pair = |
| 1821 CreateVectorSlotPair(proxy->VariableFeedbackSlot()); | 1830 CreateVectorSlotPair(proxy->VariableFeedbackSlot()); |
| 1822 old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair); | 1831 old_value = BuildVariableLoad(proxy->var(), expr->target()->id(), pair); |
| 1823 break; | 1832 break; |
| 1824 } | 1833 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1846 environment()->Push(old_value); | 1855 environment()->Push(old_value); |
| 1847 VisitForValue(expr->value()); | 1856 VisitForValue(expr->value()); |
| 1848 Node* frame_state_before = environment()->Checkpoint(expr->value()->id()); | 1857 Node* frame_state_before = environment()->Checkpoint(expr->value()->id()); |
| 1849 Node* right = environment()->Pop(); | 1858 Node* right = environment()->Pop(); |
| 1850 Node* left = environment()->Pop(); | 1859 Node* left = environment()->Pop(); |
| 1851 Node* value = BuildBinaryOp(left, right, expr->binary_op()); | 1860 Node* value = BuildBinaryOp(left, right, expr->binary_op()); |
| 1852 PrepareFrameStateAfterAndBefore(value, expr->binary_operation()->id(), | 1861 PrepareFrameStateAfterAndBefore(value, expr->binary_operation()->id(), |
| 1853 OutputFrameStateCombine::Push(), | 1862 OutputFrameStateCombine::Push(), |
| 1854 frame_state_before); | 1863 frame_state_before); |
| 1855 environment()->Push(value); | 1864 environment()->Push(value); |
| 1865 if (needs_frame_state_before) { |
| 1866 frame_state_before_store = environment()->Checkpoint( |
| 1867 expr->binary_operation()->id(), OutputFrameStateCombine::PokeAt(0)); |
| 1868 } |
| 1856 } else { | 1869 } else { |
| 1857 VisitForValue(expr->value()); | 1870 VisitForValue(expr->value()); |
| 1871 if (needs_frame_state_before) { |
| 1872 // This frame state can be used for lazy-deopting from a to-number |
| 1873 // conversion if we are storing into a typed array. It is important |
| 1874 // that the frame state is usable for such lazy deopt (i.e., it has |
| 1875 // to specify how to override the value before the conversion, in this |
| 1876 // case, it overwrites the stack top). |
| 1877 frame_state_before_store = environment()->Checkpoint( |
| 1878 expr->value()->id(), OutputFrameStateCombine::PokeAt(0)); |
| 1879 } |
| 1858 } | 1880 } |
| 1859 | 1881 |
| 1860 // Store the value. | 1882 // Store the value. |
| 1861 Node* value = environment()->Pop(); | 1883 Node* value = environment()->Pop(); |
| 1862 switch (assign_type) { | 1884 switch (assign_type) { |
| 1863 case VARIABLE: { | 1885 case VARIABLE: { |
| 1864 Variable* variable = expr->target()->AsVariableProxy()->var(); | 1886 Variable* variable = expr->target()->AsVariableProxy()->var(); |
| 1865 BuildVariableAssignment(variable, value, expr->op(), expr->id(), | 1887 BuildVariableAssignment(variable, value, expr->op(), expr->id(), |
| 1866 ast_context()->GetStateCombine()); | 1888 ast_context()->GetStateCombine()); |
| 1867 break; | 1889 break; |
| 1868 } | 1890 } |
| 1869 case NAMED_PROPERTY: { | 1891 case NAMED_PROPERTY: { |
| 1870 Node* object = environment()->Pop(); | 1892 Node* object = environment()->Pop(); |
| 1871 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 1893 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
| 1872 Node* store = BuildNamedStore(object, name, value); | 1894 Node* store = BuildNamedStore(object, name, value); |
| 1873 PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine()); | 1895 PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine()); |
| 1874 break; | 1896 break; |
| 1875 } | 1897 } |
| 1876 case KEYED_PROPERTY: { | 1898 case KEYED_PROPERTY: { |
| 1877 Node* key = environment()->Pop(); | 1899 Node* key = environment()->Pop(); |
| 1878 Node* object = environment()->Pop(); | 1900 Node* object = environment()->Pop(); |
| 1879 Node* store = BuildKeyedStore(object, key, value); | 1901 Node* store = BuildKeyedStore(object, key, value); |
| 1880 PrepareFrameState(store, expr->id(), ast_context()->GetStateCombine()); | 1902 PrepareFrameStateAfterAndBefore(store, expr->id(), |
| 1903 ast_context()->GetStateCombine(), |
| 1904 frame_state_before_store); |
| 1881 break; | 1905 break; |
| 1882 } | 1906 } |
| 1883 } | 1907 } |
| 1884 | 1908 |
| 1885 ast_context()->ProduceValue(value); | 1909 ast_context()->ProduceValue(value); |
| 1886 } | 1910 } |
| 1887 | 1911 |
| 1888 | 1912 |
| 1889 void AstGraphBuilder::VisitYield(Yield* expr) { | 1913 void AstGraphBuilder::VisitYield(Yield* expr) { |
| 1890 // TODO(turbofan): Implement yield here. | 1914 // TODO(turbofan): Implement yield here. |
| (...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2169 stack_depth = 2; | 2193 stack_depth = 2; |
| 2170 break; | 2194 break; |
| 2171 } | 2195 } |
| 2172 } | 2196 } |
| 2173 | 2197 |
| 2174 // Convert old value into a number. | 2198 // Convert old value into a number. |
| 2175 old_value = NewNode(javascript()->ToNumber(), old_value); | 2199 old_value = NewNode(javascript()->ToNumber(), old_value); |
| 2176 PrepareFrameState(old_value, expr->ToNumberId(), | 2200 PrepareFrameState(old_value, expr->ToNumberId(), |
| 2177 OutputFrameStateCombine::Push()); | 2201 OutputFrameStateCombine::Push()); |
| 2178 | 2202 |
| 2203 Node* frame_state_before_store = |
| 2204 assign_type == KEYED_PROPERTY |
| 2205 ? environment()->Checkpoint(expr->ToNumberId()) |
| 2206 : nullptr; |
| 2207 |
| 2179 // Save result for postfix expressions at correct stack depth. | 2208 // Save result for postfix expressions at correct stack depth. |
| 2180 if (is_postfix) environment()->Poke(stack_depth, old_value); | 2209 if (is_postfix) environment()->Poke(stack_depth, old_value); |
| 2181 | 2210 |
| 2182 // Create node to perform +1/-1 operation. | 2211 // Create node to perform +1/-1 operation. |
| 2183 Node* value = | 2212 Node* value = |
| 2184 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); | 2213 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); |
| 2185 // This should never deoptimize because we have converted to number | 2214 // This should never deoptimize because we have converted to number |
| 2186 // before. | 2215 // before. |
| 2187 PrepareFrameStateAfterAndBefore(value, BailoutId::None(), | 2216 PrepareFrameStateAfterAndBefore(value, BailoutId::None(), |
| 2188 OutputFrameStateCombine::Ignore(), | 2217 OutputFrameStateCombine::Ignore(), |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2205 environment()->Push(value); | 2234 environment()->Push(value); |
| 2206 PrepareFrameState(store, expr->AssignmentId()); | 2235 PrepareFrameState(store, expr->AssignmentId()); |
| 2207 environment()->Pop(); | 2236 environment()->Pop(); |
| 2208 break; | 2237 break; |
| 2209 } | 2238 } |
| 2210 case KEYED_PROPERTY: { | 2239 case KEYED_PROPERTY: { |
| 2211 Node* key = environment()->Pop(); | 2240 Node* key = environment()->Pop(); |
| 2212 Node* object = environment()->Pop(); | 2241 Node* object = environment()->Pop(); |
| 2213 Node* store = BuildKeyedStore(object, key, value); | 2242 Node* store = BuildKeyedStore(object, key, value); |
| 2214 environment()->Push(value); | 2243 environment()->Push(value); |
| 2215 PrepareFrameState(store, expr->AssignmentId()); | 2244 PrepareFrameStateAfterAndBefore(store, expr->AssignmentId(), |
| 2245 OutputFrameStateCombine::Ignore(), |
| 2246 frame_state_before_store); |
| 2216 environment()->Pop(); | 2247 environment()->Pop(); |
| 2217 break; | 2248 break; |
| 2218 } | 2249 } |
| 2219 } | 2250 } |
| 2220 | 2251 |
| 2221 // Restore old value for postfix expressions. | 2252 // Restore old value for postfix expressions. |
| 2222 if (is_postfix) value = environment()->Pop(); | 2253 if (is_postfix) value = environment()->Pop(); |
| 2223 | 2254 |
| 2224 ast_context()->ProduceValue(value); | 2255 ast_context()->ProduceValue(value); |
| 2225 } | 2256 } |
| (...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3348 // Phi does not exist yet, introduce one. | 3379 // Phi does not exist yet, introduce one. |
| 3349 value = NewPhi(inputs, value, control); | 3380 value = NewPhi(inputs, value, control); |
| 3350 value->ReplaceInput(inputs - 1, other); | 3381 value->ReplaceInput(inputs - 1, other); |
| 3351 } | 3382 } |
| 3352 return value; | 3383 return value; |
| 3353 } | 3384 } |
| 3354 | 3385 |
| 3355 } // namespace compiler | 3386 } // namespace compiler |
| 3356 } // namespace internal | 3387 } // namespace internal |
| 3357 } // namespace v8 | 3388 } // namespace v8 |
| OLD | NEW |