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