OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
496 HConstant* HGraph::GetConstantTrue() { | 496 HConstant* HGraph::GetConstantTrue() { |
497 return GetConstant(&constant_true_, Heap::true_value()); | 497 return GetConstant(&constant_true_, Heap::true_value()); |
498 } | 498 } |
499 | 499 |
500 | 500 |
501 HConstant* HGraph::GetConstantFalse() { | 501 HConstant* HGraph::GetConstantFalse() { |
502 return GetConstant(&constant_false_, Heap::false_value()); | 502 return GetConstant(&constant_false_, Heap::false_value()); |
503 } | 503 } |
504 | 504 |
505 | 505 |
506 void HSubgraph::AppendOptional(HSubgraph* graph, | |
507 bool on_true_branch, | |
508 HValue* value) { | |
509 ASSERT(HasExit() && graph->HasExit()); | |
510 HBasicBlock* other_block = graph_->CreateBasicBlock(); | |
511 HBasicBlock* join_block = graph_->CreateBasicBlock(); | |
512 | |
513 HTest* test = on_true_branch | |
514 ? new HTest(value, graph->entry_block(), other_block) | |
515 : new HTest(value, other_block, graph->entry_block()); | |
516 exit_block_->Finish(test); | |
517 other_block->Goto(join_block); | |
518 graph->exit_block()->Goto(join_block); | |
519 exit_block_ = join_block; | |
520 } | |
521 | |
522 | |
523 void HSubgraph::AppendJoin(HSubgraph* then_graph, | 506 void HSubgraph::AppendJoin(HSubgraph* then_graph, |
524 HSubgraph* else_graph, | 507 HSubgraph* else_graph, |
525 AstNode* node) { | 508 AstNode* node) { |
526 if (then_graph->HasExit() && else_graph->HasExit()) { | 509 if (then_graph->HasExit() && else_graph->HasExit()) { |
527 // We need to merge, create new merge block. | 510 // We need to merge, create new merge block. |
528 HBasicBlock* join_block = graph_->CreateBasicBlock(); | 511 HBasicBlock* join_block = graph_->CreateBasicBlock(); |
529 then_graph->exit_block()->Goto(join_block); | 512 then_graph->exit_block()->Goto(join_block); |
530 else_graph->exit_block()->Goto(join_block); | 513 else_graph->exit_block()->Goto(join_block); |
531 join_block->SetJoinId(node->id()); | 514 join_block->SetJoinId(node->id()); |
532 exit_block_ = join_block; | 515 exit_block_ = join_block; |
(...skipping 4054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4587 BAILOUT("delete with global variable"); | 4570 BAILOUT("delete with global variable"); |
4588 } else { | 4571 } else { |
4589 BAILOUT("delete with non-global variable"); | 4572 BAILOUT("delete with non-global variable"); |
4590 } | 4573 } |
4591 } else if (op == Token::NOT) { | 4574 } else if (op == Token::NOT) { |
4592 if (ast_context()->IsTest()) { | 4575 if (ast_context()->IsTest()) { |
4593 TestContext* context = TestContext::cast(ast_context()); | 4576 TestContext* context = TestContext::cast(ast_context()); |
4594 VisitForControl(expr->expression(), | 4577 VisitForControl(expr->expression(), |
4595 context->if_false(), | 4578 context->if_false(), |
4596 context->if_true()); | 4579 context->if_true()); |
4597 } else { | 4580 } else if (ast_context()->IsValue()) { |
4598 HSubgraph* true_graph = CreateEmptySubgraph(); | 4581 HSubgraph* true_graph = CreateEmptySubgraph(); |
4599 HSubgraph* false_graph = CreateEmptySubgraph(); | 4582 HSubgraph* false_graph = CreateEmptySubgraph(); |
4600 VISIT_FOR_CONTROL(expr->expression(), | 4583 VISIT_FOR_CONTROL(expr->expression(), |
4601 false_graph->entry_block(), | 4584 false_graph->entry_block(), |
4602 true_graph->entry_block()); | 4585 true_graph->entry_block()); |
4603 true_graph->entry_block()->SetJoinId(expr->expression()->id()); | 4586 true_graph->entry_block()->SetJoinId(expr->expression()->id()); |
4604 true_graph->environment()->Push(graph_->GetConstantTrue()); | 4587 true_graph->environment()->Push(graph_->GetConstantTrue()); |
4605 | 4588 |
4606 false_graph->entry_block()->SetJoinId(expr->expression()->id()); | 4589 false_graph->entry_block()->SetJoinId(expr->expression()->id()); |
4607 false_graph->environment()->Push(graph_->GetConstantFalse()); | 4590 false_graph->environment()->Push(graph_->GetConstantFalse()); |
4608 | 4591 |
4609 current_subgraph_->AppendJoin(true_graph, false_graph, expr); | 4592 current_subgraph_->AppendJoin(true_graph, false_graph, expr); |
4610 ast_context()->ReturnValue(Pop()); | 4593 ast_context()->ReturnValue(Pop()); |
| 4594 } else { |
| 4595 ASSERT(ast_context()->IsEffect()); |
| 4596 VISIT_FOR_EFFECT(expr->expression()); |
4611 } | 4597 } |
| 4598 |
4612 } else if (op == Token::BIT_NOT || op == Token::SUB) { | 4599 } else if (op == Token::BIT_NOT || op == Token::SUB) { |
4613 VISIT_FOR_VALUE(expr->expression()); | 4600 VISIT_FOR_VALUE(expr->expression()); |
4614 HValue* value = Pop(); | 4601 HValue* value = Pop(); |
4615 HInstruction* instr = NULL; | 4602 HInstruction* instr = NULL; |
4616 switch (op) { | 4603 switch (op) { |
4617 case Token::BIT_NOT: | 4604 case Token::BIT_NOT: |
4618 instr = new HBitNot(value); | 4605 instr = new HBitNot(value); |
4619 break; | 4606 break; |
4620 case Token::SUB: | 4607 case Token::SUB: |
4621 instr = new HMul(graph_->GetConstantMinus1(), value); | 4608 instr = new HMul(graph_->GetConstantMinus1(), value); |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4890 } else { | 4877 } else { |
4891 VISIT_FOR_CONTROL(expr->left(), context->if_true(), eval_right); | 4878 VISIT_FOR_CONTROL(expr->left(), context->if_true(), eval_right); |
4892 } | 4879 } |
4893 eval_right->SetJoinId(expr->RightId()); | 4880 eval_right->SetJoinId(expr->RightId()); |
4894 | 4881 |
4895 // Translate right subexpression by visiting it in the same AST | 4882 // Translate right subexpression by visiting it in the same AST |
4896 // context as the entire expression. | 4883 // context as the entire expression. |
4897 subgraph()->set_exit_block(eval_right); | 4884 subgraph()->set_exit_block(eval_right); |
4898 Visit(expr->right()); | 4885 Visit(expr->right()); |
4899 | 4886 |
4900 } else { | 4887 } else if (ast_context()->IsValue()) { |
4901 VISIT_FOR_VALUE(expr->left()); | 4888 VISIT_FOR_VALUE(expr->left()); |
4902 ASSERT(current_subgraph_->HasExit()); | 4889 ASSERT(current_subgraph_->HasExit()); |
4903 | 4890 |
4904 HValue* left = Top(); | 4891 HValue* left = Top(); |
4905 HEnvironment* environment_copy = environment()->Copy(); | 4892 HEnvironment* environment_copy = environment()->Copy(); |
4906 environment_copy->Pop(); | 4893 environment_copy->Pop(); |
4907 HSubgraph* right_subgraph; | 4894 HSubgraph* right_subgraph; |
4908 right_subgraph = CreateBranchSubgraph(environment_copy); | 4895 right_subgraph = CreateBranchSubgraph(environment_copy); |
4909 ADD_TO_SUBGRAPH(right_subgraph, expr->right()); | 4896 ADD_TO_SUBGRAPH(right_subgraph, expr->right()); |
4910 current_subgraph_->AppendOptional(right_subgraph, is_logical_and, left); | 4897 |
4911 current_subgraph_->exit_block()->SetJoinId(expr->id()); | 4898 ASSERT(subgraph()->HasExit() && right_subgraph->HasExit()); |
| 4899 // We need an extra block to maintain edge-split form. |
| 4900 HBasicBlock* empty_block = graph()->CreateBasicBlock(); |
| 4901 HBasicBlock* join_block = graph()->CreateBasicBlock(); |
| 4902 |
| 4903 HTest* test = is_logical_and |
| 4904 ? new HTest(left, right_subgraph->entry_block(), empty_block) |
| 4905 : new HTest(left, empty_block, right_subgraph->entry_block()); |
| 4906 subgraph()->exit_block()->Finish(test); |
| 4907 empty_block->Goto(join_block); |
| 4908 right_subgraph->exit_block()->Goto(join_block); |
| 4909 join_block->SetJoinId(expr->id()); |
| 4910 subgraph()->set_exit_block(join_block); |
4912 ast_context()->ReturnValue(Pop()); | 4911 ast_context()->ReturnValue(Pop()); |
| 4912 } else { |
| 4913 ASSERT(ast_context()->IsEffect()); |
| 4914 // In an effect context, we don't need the value of the left |
| 4915 // subexpression, only its control flow and side effects. We need an |
| 4916 // extra block to maintain edge-split form. |
| 4917 HBasicBlock* empty_block = graph()->CreateBasicBlock(); |
| 4918 HBasicBlock* right_block = graph()->CreateBasicBlock(); |
| 4919 HBasicBlock* join_block = graph()->CreateBasicBlock(); |
| 4920 if (is_logical_and) { |
| 4921 VISIT_FOR_CONTROL(expr->left(), right_block, empty_block); |
| 4922 } else { |
| 4923 VISIT_FOR_CONTROL(expr->left(), empty_block, right_block); |
| 4924 } |
| 4925 // TODO(kmillikin): Find a way to fix this. It's ugly that there are |
| 4926 // actually two empty blocks (one here and one inserted by |
| 4927 // TestContext::BuildBranch, and that they both have an HSimulate |
| 4928 // though the second one is not a merge node, and that we really have |
| 4929 // no good AST ID to put on that first HSimulate. |
| 4930 empty_block->SetJoinId(expr->id()); |
| 4931 right_block->SetJoinId(expr->RightId()); |
| 4932 subgraph()->set_exit_block(right_block); |
| 4933 VISIT_FOR_EFFECT(expr->right()); |
| 4934 |
| 4935 empty_block->Goto(join_block); |
| 4936 subgraph()->exit_block()->Goto(join_block); |
| 4937 join_block->SetJoinId(expr->id()); |
| 4938 subgraph()->set_exit_block(join_block); |
| 4939 // We did not materialize any value in the predecessor environments, |
| 4940 // so there is no need to handle it here. |
4913 } | 4941 } |
4914 | 4942 |
4915 } else { | 4943 } else { |
4916 VISIT_FOR_VALUE(expr->left()); | 4944 VISIT_FOR_VALUE(expr->left()); |
4917 VISIT_FOR_VALUE(expr->right()); | 4945 VISIT_FOR_VALUE(expr->right()); |
4918 | 4946 |
4919 HValue* right = Pop(); | 4947 HValue* right = Pop(); |
4920 HValue* left = Pop(); | 4948 HValue* left = Pop(); |
4921 HInstruction* instr = BuildBinaryOperation(expr, left, right); | 4949 HInstruction* instr = BuildBinaryOperation(expr, left, right); |
4922 instr->set_position(expr->position()); | 4950 instr->set_position(expr->position()); |
(...skipping 978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5901 } | 5929 } |
5902 } | 5930 } |
5903 | 5931 |
5904 #ifdef DEBUG | 5932 #ifdef DEBUG |
5905 if (graph_ != NULL) graph_->Verify(); | 5933 if (graph_ != NULL) graph_->Verify(); |
5906 if (allocator_ != NULL) allocator_->Verify(); | 5934 if (allocator_ != NULL) allocator_->Verify(); |
5907 #endif | 5935 #endif |
5908 } | 5936 } |
5909 | 5937 |
5910 } } // namespace v8::internal | 5938 } } // namespace v8::internal |
OLD | NEW |