| 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 |