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/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" |
(...skipping 1341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1352 IfBuilder test_value(this); | 1352 IfBuilder test_value(this); |
1353 Node* test_value_cond = NewNode(javascript()->StrictEqual(), value, | 1353 Node* test_value_cond = NewNode(javascript()->StrictEqual(), value, |
1354 jsgraph()->UndefinedConstant()); | 1354 jsgraph()->UndefinedConstant()); |
1355 test_value.If(test_value_cond, BranchHint::kFalse); | 1355 test_value.If(test_value_cond, BranchHint::kFalse); |
1356 test_value.Then(); | 1356 test_value.Then(); |
1357 test_value.Else(); | 1357 test_value.Else(); |
1358 { | 1358 { |
1359 // Bind value and do loop body. | 1359 // Bind value and do loop body. |
1360 VectorSlotPair feedback = | 1360 VectorSlotPair feedback = |
1361 CreateVectorSlotPair(stmt->EachFeedbackSlot()); | 1361 CreateVectorSlotPair(stmt->EachFeedbackSlot()); |
1362 VisitForInAssignment(stmt->each(), value, feedback, | 1362 VisitForInAssignment(stmt->each(), value, feedback, stmt->FilterId(), |
1363 stmt->AssignmentId()); | 1363 stmt->AssignmentId()); |
1364 VisitIterationBody(stmt, &for_loop); | 1364 VisitIterationBody(stmt, &for_loop); |
1365 } | 1365 } |
1366 test_value.End(); | 1366 test_value.End(); |
1367 index = environment()->Peek(0); | 1367 index = environment()->Peek(0); |
1368 for_loop.EndBody(); | 1368 for_loop.EndBody(); |
1369 | 1369 |
1370 // Increment counter and continue. | 1370 // Increment counter and continue. |
1371 index = NewNode(javascript()->ForInStep(), index); | 1371 index = NewNode(javascript()->ForInStep(), index); |
1372 environment()->Poke(0, index); | 1372 environment()->Poke(0, index); |
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1980 PrepareFrameState(result, expr->GetIdForElement(array_index)); | 1980 PrepareFrameState(result, expr->GetIdForElement(array_index)); |
1981 environment()->Push(result); | 1981 environment()->Push(result); |
1982 } | 1982 } |
1983 | 1983 |
1984 ast_context()->ProduceValue(environment()->Pop()); | 1984 ast_context()->ProduceValue(environment()->Pop()); |
1985 } | 1985 } |
1986 | 1986 |
1987 | 1987 |
1988 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, | 1988 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, |
1989 const VectorSlotPair& feedback, | 1989 const VectorSlotPair& feedback, |
1990 BailoutId bailout_id) { | 1990 BailoutId bailout_id_before, |
| 1991 BailoutId bailout_id_after) { |
1991 DCHECK(expr->IsValidReferenceExpressionOrThis()); | 1992 DCHECK(expr->IsValidReferenceExpressionOrThis()); |
1992 | 1993 |
1993 // Left-hand side can only be a property, a global or a variable slot. | 1994 // Left-hand side can only be a property, a global or a variable slot. |
1994 Property* property = expr->AsProperty(); | 1995 Property* property = expr->AsProperty(); |
1995 LhsKind assign_type = Property::GetAssignType(property); | 1996 LhsKind assign_type = Property::GetAssignType(property); |
1996 | 1997 |
1997 // Evaluate LHS expression and store the value. | 1998 // Evaluate LHS expression and store the value. |
1998 switch (assign_type) { | 1999 switch (assign_type) { |
1999 case VARIABLE: { | 2000 case VARIABLE: { |
2000 Variable* var = expr->AsVariableProxy()->var(); | 2001 Variable* var = expr->AsVariableProxy()->var(); |
2001 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 2002 environment()->Push(value); |
2002 BuildVariableAssignment(var, value, Token::ASSIGN, feedback, bailout_id, | 2003 FrameStateBeforeAndAfter states(this, bailout_id_before); |
2003 states); | 2004 value = environment()->Pop(); |
| 2005 BuildVariableAssignment(var, value, Token::ASSIGN, feedback, |
| 2006 bailout_id_after, states); |
2004 break; | 2007 break; |
2005 } | 2008 } |
2006 case NAMED_PROPERTY: { | 2009 case NAMED_PROPERTY: { |
2007 environment()->Push(value); | 2010 environment()->Push(value); |
2008 VisitForValue(property->obj()); | 2011 VisitForValue(property->obj()); |
2009 FrameStateBeforeAndAfter states(this, property->obj()->id()); | 2012 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
2010 Node* object = environment()->Pop(); | 2013 Node* object = environment()->Pop(); |
2011 value = environment()->Pop(); | 2014 value = environment()->Pop(); |
2012 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2015 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2013 Node* store = BuildNamedStore(object, name, value, feedback, | 2016 Node* store = BuildNamedStore(object, name, value, feedback, |
2014 TypeFeedbackId::None()); | 2017 TypeFeedbackId::None()); |
2015 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); | 2018 states.AddToNode(store, bailout_id_after, |
| 2019 OutputFrameStateCombine::Ignore()); |
2016 break; | 2020 break; |
2017 } | 2021 } |
2018 case KEYED_PROPERTY: { | 2022 case KEYED_PROPERTY: { |
2019 environment()->Push(value); | 2023 environment()->Push(value); |
2020 VisitForValue(property->obj()); | 2024 VisitForValue(property->obj()); |
2021 VisitForValue(property->key()); | 2025 VisitForValue(property->key()); |
2022 FrameStateBeforeAndAfter states(this, property->key()->id()); | 2026 FrameStateBeforeAndAfter states(this, property->key()->id()); |
2023 Node* key = environment()->Pop(); | 2027 Node* key = environment()->Pop(); |
2024 Node* object = environment()->Pop(); | 2028 Node* object = environment()->Pop(); |
2025 value = environment()->Pop(); | 2029 value = environment()->Pop(); |
2026 Node* store = | 2030 Node* store = |
2027 BuildKeyedStore(object, key, value, feedback, TypeFeedbackId::None()); | 2031 BuildKeyedStore(object, key, value, feedback, TypeFeedbackId::None()); |
2028 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); | 2032 states.AddToNode(store, bailout_id_after, |
| 2033 OutputFrameStateCombine::Ignore()); |
2029 break; | 2034 break; |
2030 } | 2035 } |
2031 case NAMED_SUPER_PROPERTY: { | 2036 case NAMED_SUPER_PROPERTY: { |
2032 environment()->Push(value); | 2037 environment()->Push(value); |
2033 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2038 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
2034 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2039 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
2035 FrameStateBeforeAndAfter states(this, property->obj()->id()); | 2040 FrameStateBeforeAndAfter states(this, property->obj()->id()); |
2036 Node* home_object = environment()->Pop(); | 2041 Node* home_object = environment()->Pop(); |
2037 Node* receiver = environment()->Pop(); | 2042 Node* receiver = environment()->Pop(); |
2038 value = environment()->Pop(); | 2043 value = environment()->Pop(); |
2039 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); | 2044 Handle<Name> name = property->key()->AsLiteral()->AsPropertyName(); |
2040 Node* store = BuildNamedSuperStore(receiver, home_object, name, value, | 2045 Node* store = BuildNamedSuperStore(receiver, home_object, name, value, |
2041 TypeFeedbackId::None()); | 2046 TypeFeedbackId::None()); |
2042 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); | 2047 states.AddToNode(store, bailout_id_after, |
| 2048 OutputFrameStateCombine::Ignore()); |
2043 break; | 2049 break; |
2044 } | 2050 } |
2045 case KEYED_SUPER_PROPERTY: { | 2051 case KEYED_SUPER_PROPERTY: { |
2046 environment()->Push(value); | 2052 environment()->Push(value); |
2047 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); | 2053 VisitForValue(property->obj()->AsSuperPropertyReference()->this_var()); |
2048 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); | 2054 VisitForValue(property->obj()->AsSuperPropertyReference()->home_object()); |
2049 VisitForValue(property->key()); | 2055 VisitForValue(property->key()); |
2050 FrameStateBeforeAndAfter states(this, property->key()->id()); | 2056 FrameStateBeforeAndAfter states(this, property->key()->id()); |
2051 Node* key = environment()->Pop(); | 2057 Node* key = environment()->Pop(); |
2052 Node* home_object = environment()->Pop(); | 2058 Node* home_object = environment()->Pop(); |
2053 Node* receiver = environment()->Pop(); | 2059 Node* receiver = environment()->Pop(); |
2054 value = environment()->Pop(); | 2060 value = environment()->Pop(); |
2055 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value, | 2061 Node* store = BuildKeyedSuperStore(receiver, home_object, key, value, |
2056 TypeFeedbackId::None()); | 2062 TypeFeedbackId::None()); |
2057 states.AddToNode(store, bailout_id, OutputFrameStateCombine::Ignore()); | 2063 states.AddToNode(store, bailout_id_after, |
| 2064 OutputFrameStateCombine::Ignore()); |
2058 break; | 2065 break; |
2059 } | 2066 } |
2060 } | 2067 } |
2061 } | 2068 } |
2062 | 2069 |
2063 | 2070 |
2064 void AstGraphBuilder::VisitAssignment(Assignment* expr) { | 2071 void AstGraphBuilder::VisitAssignment(Assignment* expr) { |
2065 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); | 2072 DCHECK(expr->target()->IsValidReferenceExpressionOrThis()); |
2066 | 2073 |
2067 // Left-hand side can only be a property, a global or a variable slot. | 2074 // Left-hand side can only be a property, a global or a variable slot. |
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2668 } | 2675 } |
2669 } | 2676 } |
2670 | 2677 |
2671 // Convert old value into a number. | 2678 // Convert old value into a number. |
2672 if (!is_strong(language_mode())) { | 2679 if (!is_strong(language_mode())) { |
2673 old_value = NewNode(javascript()->ToNumber(), old_value); | 2680 old_value = NewNode(javascript()->ToNumber(), old_value); |
2674 PrepareFrameState(old_value, expr->ToNumberId(), | 2681 PrepareFrameState(old_value, expr->ToNumberId(), |
2675 OutputFrameStateCombine::Push()); | 2682 OutputFrameStateCombine::Push()); |
2676 } | 2683 } |
2677 | 2684 |
2678 // TODO(titzer): combine this framestate with the above? | |
2679 FrameStateBeforeAndAfter store_states(this, assign_type == KEYED_PROPERTY | |
2680 ? expr->ToNumberId() | |
2681 : BailoutId::None()); | |
2682 | |
2683 // Save result for postfix expressions at correct stack depth. | 2685 // Save result for postfix expressions at correct stack depth. |
2684 if (is_postfix) environment()->Poke(stack_depth, old_value); | 2686 if (is_postfix) { |
| 2687 environment()->Poke(stack_depth, old_value); |
| 2688 } else { |
| 2689 environment()->Push(old_value); |
| 2690 } |
| 2691 // TODO(bmeurer): This might not match the fullcodegen in case of non VARIABLE |
| 2692 // eager deoptimization; we will figure out when we get there. |
| 2693 FrameStateBeforeAndAfter store_states(this, expr->ToNumberId()); |
| 2694 if (!is_postfix) old_value = environment()->Pop(); |
2685 | 2695 |
2686 // Create node to perform +1/-1 operation. | 2696 // Create node to perform +1/-1 operation. |
2687 Node* value; | 2697 Node* value; |
2688 { | 2698 { |
2689 FrameStateBeforeAndAfter states(this, BailoutId::None()); | 2699 FrameStateBeforeAndAfter states(this, BailoutId::None()); |
2690 value = | 2700 value = |
2691 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); | 2701 BuildBinaryOp(old_value, jsgraph()->OneConstant(), expr->binary_op()); |
2692 // This should never deoptimize outside strong mode because otherwise we | 2702 // This should never deoptimize outside strong mode because otherwise we |
2693 // have converted to number before. | 2703 // have converted to number before. |
2694 states.AddToNode(value, is_strong(language_mode()) ? expr->ToNumberId() | 2704 states.AddToNode(value, is_strong(language_mode()) ? expr->ToNumberId() |
(...skipping 1583 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4278 // Phi does not exist yet, introduce one. | 4288 // Phi does not exist yet, introduce one. |
4279 value = NewPhi(inputs, value, control); | 4289 value = NewPhi(inputs, value, control); |
4280 value->ReplaceInput(inputs - 1, other); | 4290 value->ReplaceInput(inputs - 1, other); |
4281 } | 4291 } |
4282 return value; | 4292 return value; |
4283 } | 4293 } |
4284 | 4294 |
4285 } // namespace compiler | 4295 } // namespace compiler |
4286 } // namespace internal | 4296 } // namespace internal |
4287 } // namespace v8 | 4297 } // namespace v8 |
OLD | NEW |