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 |