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 1368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1379 for_loop.BreakWhen(condition); | 1379 for_loop.BreakWhen(condition); |
1380 VisitForEffect(stmt->assign_each()); | 1380 VisitForEffect(stmt->assign_each()); |
1381 VisitIterationBody(stmt, &for_loop); | 1381 VisitIterationBody(stmt, &for_loop); |
1382 for_loop.EndBody(); | 1382 for_loop.EndBody(); |
1383 for_loop.EndLoop(); | 1383 for_loop.EndLoop(); |
1384 } | 1384 } |
1385 | 1385 |
1386 | 1386 |
1387 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { | 1387 void AstGraphBuilder::VisitTryCatchStatement(TryCatchStatement* stmt) { |
1388 TryCatchBuilder try_control(this); | 1388 TryCatchBuilder try_control(this); |
1389 ExternalReference message_object = | |
1390 ExternalReference::address_of_pending_message_obj(isolate()); | |
1391 | 1389 |
1392 // Evaluate the try-block inside a control scope. This simulates a handler | 1390 // Evaluate the try-block inside a control scope. This simulates a handler |
1393 // that is intercepting 'throw' control commands. | 1391 // that is intercepting 'throw' control commands. |
1394 try_control.BeginTry(); | 1392 try_control.BeginTry(); |
1395 { | 1393 { |
1396 ControlScopeForCatch scope(this, &try_control); | 1394 ControlScopeForCatch scope(this, &try_control); |
1397 STATIC_ASSERT(TryBlockConstant::kElementCount == 1); | 1395 STATIC_ASSERT(TryBlockConstant::kElementCount == 1); |
1398 environment()->Push(current_context()); | 1396 environment()->Push(current_context()); |
1399 Visit(stmt->try_block()); | 1397 Visit(stmt->try_block()); |
1400 environment()->Pop(); | 1398 environment()->Pop(); |
1401 } | 1399 } |
1402 try_control.EndTry(); | 1400 try_control.EndTry(); |
1403 | 1401 |
1404 // Insert lazy bailout point. | 1402 // Insert lazy bailout point. |
1405 // TODO(mstarzinger): We are only using a 'call' to get a lazy bailout | 1403 // TODO(mstarzinger): We are only using a 'call' to get a lazy bailout |
1406 // point. Ideally, we whould not re-enter optimized code when deoptimized | 1404 // point. Ideally, we whould not re-enter optimized code when deoptimized |
1407 // lazily. Tracked by issue v8:4195. | 1405 // lazily. Tracked by issue v8:4195. |
1408 NewNode(common()->LazyBailout(), | 1406 NewNode(common()->LazyBailout(), |
1409 jsgraph()->ZeroConstant(), // dummy target. | 1407 jsgraph()->ZeroConstant(), // dummy target. |
1410 environment()->Checkpoint(stmt->HandlerId())); // frame state. | 1408 environment()->Checkpoint(stmt->HandlerId())); // frame state. |
1411 | 1409 |
1412 // Clear message object as we enter the catch block. | 1410 // Clear message object as we enter the catch block. |
1413 Node* the_hole = jsgraph()->TheHoleConstant(); | 1411 Node* the_hole = jsgraph()->TheHoleConstant(); |
1414 BuildStoreExternal(message_object, kMachAnyTagged, the_hole); | 1412 NewNode(javascript()->StoreMessage(), the_hole); |
1415 | 1413 |
1416 // Create a catch scope that binds the exception. | 1414 // Create a catch scope that binds the exception. |
1417 Node* exception = try_control.GetExceptionNode(); | 1415 Node* exception = try_control.GetExceptionNode(); |
1418 Handle<String> name = stmt->variable()->name(); | 1416 Handle<String> name = stmt->variable()->name(); |
1419 const Operator* op = javascript()->CreateCatchContext(name); | 1417 const Operator* op = javascript()->CreateCatchContext(name); |
1420 Node* context = NewNode(op, exception, GetFunctionClosureForContext()); | 1418 Node* context = NewNode(op, exception, GetFunctionClosureForContext()); |
1421 | 1419 |
1422 // Evaluate the catch-block. | 1420 // Evaluate the catch-block. |
1423 VisitInScope(stmt->catch_block(), stmt->scope(), context); | 1421 VisitInScope(stmt->catch_block(), stmt->scope(), context); |
1424 try_control.EndCatch(); | 1422 try_control.EndCatch(); |
1425 } | 1423 } |
1426 | 1424 |
1427 | 1425 |
1428 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { | 1426 void AstGraphBuilder::VisitTryFinallyStatement(TryFinallyStatement* stmt) { |
1429 TryFinallyBuilder try_control(this); | 1427 TryFinallyBuilder try_control(this); |
1430 ExternalReference message_object = | |
1431 ExternalReference::address_of_pending_message_obj(isolate()); | |
1432 | 1428 |
1433 // We keep a record of all paths that enter the finally-block to be able to | 1429 // We keep a record of all paths that enter the finally-block to be able to |
1434 // dispatch to the correct continuation point after the statements in the | 1430 // dispatch to the correct continuation point after the statements in the |
1435 // finally-block have been evaluated. | 1431 // finally-block have been evaluated. |
1436 // | 1432 // |
1437 // The try-finally construct can enter the finally-block in three ways: | 1433 // The try-finally construct can enter the finally-block in three ways: |
1438 // 1. By exiting the try-block normally, falling through at the end. | 1434 // 1. By exiting the try-block normally, falling through at the end. |
1439 // 2. By exiting the try-block with a function-local control flow transfer | 1435 // 2. By exiting the try-block with a function-local control flow transfer |
1440 // (i.e. through break/continue/return statements). | 1436 // (i.e. through break/continue/return statements). |
1441 // 3. By exiting the try-block with a thrown exception. | 1437 // 3. By exiting the try-block with a thrown exception. |
(...skipping 24 matching lines...) Expand all Loading... |
1466 // The result value semantics depend on how the block was entered: | 1462 // The result value semantics depend on how the block was entered: |
1467 // - ReturnStatement: It represents the return value being returned. | 1463 // - ReturnStatement: It represents the return value being returned. |
1468 // - ThrowStatement: It represents the exception being thrown. | 1464 // - ThrowStatement: It represents the exception being thrown. |
1469 // - BreakStatement/ContinueStatement: Filled with the hole. | 1465 // - BreakStatement/ContinueStatement: Filled with the hole. |
1470 // - Falling through into finally-block: Filled with the hole. | 1466 // - Falling through into finally-block: Filled with the hole. |
1471 Node* result = try_control.GetResultValueNode(); | 1467 Node* result = try_control.GetResultValueNode(); |
1472 Node* token = try_control.GetDispatchTokenNode(); | 1468 Node* token = try_control.GetDispatchTokenNode(); |
1473 | 1469 |
1474 // The result value, dispatch token and message is expected on the operand | 1470 // The result value, dispatch token and message is expected on the operand |
1475 // stack (this is in sync with FullCodeGenerator::EnterFinallyBlock). | 1471 // stack (this is in sync with FullCodeGenerator::EnterFinallyBlock). |
1476 Node* message = BuildLoadExternal(message_object, kMachAnyTagged); | 1472 Node* message = NewNode(javascript()->LoadMessage()); |
1477 environment()->Push(token); // TODO(mstarzinger): Cook token! | 1473 environment()->Push(token); // TODO(mstarzinger): Cook token! |
1478 environment()->Push(result); | 1474 environment()->Push(result); |
1479 environment()->Push(message); | 1475 environment()->Push(message); |
1480 | 1476 |
1481 // Clear message object as we enter the finally block. | 1477 // Clear message object as we enter the finally block. |
1482 Node* the_hole = jsgraph()->TheHoleConstant(); | 1478 Node* the_hole = jsgraph()->TheHoleConstant(); |
1483 BuildStoreExternal(message_object, kMachAnyTagged, the_hole); | 1479 NewNode(javascript()->StoreMessage(), the_hole); |
1484 | 1480 |
1485 // Evaluate the finally-block. | 1481 // Evaluate the finally-block. |
1486 Visit(stmt->finally_block()); | 1482 Visit(stmt->finally_block()); |
1487 try_control.EndFinally(); | 1483 try_control.EndFinally(); |
1488 | 1484 |
1489 // The result value, dispatch token and message is restored from the operand | 1485 // The result value, dispatch token and message is restored from the operand |
1490 // stack (this is in sync with FullCodeGenerator::ExitFinallyBlock). | 1486 // stack (this is in sync with FullCodeGenerator::ExitFinallyBlock). |
1491 message = environment()->Pop(); | 1487 message = environment()->Pop(); |
1492 result = environment()->Pop(); | 1488 result = environment()->Pop(); |
1493 token = environment()->Pop(); // TODO(mstarzinger): Uncook token! | 1489 token = environment()->Pop(); // TODO(mstarzinger): Uncook token! |
1494 BuildStoreExternal(message_object, kMachAnyTagged, message); | 1490 NewNode(javascript()->StoreMessage(), message); |
1495 | 1491 |
1496 // Dynamic dispatch after the finally-block. | 1492 // Dynamic dispatch after the finally-block. |
1497 commands->ApplyDeferredCommands(token, result); | 1493 commands->ApplyDeferredCommands(token, result); |
1498 | 1494 |
1499 // TODO(mstarzinger): Remove bailout once everything works. | 1495 // TODO(mstarzinger): Remove bailout once everything works. |
1500 if (!FLAG_turbo_try_finally) SetStackOverflow(); | 1496 if (!FLAG_turbo_try_finally) SetStackOverflow(); |
1501 } | 1497 } |
1502 | 1498 |
1503 | 1499 |
1504 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { | 1500 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { |
(...skipping 2166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3671 Node* shared = BuildLoadImmutableObjectField( | 3667 Node* shared = BuildLoadImmutableObjectField( |
3672 closure, JSFunction::kSharedFunctionInfoOffset); | 3668 closure, JSFunction::kSharedFunctionInfoOffset); |
3673 Node* vector = BuildLoadImmutableObjectField( | 3669 Node* vector = BuildLoadImmutableObjectField( |
3674 shared, SharedFunctionInfo::kFeedbackVectorOffset); | 3670 shared, SharedFunctionInfo::kFeedbackVectorOffset); |
3675 feedback_vector_.set(vector); | 3671 feedback_vector_.set(vector); |
3676 } | 3672 } |
3677 return feedback_vector_.get(); | 3673 return feedback_vector_.get(); |
3678 } | 3674 } |
3679 | 3675 |
3680 | 3676 |
3681 Node* AstGraphBuilder::BuildLoadExternal(ExternalReference reference, | |
3682 MachineType type) { | |
3683 return NewNode(jsgraph()->machine()->Load(type), | |
3684 jsgraph()->ExternalConstant(reference), | |
3685 jsgraph()->IntPtrConstant(0)); | |
3686 } | |
3687 | |
3688 | |
3689 Node* AstGraphBuilder::BuildStoreExternal(ExternalReference reference, | |
3690 MachineType type, Node* value) { | |
3691 StoreRepresentation representation(type, kNoWriteBarrier); | |
3692 return NewNode(jsgraph()->machine()->Store(representation), | |
3693 jsgraph()->ExternalConstant(reference), | |
3694 jsgraph()->IntPtrConstant(0), value); | |
3695 } | |
3696 | |
3697 | |
3698 Node* AstGraphBuilder::BuildToBoolean(Node* input) { | 3677 Node* AstGraphBuilder::BuildToBoolean(Node* input) { |
3699 if (Node* node = TryFastToBoolean(input)) return node; | 3678 if (Node* node = TryFastToBoolean(input)) return node; |
3700 return NewNode(javascript()->ToBoolean(), input); | 3679 return NewNode(javascript()->ToBoolean(), input); |
3701 } | 3680 } |
3702 | 3681 |
3703 | 3682 |
3704 Node* AstGraphBuilder::BuildToName(Node* input, BailoutId bailout_id) { | 3683 Node* AstGraphBuilder::BuildToName(Node* input, BailoutId bailout_id) { |
3705 if (Node* node = TryFastToName(input)) return node; | 3684 if (Node* node = TryFastToName(input)) return node; |
3706 Node* name = NewNode(javascript()->ToName(), input); | 3685 Node* name = NewNode(javascript()->ToName(), input); |
3707 PrepareFrameState(name, bailout_id); | 3686 PrepareFrameState(name, bailout_id); |
(...skipping 617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4325 // Phi does not exist yet, introduce one. | 4304 // Phi does not exist yet, introduce one. |
4326 value = NewPhi(inputs, value, control); | 4305 value = NewPhi(inputs, value, control); |
4327 value->ReplaceInput(inputs - 1, other); | 4306 value->ReplaceInput(inputs - 1, other); |
4328 } | 4307 } |
4329 return value; | 4308 return value; |
4330 } | 4309 } |
4331 | 4310 |
4332 } // namespace compiler | 4311 } // namespace compiler |
4333 } // namespace internal | 4312 } // namespace internal |
4334 } // namespace v8 | 4313 } // namespace v8 |
OLD | NEW |