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 |