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 |