| 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 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 void FlowGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { | 388 void FlowGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { |
| 389 SetStackOverflow(); | 389 SetStackOverflow(); |
| 390 } | 390 } |
| 391 | 391 |
| 392 | 392 |
| 393 void FlowGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | 393 void FlowGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { |
| 394 SetStackOverflow(); | 394 SetStackOverflow(); |
| 395 } | 395 } |
| 396 | 396 |
| 397 | 397 |
| 398 void FlowGraphBuilder::VisitFunctionBoilerplateLiteral( | 398 void FlowGraphBuilder::VisitSharedFunctionInfoLiteral( |
| 399 FunctionBoilerplateLiteral* expr) { | 399 SharedFunctionInfoLiteral* expr) { |
| 400 SetStackOverflow(); | 400 SetStackOverflow(); |
| 401 } | 401 } |
| 402 | 402 |
| 403 | 403 |
| 404 void FlowGraphBuilder::VisitConditional(Conditional* expr) { | 404 void FlowGraphBuilder::VisitConditional(Conditional* expr) { |
| 405 SetStackOverflow(); | 405 SetStackOverflow(); |
| 406 } | 406 } |
| 407 | 407 |
| 408 | 408 |
| 409 void FlowGraphBuilder::VisitSlot(Slot* expr) { | 409 void FlowGraphBuilder::VisitSlot(Slot* expr) { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 void FlowGraphBuilder::VisitAssignment(Assignment* expr) { | 444 void FlowGraphBuilder::VisitAssignment(Assignment* expr) { |
| 445 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | 445 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
| 446 Property* prop = expr->target()->AsProperty(); | 446 Property* prop = expr->target()->AsProperty(); |
| 447 // Left-hand side can be a variable or property (or reference error) but | 447 // Left-hand side can be a variable or property (or reference error) but |
| 448 // not both. | 448 // not both. |
| 449 ASSERT(var == NULL || prop == NULL); | 449 ASSERT(var == NULL || prop == NULL); |
| 450 if (var != NULL) { | 450 if (var != NULL) { |
| 451 if (expr->is_compound()) Visit(expr->target()); | 451 if (expr->is_compound()) Visit(expr->target()); |
| 452 Visit(expr->value()); | 452 Visit(expr->value()); |
| 453 if (var->IsStackAllocated()) { | 453 if (var->IsStackAllocated()) { |
| 454 expr->set_num(definitions_.length()); | 454 // The first definition in the body is numbered n, where n is the |
| 455 definitions_.Add(expr); | 455 // number of parameters and stack-allocated locals. |
| 456 expr->set_num(body_definitions_.length() + variable_count_); |
| 457 body_definitions_.Add(expr); |
| 456 } | 458 } |
| 457 | 459 |
| 458 } else if (prop != NULL) { | 460 } else if (prop != NULL) { |
| 459 Visit(prop->obj()); | 461 Visit(prop->obj()); |
| 460 if (!prop->key()->IsPropertyName()) Visit(prop->key()); | 462 if (!prop->key()->IsPropertyName()) Visit(prop->key()); |
| 461 Visit(expr->value()); | 463 Visit(expr->value()); |
| 462 } | 464 } |
| 463 | 465 |
| 464 if (HasStackOverflow()) return; | 466 if (HasStackOverflow()) return; |
| 465 graph_.AppendInstruction(expr); | 467 graph_.AppendInstruction(expr); |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 522 default: | 524 default: |
| 523 UNREACHABLE(); | 525 UNREACHABLE(); |
| 524 } | 526 } |
| 525 } | 527 } |
| 526 | 528 |
| 527 | 529 |
| 528 void FlowGraphBuilder::VisitCountOperation(CountOperation* expr) { | 530 void FlowGraphBuilder::VisitCountOperation(CountOperation* expr) { |
| 529 Visit(expr->expression()); | 531 Visit(expr->expression()); |
| 530 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); | 532 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
| 531 if (var != NULL && var->IsStackAllocated()) { | 533 if (var != NULL && var->IsStackAllocated()) { |
| 532 expr->set_num(definitions_.length()); | 534 // The first definition in the body is numbered n, where n is the number |
| 533 definitions_.Add(expr); | 535 // of parameters and stack-allocated locals. |
| 536 expr->set_num(body_definitions_.length() + variable_count_); |
| 537 body_definitions_.Add(expr); |
| 534 } | 538 } |
| 535 | 539 |
| 536 if (HasStackOverflow()) return; | 540 if (HasStackOverflow()) return; |
| 537 graph_.AppendInstruction(expr); | 541 graph_.AppendInstruction(expr); |
| 538 } | 542 } |
| 539 | 543 |
| 540 | 544 |
| 541 void FlowGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { | 545 void FlowGraphBuilder::VisitBinaryOperation(BinaryOperation* expr) { |
| 542 switch (expr->op()) { | 546 switch (expr->op()) { |
| 543 case Token::COMMA: | 547 case Token::COMMA: |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 706 DebuggerStatement* stmt) { | 710 DebuggerStatement* stmt) { |
| 707 UNREACHABLE(); | 711 UNREACHABLE(); |
| 708 } | 712 } |
| 709 | 713 |
| 710 | 714 |
| 711 void AstLabeler::VisitFunctionLiteral(FunctionLiteral* expr) { | 715 void AstLabeler::VisitFunctionLiteral(FunctionLiteral* expr) { |
| 712 UNREACHABLE(); | 716 UNREACHABLE(); |
| 713 } | 717 } |
| 714 | 718 |
| 715 | 719 |
| 716 void AstLabeler::VisitFunctionBoilerplateLiteral( | 720 void AstLabeler::VisitSharedFunctionInfoLiteral( |
| 717 FunctionBoilerplateLiteral* expr) { | 721 SharedFunctionInfoLiteral* expr) { |
| 718 UNREACHABLE(); | 722 UNREACHABLE(); |
| 719 } | 723 } |
| 720 | 724 |
| 721 | 725 |
| 722 void AstLabeler::VisitConditional(Conditional* expr) { | 726 void AstLabeler::VisitConditional(Conditional* expr) { |
| 723 UNREACHABLE(); | 727 UNREACHABLE(); |
| 724 } | 728 } |
| 725 | 729 |
| 726 | 730 |
| 727 void AstLabeler::VisitSlot(Slot* expr) { | 731 void AstLabeler::VisitSlot(Slot* expr) { |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1083 // Nothing to do. | 1087 // Nothing to do. |
| 1084 } | 1088 } |
| 1085 | 1089 |
| 1086 | 1090 |
| 1087 void AssignedVariablesAnalyzer::VisitFunctionLiteral(FunctionLiteral* expr) { | 1091 void AssignedVariablesAnalyzer::VisitFunctionLiteral(FunctionLiteral* expr) { |
| 1088 // Nothing to do. | 1092 // Nothing to do. |
| 1089 ASSERT(av_.IsEmpty()); | 1093 ASSERT(av_.IsEmpty()); |
| 1090 } | 1094 } |
| 1091 | 1095 |
| 1092 | 1096 |
| 1093 void AssignedVariablesAnalyzer::VisitFunctionBoilerplateLiteral( | 1097 void AssignedVariablesAnalyzer::VisitSharedFunctionInfoLiteral( |
| 1094 FunctionBoilerplateLiteral* expr) { | 1098 SharedFunctionInfoLiteral* expr) { |
| 1095 // Nothing to do. | 1099 // Nothing to do. |
| 1096 ASSERT(av_.IsEmpty()); | 1100 ASSERT(av_.IsEmpty()); |
| 1097 } | 1101 } |
| 1098 | 1102 |
| 1099 | 1103 |
| 1100 void AssignedVariablesAnalyzer::VisitConditional(Conditional* expr) { | 1104 void AssignedVariablesAnalyzer::VisitConditional(Conditional* expr) { |
| 1101 ASSERT(av_.IsEmpty()); | 1105 ASSERT(av_.IsEmpty()); |
| 1102 | 1106 |
| 1103 Visit(expr->condition()); | 1107 Visit(expr->condition()); |
| 1104 | 1108 |
| (...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1410 void TextInstructionPrinter::VisitDebuggerStatement(DebuggerStatement* stmt) { | 1414 void TextInstructionPrinter::VisitDebuggerStatement(DebuggerStatement* stmt) { |
| 1411 PrintF("DebuggerStatement"); | 1415 PrintF("DebuggerStatement"); |
| 1412 } | 1416 } |
| 1413 | 1417 |
| 1414 | 1418 |
| 1415 void TextInstructionPrinter::VisitFunctionLiteral(FunctionLiteral* expr) { | 1419 void TextInstructionPrinter::VisitFunctionLiteral(FunctionLiteral* expr) { |
| 1416 PrintF("FunctionLiteral"); | 1420 PrintF("FunctionLiteral"); |
| 1417 } | 1421 } |
| 1418 | 1422 |
| 1419 | 1423 |
| 1420 void TextInstructionPrinter::VisitFunctionBoilerplateLiteral( | 1424 void TextInstructionPrinter::VisitSharedFunctionInfoLiteral( |
| 1421 FunctionBoilerplateLiteral* expr) { | 1425 SharedFunctionInfoLiteral* expr) { |
| 1422 PrintF("FunctionBoilerplateLiteral"); | 1426 PrintF("SharedFunctionInfoLiteral"); |
| 1423 } | 1427 } |
| 1424 | 1428 |
| 1425 | 1429 |
| 1426 void TextInstructionPrinter::VisitConditional(Conditional* expr) { | 1430 void TextInstructionPrinter::VisitConditional(Conditional* expr) { |
| 1427 PrintF("Conditional"); | 1431 PrintF("Conditional"); |
| 1428 } | 1432 } |
| 1429 | 1433 |
| 1430 | 1434 |
| 1431 void TextInstructionPrinter::VisitSlot(Slot* expr) { | 1435 void TextInstructionPrinter::VisitSlot(Slot* expr) { |
| 1432 UNREACHABLE(); | 1436 UNREACHABLE(); |
| (...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1733 | 1737 |
| 1734 void BlockNode::InitializeReachingDefinitions(int definition_count, | 1738 void BlockNode::InitializeReachingDefinitions(int definition_count, |
| 1735 List<BitVector*>* variables, | 1739 List<BitVector*>* variables, |
| 1736 WorkList<Node>* worklist, | 1740 WorkList<Node>* worklist, |
| 1737 bool mark) { | 1741 bool mark) { |
| 1738 ASSERT(!IsMarkedWith(mark)); | 1742 ASSERT(!IsMarkedWith(mark)); |
| 1739 int instruction_count = instructions_.length(); | 1743 int instruction_count = instructions_.length(); |
| 1740 int variable_count = variables->length(); | 1744 int variable_count = variables->length(); |
| 1741 | 1745 |
| 1742 rd_.Initialize(definition_count); | 1746 rd_.Initialize(definition_count); |
| 1747 // The RD_in set for the entry node has a definition for each parameter |
| 1748 // and local. |
| 1749 if (predecessor_ == NULL) { |
| 1750 for (int i = 0; i < variable_count; i++) rd_.rd_in()->Add(i); |
| 1751 } |
| 1743 | 1752 |
| 1744 for (int i = 0; i < instruction_count; i++) { | 1753 for (int i = 0; i < instruction_count; i++) { |
| 1745 Expression* expr = instructions_[i]->AsExpression(); | 1754 Expression* expr = instructions_[i]->AsExpression(); |
| 1746 if (expr == NULL) continue; | 1755 if (expr == NULL) continue; |
| 1747 Variable* var = expr->AssignedVar(); | 1756 Variable* var = expr->AssignedVar(); |
| 1748 if (var == NULL || !var->IsStackAllocated()) continue; | 1757 if (var == NULL || !var->IsStackAllocated()) continue; |
| 1749 | 1758 |
| 1750 // All definitions of this variable are killed. | 1759 // All definitions of this variable are killed. |
| 1751 BitVector* def_set = | 1760 BitVector* def_set = |
| 1752 variables->at(ReachingDefinitions::IndexFor(var, variable_count)); | 1761 variables->at(ReachingDefinitions::IndexFor(var, variable_count)); |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1928 BitVector* def_set = | 1937 BitVector* def_set = |
| 1929 variables->at(ReachingDefinitions::IndexFor(var, variable_count)); | 1938 variables->at(ReachingDefinitions::IndexFor(var, variable_count)); |
| 1930 rd.Subtract(*def_set); | 1939 rd.Subtract(*def_set); |
| 1931 // This definition is generated. | 1940 // This definition is generated. |
| 1932 rd.Add(expr->num()); | 1941 rd.Add(expr->num()); |
| 1933 } | 1942 } |
| 1934 } | 1943 } |
| 1935 | 1944 |
| 1936 | 1945 |
| 1937 void ReachingDefinitions::Compute() { | 1946 void ReachingDefinitions::Compute() { |
| 1938 ASSERT(!definitions_->is_empty()); | 1947 // The definitions in the body plus an implicit definition for each |
| 1939 | 1948 // variable at function entry. |
| 1940 int variable_count = variables_.length(); | 1949 int definition_count = body_definitions_->length() + variable_count_; |
| 1941 int definition_count = definitions_->length(); | |
| 1942 int node_count = postorder_->length(); | 1950 int node_count = postorder_->length(); |
| 1943 | 1951 |
| 1944 // Step 1: For each variable, identify the set of all its definitions in | 1952 // Step 1: For each stack-allocated variable, identify the set of all its |
| 1945 // the body. | 1953 // definitions. |
| 1946 for (int i = 0; i < definition_count; i++) { | 1954 List<BitVector*> variables; |
| 1947 Variable* var = definitions_->at(i)->AssignedVar(); | 1955 for (int i = 0; i < variable_count_; i++) { |
| 1948 variables_[IndexFor(var, variable_count)]->Add(i); | 1956 // Add the initial definition for each variable. |
| 1957 BitVector* initial = new BitVector(definition_count); |
| 1958 initial->Add(i); |
| 1959 variables.Add(initial); |
| 1949 } | 1960 } |
| 1950 | 1961 for (int i = 0, len = body_definitions_->length(); i < len; i++) { |
| 1951 if (FLAG_print_graph_text) { | 1962 // Account for each definition in the body as a definition of the |
| 1952 for (int i = 0; i < variable_count; i++) { | 1963 // defined variable. |
| 1953 BitVector* def_set = variables_[i]; | 1964 Variable* var = body_definitions_->at(i)->AssignedVar(); |
| 1954 if (!def_set->IsEmpty()) { | 1965 variables[IndexFor(var, variable_count_)]->Add(i + variable_count_); |
| 1955 // At least one definition. | |
| 1956 bool first = true; | |
| 1957 for (int j = 0; j < definition_count; j++) { | |
| 1958 if (def_set->Contains(j)) { | |
| 1959 if (first) { | |
| 1960 Variable* var = definitions_->at(j)->AssignedVar(); | |
| 1961 ASSERT(var != NULL); | |
| 1962 PrintF("Def[%s] = {%d", *var->name()->ToCString(), j); | |
| 1963 first = false; | |
| 1964 } else { | |
| 1965 PrintF(",%d", j); | |
| 1966 } | |
| 1967 } | |
| 1968 } | |
| 1969 PrintF("}\n"); | |
| 1970 } | |
| 1971 } | |
| 1972 } | 1966 } |
| 1973 | 1967 |
| 1974 // Step 2: Compute KILL and GEN for each block node, initialize RD_in for | 1968 // Step 2: Compute KILL and GEN for each block node, initialize RD_in for |
| 1975 // all nodes, and mark and add all nodes to the worklist in reverse | 1969 // all nodes, and mark and add all nodes to the worklist in reverse |
| 1976 // postorder. All nodes should currently have the same mark. | 1970 // postorder. All nodes should currently have the same mark. |
| 1977 bool mark = postorder_->at(0)->IsMarkedWith(false); // Negation of current. | 1971 bool mark = postorder_->at(0)->IsMarkedWith(false); // Negation of current. |
| 1978 WorkList<Node> worklist(node_count); | 1972 WorkList<Node> worklist(node_count); |
| 1979 for (int i = node_count - 1; i >= 0; i--) { | 1973 for (int i = node_count - 1; i >= 0; i--) { |
| 1980 postorder_->at(i)->InitializeReachingDefinitions(definition_count, | 1974 postorder_->at(i)->InitializeReachingDefinitions(definition_count, |
| 1981 &variables_, | 1975 &variables, |
| 1982 &worklist, | 1976 &worklist, |
| 1983 mark); | 1977 mark); |
| 1984 } | 1978 } |
| 1985 | 1979 |
| 1986 // Step 3: Until the worklist is empty, remove an item compute and update | 1980 // Step 3: Until the worklist is empty, remove an item compute and update |
| 1987 // its rd_in based on its predecessor's rd_out. If rd_in has changed, add | 1981 // its rd_in based on its predecessor's rd_out. If rd_in has changed, add |
| 1988 // all necessary successors to the worklist. | 1982 // all necessary successors to the worklist. |
| 1989 while (!worklist.is_empty()) { | 1983 while (!worklist.is_empty()) { |
| 1990 Node* node = worklist.Remove(); | 1984 Node* node = worklist.Remove(); |
| 1991 node->MarkWith(!mark); | 1985 node->MarkWith(!mark); |
| 1992 node->UpdateRDIn(&worklist, mark); | 1986 node->UpdateRDIn(&worklist, mark); |
| 1993 } | 1987 } |
| 1994 | 1988 |
| 1995 // Step 4: Based on RD_in for block nodes, propagate reaching definitions | 1989 // Step 4: Based on RD_in for block nodes, propagate reaching definitions |
| 1996 // to all variable uses in the block. | 1990 // to all variable uses in the block. |
| 1997 for (int i = 0; i < node_count; i++) { | 1991 for (int i = 0; i < node_count; i++) { |
| 1998 postorder_->at(i)->PropagateReachingDefinitions(&variables_); | 1992 postorder_->at(i)->PropagateReachingDefinitions(&variables); |
| 1999 } | 1993 } |
| 2000 } | 1994 } |
| 2001 | 1995 |
| 2002 | 1996 |
| 2003 } } // namespace v8::internal | 1997 } } // namespace v8::internal |
| OLD | NEW |