| 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 752 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 763 void AstLabeler::VisitThisFunction(ThisFunction* expr) { | 763 void AstLabeler::VisitThisFunction(ThisFunction* expr) { |
| 764 UNREACHABLE(); | 764 UNREACHABLE(); |
| 765 } | 765 } |
| 766 | 766 |
| 767 | 767 |
| 768 void AstLabeler::VisitDeclaration(Declaration* decl) { | 768 void AstLabeler::VisitDeclaration(Declaration* decl) { |
| 769 UNREACHABLE(); | 769 UNREACHABLE(); |
| 770 } | 770 } |
| 771 | 771 |
| 772 | 772 |
| 773 ZoneList<Expression*>* VarUseMap::Lookup(Variable* var) { | |
| 774 HashMap::Entry* entry = HashMap::Lookup(var, var->name()->Hash(), true); | |
| 775 if (entry->value == NULL) { | |
| 776 entry->value = new ZoneList<Expression*>(1); | |
| 777 } | |
| 778 return reinterpret_cast<ZoneList<Expression*>*>(entry->value); | |
| 779 } | |
| 780 | |
| 781 | |
| 782 void LivenessAnalyzer::Analyze(FunctionLiteral* fun) { | |
| 783 // Process the function body. | |
| 784 VisitStatements(fun->body()); | |
| 785 | |
| 786 // All variables are implicitly defined at the function start. | |
| 787 // Record a definition of all variables live at function entry. | |
| 788 for (HashMap::Entry* p = live_vars_.Start(); | |
| 789 p != NULL; | |
| 790 p = live_vars_.Next(p)) { | |
| 791 Variable* var = reinterpret_cast<Variable*>(p->key); | |
| 792 RecordDef(var, fun); | |
| 793 } | |
| 794 } | |
| 795 | |
| 796 | |
| 797 void LivenessAnalyzer::VisitStatements(ZoneList<Statement*>* stmts) { | |
| 798 // Visit statements right-to-left. | |
| 799 for (int i = stmts->length() - 1; i >= 0; i--) { | |
| 800 Visit(stmts->at(i)); | |
| 801 } | |
| 802 } | |
| 803 | |
| 804 | |
| 805 void LivenessAnalyzer::RecordUse(Variable* var, Expression* expr) { | |
| 806 ASSERT(var->is_global() || var->is_this()); | |
| 807 ZoneList<Expression*>* uses = live_vars_.Lookup(var); | |
| 808 uses->Add(expr); | |
| 809 } | |
| 810 | |
| 811 | |
| 812 void LivenessAnalyzer::RecordDef(Variable* var, Expression* expr) { | |
| 813 ASSERT(var->is_global() || var->is_this()); | |
| 814 | |
| 815 // We do not support other expressions that can define variables. | |
| 816 ASSERT(expr->AsFunctionLiteral() != NULL); | |
| 817 | |
| 818 // Add the variable to the list of defined variables. | |
| 819 if (expr->defined_vars() == NULL) { | |
| 820 expr->set_defined_vars(new ZoneList<DefinitionInfo*>(1)); | |
| 821 } | |
| 822 DefinitionInfo* def = new DefinitionInfo(); | |
| 823 expr->AsFunctionLiteral()->defined_vars()->Add(def); | |
| 824 | |
| 825 // Compute the last use of the definition. The variable uses are | |
| 826 // inserted in reversed evaluation order. The first element | |
| 827 // in the list of live uses is the last use. | |
| 828 ZoneList<Expression*>* uses = live_vars_.Lookup(var); | |
| 829 while (uses->length() > 0) { | |
| 830 Expression* use_site = uses->RemoveLast(); | |
| 831 use_site->set_var_def(def); | |
| 832 if (uses->length() == 0) { | |
| 833 def->set_last_use(use_site); | |
| 834 } | |
| 835 } | |
| 836 } | |
| 837 | |
| 838 | |
| 839 // Visitor functions for live variable analysis. | |
| 840 void LivenessAnalyzer::VisitDeclaration(Declaration* decl) { | |
| 841 UNREACHABLE(); | |
| 842 } | |
| 843 | |
| 844 | |
| 845 void LivenessAnalyzer::VisitBlock(Block* stmt) { | |
| 846 VisitStatements(stmt->statements()); | |
| 847 } | |
| 848 | |
| 849 | |
| 850 void LivenessAnalyzer::VisitExpressionStatement( | |
| 851 ExpressionStatement* stmt) { | |
| 852 Visit(stmt->expression()); | |
| 853 } | |
| 854 | |
| 855 | |
| 856 void LivenessAnalyzer::VisitEmptyStatement(EmptyStatement* stmt) { | |
| 857 // Do nothing. | |
| 858 } | |
| 859 | |
| 860 | |
| 861 void LivenessAnalyzer::VisitIfStatement(IfStatement* stmt) { | |
| 862 UNREACHABLE(); | |
| 863 } | |
| 864 | |
| 865 | |
| 866 void LivenessAnalyzer::VisitContinueStatement(ContinueStatement* stmt) { | |
| 867 UNREACHABLE(); | |
| 868 } | |
| 869 | |
| 870 | |
| 871 void LivenessAnalyzer::VisitBreakStatement(BreakStatement* stmt) { | |
| 872 UNREACHABLE(); | |
| 873 } | |
| 874 | |
| 875 | |
| 876 void LivenessAnalyzer::VisitReturnStatement(ReturnStatement* stmt) { | |
| 877 UNREACHABLE(); | |
| 878 } | |
| 879 | |
| 880 | |
| 881 void LivenessAnalyzer::VisitWithEnterStatement( | |
| 882 WithEnterStatement* stmt) { | |
| 883 UNREACHABLE(); | |
| 884 } | |
| 885 | |
| 886 | |
| 887 void LivenessAnalyzer::VisitWithExitStatement(WithExitStatement* stmt) { | |
| 888 UNREACHABLE(); | |
| 889 } | |
| 890 | |
| 891 | |
| 892 void LivenessAnalyzer::VisitSwitchStatement(SwitchStatement* stmt) { | |
| 893 UNREACHABLE(); | |
| 894 } | |
| 895 | |
| 896 | |
| 897 void LivenessAnalyzer::VisitDoWhileStatement(DoWhileStatement* stmt) { | |
| 898 UNREACHABLE(); | |
| 899 } | |
| 900 | |
| 901 | |
| 902 void LivenessAnalyzer::VisitWhileStatement(WhileStatement* stmt) { | |
| 903 UNREACHABLE(); | |
| 904 } | |
| 905 | |
| 906 | |
| 907 void LivenessAnalyzer::VisitForStatement(ForStatement* stmt) { | |
| 908 UNREACHABLE(); | |
| 909 } | |
| 910 | |
| 911 | |
| 912 void LivenessAnalyzer::VisitForInStatement(ForInStatement* stmt) { | |
| 913 UNREACHABLE(); | |
| 914 } | |
| 915 | |
| 916 | |
| 917 void LivenessAnalyzer::VisitTryCatchStatement(TryCatchStatement* stmt) { | |
| 918 UNREACHABLE(); | |
| 919 } | |
| 920 | |
| 921 | |
| 922 void LivenessAnalyzer::VisitTryFinallyStatement( | |
| 923 TryFinallyStatement* stmt) { | |
| 924 UNREACHABLE(); | |
| 925 } | |
| 926 | |
| 927 | |
| 928 void LivenessAnalyzer::VisitDebuggerStatement( | |
| 929 DebuggerStatement* stmt) { | |
| 930 UNREACHABLE(); | |
| 931 } | |
| 932 | |
| 933 | |
| 934 void LivenessAnalyzer::VisitFunctionLiteral(FunctionLiteral* expr) { | |
| 935 UNREACHABLE(); | |
| 936 } | |
| 937 | |
| 938 | |
| 939 void LivenessAnalyzer::VisitFunctionBoilerplateLiteral( | |
| 940 FunctionBoilerplateLiteral* expr) { | |
| 941 UNREACHABLE(); | |
| 942 } | |
| 943 | |
| 944 | |
| 945 void LivenessAnalyzer::VisitConditional(Conditional* expr) { | |
| 946 UNREACHABLE(); | |
| 947 } | |
| 948 | |
| 949 | |
| 950 void LivenessAnalyzer::VisitSlot(Slot* expr) { | |
| 951 UNREACHABLE(); | |
| 952 } | |
| 953 | |
| 954 | |
| 955 void LivenessAnalyzer::VisitVariableProxy(VariableProxy* expr) { | |
| 956 Variable* var = expr->var(); | |
| 957 ASSERT(var->is_global()); | |
| 958 ASSERT(!var->is_this()); | |
| 959 RecordUse(var, expr); | |
| 960 } | |
| 961 | |
| 962 | |
| 963 void LivenessAnalyzer::VisitLiteral(Literal* expr) { | |
| 964 UNREACHABLE(); | |
| 965 } | |
| 966 | |
| 967 | |
| 968 void LivenessAnalyzer::VisitRegExpLiteral(RegExpLiteral* expr) { | |
| 969 UNREACHABLE(); | |
| 970 } | |
| 971 | |
| 972 | |
| 973 void LivenessAnalyzer::VisitObjectLiteral(ObjectLiteral* expr) { | |
| 974 UNREACHABLE(); | |
| 975 } | |
| 976 | |
| 977 | |
| 978 void LivenessAnalyzer::VisitArrayLiteral(ArrayLiteral* expr) { | |
| 979 UNREACHABLE(); | |
| 980 } | |
| 981 | |
| 982 | |
| 983 void LivenessAnalyzer::VisitCatchExtensionObject( | |
| 984 CatchExtensionObject* expr) { | |
| 985 UNREACHABLE(); | |
| 986 } | |
| 987 | |
| 988 | |
| 989 void LivenessAnalyzer::VisitAssignment(Assignment* expr) { | |
| 990 Property* prop = expr->target()->AsProperty(); | |
| 991 ASSERT(prop != NULL); | |
| 992 ASSERT(prop->key()->IsPropertyName()); | |
| 993 VariableProxy* proxy = prop->obj()->AsVariableProxy(); | |
| 994 ASSERT(proxy != NULL && proxy->var()->is_this()); | |
| 995 | |
| 996 // Record use of this at the assignment node. Assignments to | |
| 997 // this-properties are treated like unary operations. | |
| 998 RecordUse(proxy->var(), expr); | |
| 999 | |
| 1000 // Visit right-hand side. | |
| 1001 Visit(expr->value()); | |
| 1002 } | |
| 1003 | |
| 1004 | |
| 1005 void LivenessAnalyzer::VisitThrow(Throw* expr) { | |
| 1006 UNREACHABLE(); | |
| 1007 } | |
| 1008 | |
| 1009 | |
| 1010 void LivenessAnalyzer::VisitProperty(Property* expr) { | |
| 1011 ASSERT(expr->key()->IsPropertyName()); | |
| 1012 VariableProxy* proxy = expr->obj()->AsVariableProxy(); | |
| 1013 ASSERT(proxy != NULL && proxy->var()->is_this()); | |
| 1014 RecordUse(proxy->var(), expr); | |
| 1015 } | |
| 1016 | |
| 1017 | |
| 1018 void LivenessAnalyzer::VisitCall(Call* expr) { | |
| 1019 UNREACHABLE(); | |
| 1020 } | |
| 1021 | |
| 1022 | |
| 1023 void LivenessAnalyzer::VisitCallNew(CallNew* expr) { | |
| 1024 UNREACHABLE(); | |
| 1025 } | |
| 1026 | |
| 1027 | |
| 1028 void LivenessAnalyzer::VisitCallRuntime(CallRuntime* expr) { | |
| 1029 UNREACHABLE(); | |
| 1030 } | |
| 1031 | |
| 1032 | |
| 1033 void LivenessAnalyzer::VisitUnaryOperation(UnaryOperation* expr) { | |
| 1034 UNREACHABLE(); | |
| 1035 } | |
| 1036 | |
| 1037 | |
| 1038 void LivenessAnalyzer::VisitCountOperation(CountOperation* expr) { | |
| 1039 UNREACHABLE(); | |
| 1040 } | |
| 1041 | |
| 1042 | |
| 1043 void LivenessAnalyzer::VisitBinaryOperation(BinaryOperation* expr) { | |
| 1044 // Visit child nodes in reverse evaluation order. | |
| 1045 Visit(expr->right()); | |
| 1046 Visit(expr->left()); | |
| 1047 } | |
| 1048 | |
| 1049 | |
| 1050 void LivenessAnalyzer::VisitCompareOperation(CompareOperation* expr) { | |
| 1051 UNREACHABLE(); | |
| 1052 } | |
| 1053 | |
| 1054 | |
| 1055 void LivenessAnalyzer::VisitThisFunction(ThisFunction* expr) { | |
| 1056 UNREACHABLE(); | |
| 1057 } | |
| 1058 | |
| 1059 | |
| 1060 AssignedVariablesAnalyzer::AssignedVariablesAnalyzer(FunctionLiteral* fun) | 773 AssignedVariablesAnalyzer::AssignedVariablesAnalyzer(FunctionLiteral* fun) |
| 1061 : fun_(fun), | 774 : fun_(fun), |
| 1062 av_(fun->scope()->num_parameters() + fun->scope()->num_stack_slots()) {} | 775 av_(fun->scope()->num_parameters() + fun->scope()->num_stack_slots()) {} |
| 1063 | 776 |
| 1064 | 777 |
| 1065 void AssignedVariablesAnalyzer::Analyze() { | 778 void AssignedVariablesAnalyzer::Analyze() { |
| 1066 ASSERT(av_.length() > 0); | 779 ASSERT(av_.length() > 0); |
| 1067 VisitStatements(fun_->body()); | 780 VisitStatements(fun_->body()); |
| 1068 } | 781 } |
| 1069 | 782 |
| (...skipping 1135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2205 | 1918 |
| 2206 // Step 4: Based on RD_in for block nodes, propagate reaching definitions | 1919 // Step 4: Based on RD_in for block nodes, propagate reaching definitions |
| 2207 // to all variable uses in the block. | 1920 // to all variable uses in the block. |
| 2208 for (int i = 0; i < node_count; i++) { | 1921 for (int i = 0; i < node_count; i++) { |
| 2209 postorder_->at(i)->PropagateReachingDefinitions(&variables_); | 1922 postorder_->at(i)->PropagateReachingDefinitions(&variables_); |
| 2210 } | 1923 } |
| 2211 } | 1924 } |
| 2212 | 1925 |
| 2213 | 1926 |
| 2214 } } // namespace v8::internal | 1927 } } // namespace v8::internal |
| OLD | NEW |