| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 | 215 |
| 216 | 216 |
| 217 void AstOptimizer::VisitConditional(Conditional* node) { | 217 void AstOptimizer::VisitConditional(Conditional* node) { |
| 218 node->condition()->set_no_negative_zero(true); | 218 node->condition()->set_no_negative_zero(true); |
| 219 Visit(node->condition()); | 219 Visit(node->condition()); |
| 220 Visit(node->then_expression()); | 220 Visit(node->then_expression()); |
| 221 Visit(node->else_expression()); | 221 Visit(node->else_expression()); |
| 222 } | 222 } |
| 223 | 223 |
| 224 | 224 |
| 225 void AstOptimizer::VisitSlot(Slot* node) { | |
| 226 USE(node); | |
| 227 } | |
| 228 | |
| 229 | |
| 230 void AstOptimizer::VisitVariableProxy(VariableProxy* node) { | 225 void AstOptimizer::VisitVariableProxy(VariableProxy* node) { |
| 231 Variable* var = node->AsVariable(); | 226 Variable* var = node->AsVariable(); |
| 232 if (var != NULL) { | 227 if (var != NULL) { |
| 233 if (var->type()->IsKnown()) { | 228 if (var->type()->IsKnown()) { |
| 234 node->type()->CopyFrom(var->type()); | 229 node->type()->CopyFrom(var->type()); |
| 235 } else if (node->type()->IsLikelySmi()) { | 230 } else if (node->type()->IsLikelySmi()) { |
| 236 var->type()->SetAsLikelySmi(); | 231 var->type()->SetAsLikelySmi(); |
| 237 } | 232 } |
| 238 | 233 |
| 239 if (FLAG_safe_int32_compiler) { | 234 if (FLAG_safe_int32_compiler) { |
| (...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 } | 674 } |
| 680 | 675 |
| 681 | 676 |
| 682 void AstOptimizer::VisitThisFunction(ThisFunction* node) { | 677 void AstOptimizer::VisitThisFunction(ThisFunction* node) { |
| 683 USE(node); | 678 USE(node); |
| 684 } | 679 } |
| 685 | 680 |
| 686 | 681 |
| 687 class Processor: public AstVisitor { | 682 class Processor: public AstVisitor { |
| 688 public: | 683 public: |
| 689 explicit Processor(VariableProxy* result) | 684 explicit Processor(Variable* result) |
| 690 : result_(result), | 685 : result_(result), |
| 691 result_assigned_(false), | 686 result_assigned_(false), |
| 692 is_set_(false), | 687 is_set_(false), |
| 693 in_try_(false) { | 688 in_try_(false) { |
| 694 } | 689 } |
| 695 | 690 |
| 696 void Process(ZoneList<Statement*>* statements); | 691 void Process(ZoneList<Statement*>* statements); |
| 697 bool result_assigned() const { return result_assigned_; } | 692 bool result_assigned() const { return result_assigned_; } |
| 698 | 693 |
| 699 private: | 694 private: |
| 700 VariableProxy* result_; | 695 Variable* result_; |
| 701 | 696 |
| 702 // We are not tracking result usage via the result_'s use | 697 // We are not tracking result usage via the result_'s use |
| 703 // counts (we leave the accurate computation to the | 698 // counts (we leave the accurate computation to the |
| 704 // usage analyzer). Instead we simple remember if | 699 // usage analyzer). Instead we simple remember if |
| 705 // there was ever an assignment to result_. | 700 // there was ever an assignment to result_. |
| 706 bool result_assigned_; | 701 bool result_assigned_; |
| 707 | 702 |
| 708 // To avoid storing to .result all the time, we eliminate some of | 703 // To avoid storing to .result all the time, we eliminate some of |
| 709 // the stores by keeping track of whether or not we're sure .result | 704 // the stores by keeping track of whether or not we're sure .result |
| 710 // will be overwritten anyway. This is a bit more tricky than what I | 705 // will be overwritten anyway. This is a bit more tricky than what I |
| 711 // was hoping for | 706 // was hoping for |
| 712 bool is_set_; | 707 bool is_set_; |
| 713 bool in_try_; | 708 bool in_try_; |
| 714 | 709 |
| 715 Expression* SetResult(Expression* value) { | 710 Expression* SetResult(Expression* value) { |
| 716 result_assigned_ = true; | 711 result_assigned_ = true; |
| 717 return new Assignment(Token::ASSIGN, result_, value, | 712 VariableProxy* result_proxy = new VariableProxy(result_); |
| 713 return new Assignment(Token::ASSIGN, result_proxy, value, |
| 718 RelocInfo::kNoPosition); | 714 RelocInfo::kNoPosition); |
| 719 } | 715 } |
| 720 | 716 |
| 721 // Node visitors. | 717 // Node visitors. |
| 722 #define DEF_VISIT(type) \ | 718 #define DEF_VISIT(type) \ |
| 723 virtual void Visit##type(type* node); | 719 virtual void Visit##type(type* node); |
| 724 AST_NODE_LIST(DEF_VISIT) | 720 AST_NODE_LIST(DEF_VISIT) |
| 725 #undef DEF_VISIT | 721 #undef DEF_VISIT |
| 726 | 722 |
| 727 void VisitIterationStatement(IterationStatement* stmt); | 723 void VisitIterationStatement(IterationStatement* stmt); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 862 UNREACHABLE(); | 858 UNREACHABLE(); |
| 863 } | 859 } |
| 864 | 860 |
| 865 | 861 |
| 866 void Processor::VisitConditional(Conditional* node) { | 862 void Processor::VisitConditional(Conditional* node) { |
| 867 USE(node); | 863 USE(node); |
| 868 UNREACHABLE(); | 864 UNREACHABLE(); |
| 869 } | 865 } |
| 870 | 866 |
| 871 | 867 |
| 872 void Processor::VisitSlot(Slot* node) { | |
| 873 USE(node); | |
| 874 UNREACHABLE(); | |
| 875 } | |
| 876 | |
| 877 | |
| 878 void Processor::VisitVariableProxy(VariableProxy* node) { | 868 void Processor::VisitVariableProxy(VariableProxy* node) { |
| 879 USE(node); | 869 USE(node); |
| 880 UNREACHABLE(); | 870 UNREACHABLE(); |
| 881 } | 871 } |
| 882 | 872 |
| 883 | 873 |
| 884 void Processor::VisitLiteral(Literal* node) { | 874 void Processor::VisitLiteral(Literal* node) { |
| 885 USE(node); | 875 USE(node); |
| 886 UNREACHABLE(); | 876 UNREACHABLE(); |
| 887 } | 877 } |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 992 // AST, so the AST should not continue to be used in the case of failure. | 982 // AST, so the AST should not continue to be used in the case of failure. |
| 993 bool Rewriter::Rewrite(CompilationInfo* info) { | 983 bool Rewriter::Rewrite(CompilationInfo* info) { |
| 994 FunctionLiteral* function = info->function(); | 984 FunctionLiteral* function = info->function(); |
| 995 ASSERT(function != NULL); | 985 ASSERT(function != NULL); |
| 996 Scope* scope = function->scope(); | 986 Scope* scope = function->scope(); |
| 997 ASSERT(scope != NULL); | 987 ASSERT(scope != NULL); |
| 998 if (scope->is_function_scope()) return true; | 988 if (scope->is_function_scope()) return true; |
| 999 | 989 |
| 1000 ZoneList<Statement*>* body = function->body(); | 990 ZoneList<Statement*>* body = function->body(); |
| 1001 if (!body->is_empty()) { | 991 if (!body->is_empty()) { |
| 1002 VariableProxy* result = scope->NewTemporary( | 992 Variable* result = scope->NewTemporary( |
| 1003 info->isolate()->factory()->result_symbol()); | 993 info->isolate()->factory()->result_symbol()); |
| 1004 Processor processor(result); | 994 Processor processor(result); |
| 1005 processor.Process(body); | 995 processor.Process(body); |
| 1006 if (processor.HasStackOverflow()) return false; | 996 if (processor.HasStackOverflow()) return false; |
| 1007 | 997 |
| 1008 if (processor.result_assigned()) body->Add(new ReturnStatement(result)); | 998 if (processor.result_assigned()) { |
| 999 VariableProxy* result_proxy = new VariableProxy(result); |
| 1000 body->Add(new ReturnStatement(result_proxy)); |
| 1001 } |
| 1009 } | 1002 } |
| 1010 | 1003 |
| 1011 return true; | 1004 return true; |
| 1012 } | 1005 } |
| 1013 | 1006 |
| 1014 | 1007 |
| 1015 // Assumes code has been parsed and scopes have been analyzed. Mutates the | 1008 // Assumes code has been parsed and scopes have been analyzed. Mutates the |
| 1016 // AST, so the AST should not continue to be used in the case of failure. | 1009 // AST, so the AST should not continue to be used in the case of failure. |
| 1017 bool Rewriter::Analyze(CompilationInfo* info) { | 1010 bool Rewriter::Analyze(CompilationInfo* info) { |
| 1018 FunctionLiteral* function = info->function(); | 1011 FunctionLiteral* function = info->function(); |
| 1019 ASSERT(function != NULL && function->scope() != NULL); | 1012 ASSERT(function != NULL && function->scope() != NULL); |
| 1020 | 1013 |
| 1021 ZoneList<Statement*>* body = function->body(); | 1014 ZoneList<Statement*>* body = function->body(); |
| 1022 if (FLAG_optimize_ast && !body->is_empty()) { | 1015 if (FLAG_optimize_ast && !body->is_empty()) { |
| 1023 AstOptimizer optimizer; | 1016 AstOptimizer optimizer; |
| 1024 optimizer.Optimize(body); | 1017 optimizer.Optimize(body); |
| 1025 if (optimizer.HasStackOverflow()) return false; | 1018 if (optimizer.HasStackOverflow()) return false; |
| 1026 } | 1019 } |
| 1027 return true; | 1020 return true; |
| 1028 } | 1021 } |
| 1029 | 1022 |
| 1030 | 1023 |
| 1031 } } // namespace v8::internal | 1024 } } // namespace v8::internal |
| OLD | NEW |