| 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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 if (!first) PrintF(","); | 43 if (!first) PrintF(","); |
| 44 first = false; | 44 first = false; |
| 45 PrintF("%d"); | 45 PrintF("%d"); |
| 46 } | 46 } |
| 47 } | 47 } |
| 48 PrintF("}"); | 48 PrintF("}"); |
| 49 } | 49 } |
| 50 #endif | 50 #endif |
| 51 | 51 |
| 52 | 52 |
| 53 void AstLabeler::Label(CompilationInfo* info) { | 53 bool AssignedVariablesAnalyzer::Analyze() { |
| 54 info_ = info; | 54 Scope* scope = fun_->scope(); |
| 55 VisitStatements(info_->function()->body()); | 55 int variables = scope->num_parameters() + scope->num_stack_slots(); |
| 56 if (variables == 0) return true; |
| 57 av_.ExpandTo(variables); |
| 58 VisitStatements(fun_->body()); |
| 59 return !HasStackOverflow(); |
| 56 } | 60 } |
| 57 | 61 |
| 58 | 62 |
| 59 void AstLabeler::VisitStatements(ZoneList<Statement*>* stmts) { | |
| 60 for (int i = 0, len = stmts->length(); i < len; i++) { | |
| 61 Visit(stmts->at(i)); | |
| 62 } | |
| 63 } | |
| 64 | |
| 65 | |
| 66 void AstLabeler::VisitDeclarations(ZoneList<Declaration*>* decls) { | |
| 67 UNREACHABLE(); | |
| 68 } | |
| 69 | |
| 70 | |
| 71 void AstLabeler::VisitBlock(Block* stmt) { | |
| 72 VisitStatements(stmt->statements()); | |
| 73 } | |
| 74 | |
| 75 | |
| 76 void AstLabeler::VisitExpressionStatement( | |
| 77 ExpressionStatement* stmt) { | |
| 78 Visit(stmt->expression()); | |
| 79 } | |
| 80 | |
| 81 | |
| 82 void AstLabeler::VisitEmptyStatement(EmptyStatement* stmt) { | |
| 83 // Do nothing. | |
| 84 } | |
| 85 | |
| 86 | |
| 87 void AstLabeler::VisitIfStatement(IfStatement* stmt) { | |
| 88 UNREACHABLE(); | |
| 89 } | |
| 90 | |
| 91 | |
| 92 void AstLabeler::VisitContinueStatement(ContinueStatement* stmt) { | |
| 93 UNREACHABLE(); | |
| 94 } | |
| 95 | |
| 96 | |
| 97 void AstLabeler::VisitBreakStatement(BreakStatement* stmt) { | |
| 98 UNREACHABLE(); | |
| 99 } | |
| 100 | |
| 101 | |
| 102 void AstLabeler::VisitReturnStatement(ReturnStatement* stmt) { | |
| 103 UNREACHABLE(); | |
| 104 } | |
| 105 | |
| 106 | |
| 107 void AstLabeler::VisitWithEnterStatement( | |
| 108 WithEnterStatement* stmt) { | |
| 109 UNREACHABLE(); | |
| 110 } | |
| 111 | |
| 112 | |
| 113 void AstLabeler::VisitWithExitStatement(WithExitStatement* stmt) { | |
| 114 UNREACHABLE(); | |
| 115 } | |
| 116 | |
| 117 | |
| 118 void AstLabeler::VisitSwitchStatement(SwitchStatement* stmt) { | |
| 119 UNREACHABLE(); | |
| 120 } | |
| 121 | |
| 122 | |
| 123 void AstLabeler::VisitDoWhileStatement(DoWhileStatement* stmt) { | |
| 124 UNREACHABLE(); | |
| 125 } | |
| 126 | |
| 127 | |
| 128 void AstLabeler::VisitWhileStatement(WhileStatement* stmt) { | |
| 129 UNREACHABLE(); | |
| 130 } | |
| 131 | |
| 132 | |
| 133 void AstLabeler::VisitForStatement(ForStatement* stmt) { | |
| 134 UNREACHABLE(); | |
| 135 } | |
| 136 | |
| 137 | |
| 138 void AstLabeler::VisitForInStatement(ForInStatement* stmt) { | |
| 139 UNREACHABLE(); | |
| 140 } | |
| 141 | |
| 142 | |
| 143 void AstLabeler::VisitTryCatchStatement(TryCatchStatement* stmt) { | |
| 144 UNREACHABLE(); | |
| 145 } | |
| 146 | |
| 147 | |
| 148 void AstLabeler::VisitTryFinallyStatement( | |
| 149 TryFinallyStatement* stmt) { | |
| 150 UNREACHABLE(); | |
| 151 } | |
| 152 | |
| 153 | |
| 154 void AstLabeler::VisitDebuggerStatement( | |
| 155 DebuggerStatement* stmt) { | |
| 156 UNREACHABLE(); | |
| 157 } | |
| 158 | |
| 159 | |
| 160 void AstLabeler::VisitFunctionLiteral(FunctionLiteral* expr) { | |
| 161 UNREACHABLE(); | |
| 162 } | |
| 163 | |
| 164 | |
| 165 void AstLabeler::VisitSharedFunctionInfoLiteral( | |
| 166 SharedFunctionInfoLiteral* expr) { | |
| 167 UNREACHABLE(); | |
| 168 } | |
| 169 | |
| 170 | |
| 171 void AstLabeler::VisitConditional(Conditional* expr) { | |
| 172 UNREACHABLE(); | |
| 173 } | |
| 174 | |
| 175 | |
| 176 void AstLabeler::VisitSlot(Slot* expr) { | |
| 177 UNREACHABLE(); | |
| 178 } | |
| 179 | |
| 180 | |
| 181 void AstLabeler::VisitVariableProxy(VariableProxy* expr) { | |
| 182 expr->set_num(next_number_++); | |
| 183 Variable* var = expr->var(); | |
| 184 if (var->is_global() && !var->is_this()) { | |
| 185 info_->set_has_globals(true); | |
| 186 } | |
| 187 } | |
| 188 | |
| 189 | |
| 190 void AstLabeler::VisitLiteral(Literal* expr) { | |
| 191 UNREACHABLE(); | |
| 192 } | |
| 193 | |
| 194 | |
| 195 void AstLabeler::VisitRegExpLiteral(RegExpLiteral* expr) { | |
| 196 UNREACHABLE(); | |
| 197 } | |
| 198 | |
| 199 | |
| 200 void AstLabeler::VisitObjectLiteral(ObjectLiteral* expr) { | |
| 201 UNREACHABLE(); | |
| 202 } | |
| 203 | |
| 204 | |
| 205 void AstLabeler::VisitArrayLiteral(ArrayLiteral* expr) { | |
| 206 UNREACHABLE(); | |
| 207 } | |
| 208 | |
| 209 | |
| 210 void AstLabeler::VisitCatchExtensionObject( | |
| 211 CatchExtensionObject* expr) { | |
| 212 UNREACHABLE(); | |
| 213 } | |
| 214 | |
| 215 | |
| 216 void AstLabeler::VisitAssignment(Assignment* expr) { | |
| 217 Property* prop = expr->target()->AsProperty(); | |
| 218 ASSERT(prop != NULL); | |
| 219 ASSERT(prop->key()->IsPropertyName()); | |
| 220 VariableProxy* proxy = prop->obj()->AsVariableProxy(); | |
| 221 USE(proxy); | |
| 222 ASSERT(proxy != NULL && proxy->var()->is_this()); | |
| 223 info()->set_has_this_properties(true); | |
| 224 | |
| 225 prop->obj()->set_num(AstNode::kNoNumber); | |
| 226 prop->key()->set_num(AstNode::kNoNumber); | |
| 227 Visit(expr->value()); | |
| 228 expr->set_num(next_number_++); | |
| 229 } | |
| 230 | |
| 231 | |
| 232 void AstLabeler::VisitThrow(Throw* expr) { | |
| 233 UNREACHABLE(); | |
| 234 } | |
| 235 | |
| 236 | |
| 237 void AstLabeler::VisitProperty(Property* expr) { | |
| 238 ASSERT(expr->key()->IsPropertyName()); | |
| 239 VariableProxy* proxy = expr->obj()->AsVariableProxy(); | |
| 240 USE(proxy); | |
| 241 ASSERT(proxy != NULL && proxy->var()->is_this()); | |
| 242 info()->set_has_this_properties(true); | |
| 243 | |
| 244 expr->obj()->set_num(AstNode::kNoNumber); | |
| 245 expr->key()->set_num(AstNode::kNoNumber); | |
| 246 expr->set_num(next_number_++); | |
| 247 } | |
| 248 | |
| 249 | |
| 250 void AstLabeler::VisitCall(Call* expr) { | |
| 251 UNREACHABLE(); | |
| 252 } | |
| 253 | |
| 254 | |
| 255 void AstLabeler::VisitCallNew(CallNew* expr) { | |
| 256 UNREACHABLE(); | |
| 257 } | |
| 258 | |
| 259 | |
| 260 void AstLabeler::VisitCallRuntime(CallRuntime* expr) { | |
| 261 UNREACHABLE(); | |
| 262 } | |
| 263 | |
| 264 | |
| 265 void AstLabeler::VisitUnaryOperation(UnaryOperation* expr) { | |
| 266 UNREACHABLE(); | |
| 267 } | |
| 268 | |
| 269 | |
| 270 void AstLabeler::VisitCountOperation(CountOperation* expr) { | |
| 271 UNREACHABLE(); | |
| 272 } | |
| 273 | |
| 274 | |
| 275 void AstLabeler::VisitBinaryOperation(BinaryOperation* expr) { | |
| 276 Visit(expr->left()); | |
| 277 Visit(expr->right()); | |
| 278 expr->set_num(next_number_++); | |
| 279 } | |
| 280 | |
| 281 | |
| 282 void AstLabeler::VisitCompareOperation(CompareOperation* expr) { | |
| 283 UNREACHABLE(); | |
| 284 } | |
| 285 | |
| 286 | |
| 287 void AstLabeler::VisitThisFunction(ThisFunction* expr) { | |
| 288 UNREACHABLE(); | |
| 289 } | |
| 290 | |
| 291 | |
| 292 void AstLabeler::VisitDeclaration(Declaration* decl) { | |
| 293 UNREACHABLE(); | |
| 294 } | |
| 295 | |
| 296 | |
| 297 AssignedVariablesAnalyzer::AssignedVariablesAnalyzer(FunctionLiteral* fun) | |
| 298 : fun_(fun), | |
| 299 av_(fun->scope()->num_parameters() + fun->scope()->num_stack_slots()) {} | |
| 300 | |
| 301 | |
| 302 void AssignedVariablesAnalyzer::Analyze() { | |
| 303 ASSERT(av_.length() > 0); | |
| 304 VisitStatements(fun_->body()); | |
| 305 } | |
| 306 | |
| 307 | |
| 308 Variable* AssignedVariablesAnalyzer::FindSmiLoopVariable(ForStatement* stmt) { | 63 Variable* AssignedVariablesAnalyzer::FindSmiLoopVariable(ForStatement* stmt) { |
| 309 // The loop must have all necessary parts. | 64 // The loop must have all necessary parts. |
| 310 if (stmt->init() == NULL || stmt->cond() == NULL || stmt->next() == NULL) { | 65 if (stmt->init() == NULL || stmt->cond() == NULL || stmt->next() == NULL) { |
| 311 return NULL; | 66 return NULL; |
| 312 } | 67 } |
| 313 // The initialization statement has to be a simple assignment. | 68 // The initialization statement has to be a simple assignment. |
| 314 Assignment* init = stmt->init()->StatementAsSimpleAssignment(); | 69 Assignment* init = stmt->init()->StatementAsSimpleAssignment(); |
| 315 if (init == NULL) return NULL; | 70 if (init == NULL) return NULL; |
| 316 | 71 |
| 317 // We only deal with local variables. | 72 // We only deal with local variables. |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 } | 142 } |
| 388 | 143 |
| 389 | 144 |
| 390 void AssignedVariablesAnalyzer::MarkIfTrivial(Expression* expr) { | 145 void AssignedVariablesAnalyzer::MarkIfTrivial(Expression* expr) { |
| 391 Variable* var = expr->AsVariableProxy()->AsVariable(); | 146 Variable* var = expr->AsVariableProxy()->AsVariable(); |
| 392 if (var != NULL && | 147 if (var != NULL && |
| 393 var->IsStackAllocated() && | 148 var->IsStackAllocated() && |
| 394 !var->is_arguments() && | 149 !var->is_arguments() && |
| 395 var->mode() != Variable::CONST && | 150 var->mode() != Variable::CONST && |
| 396 (var->is_this() || !av_.Contains(BitIndex(var)))) { | 151 (var->is_this() || !av_.Contains(BitIndex(var)))) { |
| 397 expr->AsVariableProxy()->set_is_trivial(true); | 152 expr->AsVariableProxy()->MarkAsTrivial(); |
| 398 } | 153 } |
| 399 } | 154 } |
| 400 | 155 |
| 401 | 156 |
| 402 void AssignedVariablesAnalyzer::ProcessExpression(Expression* expr) { | 157 void AssignedVariablesAnalyzer::ProcessExpression(Expression* expr) { |
| 403 BitVector saved_av(av_); | 158 BitVector saved_av(av_); |
| 404 av_.Clear(); | 159 av_.Clear(); |
| 405 Visit(expr); | 160 Visit(expr); |
| 406 av_.Union(saved_av); | 161 av_.Union(saved_av); |
| 407 } | 162 } |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 | 237 |
| 483 | 238 |
| 484 void AssignedVariablesAnalyzer::VisitWhileStatement(WhileStatement* stmt) { | 239 void AssignedVariablesAnalyzer::VisitWhileStatement(WhileStatement* stmt) { |
| 485 ProcessExpression(stmt->cond()); | 240 ProcessExpression(stmt->cond()); |
| 486 Visit(stmt->body()); | 241 Visit(stmt->body()); |
| 487 } | 242 } |
| 488 | 243 |
| 489 | 244 |
| 490 void AssignedVariablesAnalyzer::VisitForStatement(ForStatement* stmt) { | 245 void AssignedVariablesAnalyzer::VisitForStatement(ForStatement* stmt) { |
| 491 if (stmt->init() != NULL) Visit(stmt->init()); | 246 if (stmt->init() != NULL) Visit(stmt->init()); |
| 492 | |
| 493 if (stmt->cond() != NULL) ProcessExpression(stmt->cond()); | 247 if (stmt->cond() != NULL) ProcessExpression(stmt->cond()); |
| 494 | |
| 495 if (stmt->next() != NULL) Visit(stmt->next()); | 248 if (stmt->next() != NULL) Visit(stmt->next()); |
| 496 | 249 |
| 497 // Process loop body. After visiting the loop body av_ contains | 250 // Process loop body. After visiting the loop body av_ contains |
| 498 // the assigned variables of the loop body. | 251 // the assigned variables of the loop body. |
| 499 BitVector saved_av(av_); | 252 BitVector saved_av(av_); |
| 500 av_.Clear(); | 253 av_.Clear(); |
| 501 Visit(stmt->body()); | 254 Visit(stmt->body()); |
| 502 | 255 |
| 503 Variable* var = FindSmiLoopVariable(stmt); | 256 Variable* var = FindSmiLoopVariable(stmt); |
| 504 if (var != NULL && !av_.Contains(BitIndex(var))) { | 257 if (var != NULL && !av_.Contains(BitIndex(var))) { |
| 505 stmt->set_loop_variable(var); | 258 stmt->set_loop_variable(var); |
| 506 } | 259 } |
| 507 | |
| 508 av_.Union(saved_av); | 260 av_.Union(saved_av); |
| 509 } | 261 } |
| 510 | 262 |
| 511 | 263 |
| 512 void AssignedVariablesAnalyzer::VisitForInStatement(ForInStatement* stmt) { | 264 void AssignedVariablesAnalyzer::VisitForInStatement(ForInStatement* stmt) { |
| 513 ProcessExpression(stmt->each()); | 265 ProcessExpression(stmt->each()); |
| 514 ProcessExpression(stmt->enumerable()); | 266 ProcessExpression(stmt->enumerable()); |
| 515 Visit(stmt->body()); | 267 Visit(stmt->body()); |
| 516 } | 268 } |
| 517 | 269 |
| (...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 av_.Clear(); | 457 av_.Clear(); |
| 706 Visit(expr->arguments()->at(i)); | 458 Visit(expr->arguments()->at(i)); |
| 707 result.Union(av_); | 459 result.Union(av_); |
| 708 } | 460 } |
| 709 av_ = result; | 461 av_ = result; |
| 710 } | 462 } |
| 711 | 463 |
| 712 | 464 |
| 713 void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) { | 465 void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) { |
| 714 ASSERT(av_.IsEmpty()); | 466 ASSERT(av_.IsEmpty()); |
| 467 MarkIfTrivial(expr->expression()); |
| 715 Visit(expr->expression()); | 468 Visit(expr->expression()); |
| 716 } | 469 } |
| 717 | 470 |
| 718 | 471 |
| 719 void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) { | 472 void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) { |
| 720 ASSERT(av_.IsEmpty()); | 473 ASSERT(av_.IsEmpty()); |
| 721 | 474 if (expr->is_prefix()) MarkIfTrivial(expr->expression()); |
| 722 Visit(expr->expression()); | 475 Visit(expr->expression()); |
| 723 | 476 |
| 724 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); | 477 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
| 725 if (var != NULL) RecordAssignedVar(var); | 478 if (var != NULL) RecordAssignedVar(var); |
| 726 } | 479 } |
| 727 | 480 |
| 728 | 481 |
| 729 void AssignedVariablesAnalyzer::VisitBinaryOperation(BinaryOperation* expr) { | 482 void AssignedVariablesAnalyzer::VisitBinaryOperation(BinaryOperation* expr) { |
| 730 ASSERT(av_.IsEmpty()); | 483 ASSERT(av_.IsEmpty()); |
| 731 MarkIfTrivial(expr->right()); | 484 MarkIfTrivial(expr->right()); |
| 732 Visit(expr->right()); | 485 Visit(expr->right()); |
| 733 MarkIfTrivial(expr->left()); | 486 MarkIfTrivial(expr->left()); |
| 734 ProcessExpression(expr->left()); | 487 ProcessExpression(expr->left()); |
| 735 } | 488 } |
| 736 | 489 |
| 737 | 490 |
| 738 void AssignedVariablesAnalyzer::VisitCompareOperation(CompareOperation* expr) { | 491 void AssignedVariablesAnalyzer::VisitCompareOperation(CompareOperation* expr) { |
| 739 ASSERT(av_.IsEmpty()); | 492 ASSERT(av_.IsEmpty()); |
| 740 MarkIfTrivial(expr->right()); | 493 MarkIfTrivial(expr->right()); |
| 741 Visit(expr->right()); | 494 Visit(expr->right()); |
| 742 MarkIfTrivial(expr->left()); | 495 MarkIfTrivial(expr->left()); |
| 743 ProcessExpression(expr->left()); | 496 ProcessExpression(expr->left()); |
| 744 } | 497 } |
| 745 | 498 |
| 746 | 499 |
| 500 void AssignedVariablesAnalyzer::VisitCompareToNull(CompareToNull* expr) { |
| 501 ASSERT(av_.IsEmpty()); |
| 502 MarkIfTrivial(expr->expression()); |
| 503 Visit(expr->expression()); |
| 504 } |
| 505 |
| 506 |
| 747 void AssignedVariablesAnalyzer::VisitThisFunction(ThisFunction* expr) { | 507 void AssignedVariablesAnalyzer::VisitThisFunction(ThisFunction* expr) { |
| 748 // Nothing to do. | 508 // Nothing to do. |
| 749 ASSERT(av_.IsEmpty()); | 509 ASSERT(av_.IsEmpty()); |
| 750 } | 510 } |
| 751 | 511 |
| 752 | 512 |
| 753 void AssignedVariablesAnalyzer::VisitDeclaration(Declaration* decl) { | 513 void AssignedVariablesAnalyzer::VisitDeclaration(Declaration* decl) { |
| 754 UNREACHABLE(); | 514 UNREACHABLE(); |
| 755 } | 515 } |
| 756 | 516 |
| 757 | 517 |
| 758 } } // namespace v8::internal | 518 } } // namespace v8::internal |
| OLD | NEW |