| 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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 // Helper for generating before and after frame states. | 387 // Helper for generating before and after frame states. |
| 388 class AstGraphBuilder::FrameStateBeforeAndAfter { | 388 class AstGraphBuilder::FrameStateBeforeAndAfter { |
| 389 public: | 389 public: |
| 390 FrameStateBeforeAndAfter(AstGraphBuilder* builder, BailoutId id_before) | 390 FrameStateBeforeAndAfter(AstGraphBuilder* builder, BailoutId id_before) |
| 391 : builder_(builder), frame_state_before_(nullptr) { | 391 : builder_(builder), frame_state_before_(nullptr) { |
| 392 frame_state_before_ = id_before == BailoutId::None() | 392 frame_state_before_ = id_before == BailoutId::None() |
| 393 ? builder_->jsgraph()->EmptyFrameState() | 393 ? builder_->jsgraph()->EmptyFrameState() |
| 394 : builder_->environment()->Checkpoint(id_before); | 394 : builder_->environment()->Checkpoint(id_before); |
| 395 } | 395 } |
| 396 | 396 |
| 397 void AddToNode(Node* node, BailoutId id_after, | 397 void AddToNode( |
| 398 OutputFrameStateCombine combine) { | 398 Node* node, BailoutId id_after, |
| 399 OutputFrameStateCombine combine = OutputFrameStateCombine::Ignore()) { |
| 399 int count = OperatorProperties::GetFrameStateInputCount(node->op()); | 400 int count = OperatorProperties::GetFrameStateInputCount(node->op()); |
| 400 DCHECK_LE(count, 2); | 401 DCHECK_LE(count, 2); |
| 401 | 402 |
| 402 if (count >= 1) { | 403 if (count >= 1) { |
| 403 // Add the frame state for after the operation. | 404 // Add the frame state for after the operation. |
| 404 DCHECK_EQ(IrOpcode::kDead, | 405 DCHECK_EQ(IrOpcode::kDead, |
| 405 NodeProperties::GetFrameStateInput(node, 0)->opcode()); | 406 NodeProperties::GetFrameStateInput(node, 0)->opcode()); |
| 406 | 407 |
| 407 Node* frame_state_after = | 408 Node* frame_state_after = |
| 408 id_after == BailoutId::None() | 409 id_after == BailoutId::None() |
| (...skipping 1546 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1955 // (inclusive) and these elements gets appended to the array. Note that the | 1956 // (inclusive) and these elements gets appended to the array. Note that the |
| 1956 // number elements an iterable produces is unknown ahead of time. | 1957 // number elements an iterable produces is unknown ahead of time. |
| 1957 environment()->Pop(); // Array literal index. | 1958 environment()->Pop(); // Array literal index. |
| 1958 for (; array_index < expr->values()->length(); array_index++) { | 1959 for (; array_index < expr->values()->length(); array_index++) { |
| 1959 Expression* subexpr = expr->values()->at(array_index); | 1960 Expression* subexpr = expr->values()->at(array_index); |
| 1960 Node* array = environment()->Pop(); | 1961 Node* array = environment()->Pop(); |
| 1961 Node* result; | 1962 Node* result; |
| 1962 | 1963 |
| 1963 if (subexpr->IsSpread()) { | 1964 if (subexpr->IsSpread()) { |
| 1964 VisitForValue(subexpr->AsSpread()->expression()); | 1965 VisitForValue(subexpr->AsSpread()->expression()); |
| 1966 FrameStateBeforeAndAfter states(this, |
| 1967 subexpr->AsSpread()->expression()->id()); |
| 1965 Node* iterable = environment()->Pop(); | 1968 Node* iterable = environment()->Pop(); |
| 1966 Node* function = BuildLoadNativeContextField( | 1969 Node* function = BuildLoadNativeContextField( |
| 1967 Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX); | 1970 Context::CONCAT_ITERABLE_TO_ARRAY_BUILTIN_INDEX); |
| 1968 result = NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS, | 1971 result = NewNode(javascript()->CallFunction(3, NO_CALL_FUNCTION_FLAGS, |
| 1969 language_mode()), | 1972 language_mode()), |
| 1970 function, array, iterable); | 1973 function, array, iterable); |
| 1974 states.AddToNode(result, expr->GetIdForElement(array_index)); |
| 1971 } else { | 1975 } else { |
| 1972 VisitForValue(subexpr); | 1976 VisitForValue(subexpr); |
| 1973 Node* value = environment()->Pop(); | 1977 Node* value = environment()->Pop(); |
| 1974 const Operator* op = | 1978 const Operator* op = |
| 1975 javascript()->CallRuntime(Runtime::kAppendElement, 2); | 1979 javascript()->CallRuntime(Runtime::kAppendElement, 2); |
| 1976 result = NewNode(op, array, value); | 1980 result = NewNode(op, array, value); |
| 1981 PrepareFrameState(result, expr->GetIdForElement(array_index)); |
| 1977 } | 1982 } |
| 1978 | 1983 |
| 1979 PrepareFrameState(result, expr->GetIdForElement(array_index)); | |
| 1980 environment()->Push(result); | 1984 environment()->Push(result); |
| 1981 } | 1985 } |
| 1982 | 1986 |
| 1983 ast_context()->ProduceValue(environment()->Pop()); | 1987 ast_context()->ProduceValue(environment()->Pop()); |
| 1984 } | 1988 } |
| 1985 | 1989 |
| 1986 | 1990 |
| 1987 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, | 1991 void AstGraphBuilder::VisitForInAssignment(Expression* expr, Node* value, |
| 1988 const VectorSlotPair& feedback, | 1992 const VectorSlotPair& feedback, |
| 1989 BailoutId bailout_id_before, | 1993 BailoutId bailout_id_before, |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2482 OutputFrameStateCombine::PokeAt(arg_count + 1)); | 2486 OutputFrameStateCombine::PokeAt(arg_count + 1)); |
| 2483 | 2487 |
| 2484 // Patch callee on the environment. | 2488 // Patch callee on the environment. |
| 2485 environment()->Poke(arg_count + 1, new_callee); | 2489 environment()->Poke(arg_count + 1, new_callee); |
| 2486 } | 2490 } |
| 2487 | 2491 |
| 2488 // Create node to perform the function call. | 2492 // Create node to perform the function call. |
| 2489 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); | 2493 VectorSlotPair feedback = CreateVectorSlotPair(expr->CallFeedbackICSlot()); |
| 2490 const Operator* call = javascript()->CallFunction( | 2494 const Operator* call = javascript()->CallFunction( |
| 2491 args->length() + 2, flags, language_mode(), feedback, receiver_hint); | 2495 args->length() + 2, flags, language_mode(), feedback, receiver_hint); |
| 2496 FrameStateBeforeAndAfter states(this, expr->CallId()); |
| 2492 Node* value = ProcessArguments(call, args->length() + 2); | 2497 Node* value = ProcessArguments(call, args->length() + 2); |
| 2493 environment()->Push(value->InputAt(0)); // The callee passed to the call. | 2498 environment()->Push(value->InputAt(0)); // The callee passed to the call. |
| 2494 PrepareFrameState(value, expr->ReturnId(), OutputFrameStateCombine::Push()); | 2499 states.AddToNode(value, expr->ReturnId(), OutputFrameStateCombine::Push()); |
| 2495 environment()->Drop(1); | 2500 environment()->Drop(1); |
| 2496 ast_context()->ProduceValue(value); | 2501 ast_context()->ProduceValue(value); |
| 2497 } | 2502 } |
| 2498 | 2503 |
| 2499 | 2504 |
| 2500 void AstGraphBuilder::VisitCallSuper(Call* expr) { | 2505 void AstGraphBuilder::VisitCallSuper(Call* expr) { |
| 2501 SuperCallReference* super = expr->expression()->AsSuperCallReference(); | 2506 SuperCallReference* super = expr->expression()->AsSuperCallReference(); |
| 2502 DCHECK_NOT_NULL(super); | 2507 DCHECK_NOT_NULL(super); |
| 2503 | 2508 |
| 2504 // Prepare the callee to the super call. The super constructor is stored as | 2509 // Prepare the callee to the super call. The super constructor is stored as |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2554 environment()->Push(callee_value); | 2559 environment()->Push(callee_value); |
| 2555 environment()->Push(receiver_value); | 2560 environment()->Push(receiver_value); |
| 2556 | 2561 |
| 2557 // Evaluate all arguments to the JS runtime call. | 2562 // Evaluate all arguments to the JS runtime call. |
| 2558 ZoneList<Expression*>* args = expr->arguments(); | 2563 ZoneList<Expression*>* args = expr->arguments(); |
| 2559 VisitForValues(args); | 2564 VisitForValues(args); |
| 2560 | 2565 |
| 2561 // Create node to perform the JS runtime call. | 2566 // Create node to perform the JS runtime call. |
| 2562 const Operator* call = | 2567 const Operator* call = |
| 2563 javascript()->CallFunction(args->length() + 2, flags, language_mode()); | 2568 javascript()->CallFunction(args->length() + 2, flags, language_mode()); |
| 2569 FrameStateBeforeAndAfter states(this, expr->CallId()); |
| 2564 Node* value = ProcessArguments(call, args->length() + 2); | 2570 Node* value = ProcessArguments(call, args->length() + 2); |
| 2565 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2571 states.AddToNode(value, expr->id(), ast_context()->GetStateCombine()); |
| 2566 ast_context()->ProduceValue(value); | 2572 ast_context()->ProduceValue(value); |
| 2567 } | 2573 } |
| 2568 | 2574 |
| 2569 | 2575 |
| 2570 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 2576 void AstGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
| 2571 // Handle calls to runtime functions implemented in JavaScript separately as | 2577 // Handle calls to runtime functions implemented in JavaScript separately as |
| 2572 // the call follows JavaScript ABI and the callee is statically unknown. | 2578 // the call follows JavaScript ABI and the callee is statically unknown. |
| 2573 if (expr->is_jsruntime()) { | 2579 if (expr->is_jsruntime()) { |
| 2574 return VisitCallJSRuntime(expr); | 2580 return VisitCallJSRuntime(expr); |
| 2575 } | 2581 } |
| (...skipping 1677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4253 // Phi does not exist yet, introduce one. | 4259 // Phi does not exist yet, introduce one. |
| 4254 value = NewPhi(inputs, value, control); | 4260 value = NewPhi(inputs, value, control); |
| 4255 value->ReplaceInput(inputs - 1, other); | 4261 value->ReplaceInput(inputs - 1, other); |
| 4256 } | 4262 } |
| 4257 return value; | 4263 return value; |
| 4258 } | 4264 } |
| 4259 | 4265 |
| 4260 } // namespace compiler | 4266 } // namespace compiler |
| 4261 } // namespace internal | 4267 } // namespace internal |
| 4262 } // namespace v8 | 4268 } // namespace v8 |
| OLD | NEW |