| 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 10 matching lines...) Expand all Loading... |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 #include "v8.h" | 28 #include "v8.h" |
| 29 | 29 |
| 30 #include "data-flow.h" | 30 #include "data-flow.h" |
| 31 #include "scopes.h" | |
| 32 | 31 |
| 33 namespace v8 { | 32 namespace v8 { |
| 34 namespace internal { | 33 namespace internal { |
| 35 | 34 |
| 36 | 35 |
| 37 void FlowGraph::AppendInstruction(AstNode* instruction) { | 36 void FlowGraph::AppendInstruction(AstNode* instruction) { |
| 38 // Add a (non-null) AstNode to the end of the graph fragment. | 37 // Add a (non-null) AstNode to the end of the graph fragment. |
| 39 ASSERT(instruction != NULL); | 38 ASSERT(instruction != NULL); |
| 40 if (exit()->IsExitNode()) return; | 39 if (exit()->IsExitNode()) return; |
| 41 if (!exit()->IsBlockNode()) AppendNode(new BlockNode()); | 40 if (!exit()->IsBlockNode()) AppendNode(new BlockNode()); |
| (...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1029 void LivenessAnalyzer::VisitCompareOperation(CompareOperation* expr) { | 1028 void LivenessAnalyzer::VisitCompareOperation(CompareOperation* expr) { |
| 1030 UNREACHABLE(); | 1029 UNREACHABLE(); |
| 1031 } | 1030 } |
| 1032 | 1031 |
| 1033 | 1032 |
| 1034 void LivenessAnalyzer::VisitThisFunction(ThisFunction* expr) { | 1033 void LivenessAnalyzer::VisitThisFunction(ThisFunction* expr) { |
| 1035 UNREACHABLE(); | 1034 UNREACHABLE(); |
| 1036 } | 1035 } |
| 1037 | 1036 |
| 1038 | 1037 |
| 1039 AssignedVariablesAnalyzer::AssignedVariablesAnalyzer(FunctionLiteral* fun) | |
| 1040 : fun_(fun), | |
| 1041 av_(fun->scope()->num_parameters() + fun->scope()->num_stack_slots()) {} | |
| 1042 | |
| 1043 | |
| 1044 void AssignedVariablesAnalyzer::Analyze() { | |
| 1045 ASSERT(av_.length() > 0); | |
| 1046 VisitStatements(fun_->body()); | |
| 1047 } | |
| 1048 | |
| 1049 | |
| 1050 Variable* AssignedVariablesAnalyzer::FindSmiLoopVariable(ForStatement* stmt) { | |
| 1051 // The loop must have all necessary parts. | |
| 1052 if (stmt->init() == NULL || stmt->cond() == NULL || stmt->next() == NULL) { | |
| 1053 return NULL; | |
| 1054 } | |
| 1055 // The initialization statement has to be a simple assignment. | |
| 1056 Assignment* init = stmt->init()->StatementAsSimpleAssignment(); | |
| 1057 if (init == NULL) return NULL; | |
| 1058 | |
| 1059 // We only deal with local variables. | |
| 1060 Variable* loop_var = init->target()->AsVariableProxy()->AsVariable(); | |
| 1061 if (!loop_var->IsStackAllocated()) return NULL; | |
| 1062 | |
| 1063 // The initial value has to be a smi. | |
| 1064 Literal* init_lit = init->value()->AsLiteral(); | |
| 1065 if (init_lit == NULL || !init_lit->handle()->IsSmi()) return NULL; | |
| 1066 int init_value = Smi::cast(*init_lit->handle())->value(); | |
| 1067 | |
| 1068 // The condition must be a compare of variable with <, <=, >, or >=. | |
| 1069 CompareOperation* cond = stmt->cond()->AsCompareOperation(); | |
| 1070 if (cond == NULL) return NULL; | |
| 1071 if (cond->op() != Token::LT | |
| 1072 && cond->op() != Token::LTE | |
| 1073 && cond->op() != Token::GT | |
| 1074 && cond->op() != Token::GTE) return NULL; | |
| 1075 | |
| 1076 // The lhs must be the same variable as in the init expression. | |
| 1077 if (cond->left()->AsVariableProxy()->AsVariable() != loop_var) return NULL; | |
| 1078 | |
| 1079 // The rhs must be a smi. | |
| 1080 Literal* term_lit = cond->right()->AsLiteral(); | |
| 1081 if (term_lit == NULL || !term_lit->handle()->IsSmi()) return NULL; | |
| 1082 int term_value = Smi::cast(*term_lit->handle())->value(); | |
| 1083 | |
| 1084 // The count operation updates the same variable as in the init expression. | |
| 1085 CountOperation* update = stmt->next()->StatementAsCountOperation(); | |
| 1086 if (update == NULL) return NULL; | |
| 1087 if (update->expression()->AsVariableProxy()->AsVariable() != loop_var) { | |
| 1088 return NULL; | |
| 1089 } | |
| 1090 | |
| 1091 // The direction of the count operation must agree with the start and the end | |
| 1092 // value. We currently do not allow the initial value to be the same as the | |
| 1093 // terminal value. This _would_ be ok as long as the loop body never executes | |
| 1094 // or executes exactly one time. | |
| 1095 if (init_value == term_value) return NULL; | |
| 1096 if (init_value < term_value && update->op() != Token::INC) return NULL; | |
| 1097 if (init_value > term_value && update->op() != Token::DEC) return NULL; | |
| 1098 | |
| 1099 // Found a smi loop variable. | |
| 1100 return loop_var; | |
| 1101 } | |
| 1102 | |
| 1103 int AssignedVariablesAnalyzer::BitIndex(Variable* var) { | |
| 1104 ASSERT(var != NULL); | |
| 1105 ASSERT(var->IsStackAllocated()); | |
| 1106 Slot* slot = var->slot(); | |
| 1107 if (slot->type() == Slot::PARAMETER) { | |
| 1108 return slot->index(); | |
| 1109 } else { | |
| 1110 return fun_->scope()->num_parameters() + slot->index(); | |
| 1111 } | |
| 1112 } | |
| 1113 | |
| 1114 | |
| 1115 void AssignedVariablesAnalyzer::RecordAssignedVar(Variable* var) { | |
| 1116 ASSERT(var != NULL); | |
| 1117 if (var->IsStackAllocated()) { | |
| 1118 av_.Add(BitIndex(var)); | |
| 1119 } | |
| 1120 } | |
| 1121 | |
| 1122 | |
| 1123 void AssignedVariablesAnalyzer::MarkIfTrivial(Expression* expr) { | |
| 1124 Variable* var = expr->AsVariableProxy()->AsVariable(); | |
| 1125 if (var != NULL && | |
| 1126 var->IsStackAllocated() && | |
| 1127 (var->is_this() || !av_.Contains(BitIndex(var)))) { | |
| 1128 expr->AsVariableProxy()->set_is_trivial(true); | |
| 1129 } | |
| 1130 } | |
| 1131 | |
| 1132 | |
| 1133 void AssignedVariablesAnalyzer::ProcessExpression(Expression* expr) { | |
| 1134 BitVector saved_av(av_); | |
| 1135 av_.Clear(); | |
| 1136 Visit(expr); | |
| 1137 av_.Union(saved_av); | |
| 1138 } | |
| 1139 | |
| 1140 void AssignedVariablesAnalyzer::VisitBlock(Block* stmt) { | |
| 1141 VisitStatements(stmt->statements()); | |
| 1142 } | |
| 1143 | |
| 1144 | |
| 1145 void AssignedVariablesAnalyzer::VisitExpressionStatement( | |
| 1146 ExpressionStatement* stmt) { | |
| 1147 ProcessExpression(stmt->expression()); | |
| 1148 } | |
| 1149 | |
| 1150 | |
| 1151 void AssignedVariablesAnalyzer::VisitEmptyStatement(EmptyStatement* stmt) { | |
| 1152 // Do nothing. | |
| 1153 } | |
| 1154 | |
| 1155 | |
| 1156 void AssignedVariablesAnalyzer::VisitIfStatement(IfStatement* stmt) { | |
| 1157 ProcessExpression(stmt->condition()); | |
| 1158 Visit(stmt->then_statement()); | |
| 1159 Visit(stmt->else_statement()); | |
| 1160 } | |
| 1161 | |
| 1162 | |
| 1163 void AssignedVariablesAnalyzer::VisitContinueStatement( | |
| 1164 ContinueStatement* stmt) { | |
| 1165 // Nothing to do. | |
| 1166 } | |
| 1167 | |
| 1168 | |
| 1169 void AssignedVariablesAnalyzer::VisitBreakStatement(BreakStatement* stmt) { | |
| 1170 // Nothing to do. | |
| 1171 } | |
| 1172 | |
| 1173 | |
| 1174 void AssignedVariablesAnalyzer::VisitReturnStatement(ReturnStatement* stmt) { | |
| 1175 ProcessExpression(stmt->expression()); | |
| 1176 } | |
| 1177 | |
| 1178 | |
| 1179 void AssignedVariablesAnalyzer::VisitWithEnterStatement( | |
| 1180 WithEnterStatement* stmt) { | |
| 1181 ProcessExpression(stmt->expression()); | |
| 1182 } | |
| 1183 | |
| 1184 | |
| 1185 void AssignedVariablesAnalyzer::VisitWithExitStatement( | |
| 1186 WithExitStatement* stmt) { | |
| 1187 // Nothing to do. | |
| 1188 } | |
| 1189 | |
| 1190 | |
| 1191 void AssignedVariablesAnalyzer::VisitSwitchStatement(SwitchStatement* stmt) { | |
| 1192 BitVector result(av_); | |
| 1193 av_.Clear(); | |
| 1194 Visit(stmt->tag()); | |
| 1195 result.Union(av_); | |
| 1196 for (int i = 0; i < stmt->cases()->length(); i++) { | |
| 1197 CaseClause* clause = stmt->cases()->at(i); | |
| 1198 if (!clause->is_default()) { | |
| 1199 av_.Clear(); | |
| 1200 Visit(clause->label()); | |
| 1201 result.Union(av_); | |
| 1202 } | |
| 1203 VisitStatements(clause->statements()); | |
| 1204 } | |
| 1205 av_.Union(result); | |
| 1206 } | |
| 1207 | |
| 1208 | |
| 1209 void AssignedVariablesAnalyzer::VisitDoWhileStatement(DoWhileStatement* stmt) { | |
| 1210 ProcessExpression(stmt->cond()); | |
| 1211 Visit(stmt->body()); | |
| 1212 } | |
| 1213 | |
| 1214 | |
| 1215 void AssignedVariablesAnalyzer::VisitWhileStatement(WhileStatement* stmt) { | |
| 1216 ProcessExpression(stmt->cond()); | |
| 1217 Visit(stmt->body()); | |
| 1218 } | |
| 1219 | |
| 1220 | |
| 1221 void AssignedVariablesAnalyzer::VisitForStatement(ForStatement* stmt) { | |
| 1222 if (stmt->init() != NULL) Visit(stmt->init()); | |
| 1223 | |
| 1224 if (stmt->cond() != NULL) ProcessExpression(stmt->cond()); | |
| 1225 | |
| 1226 if (stmt->next() != NULL) Visit(stmt->next()); | |
| 1227 | |
| 1228 // Process loop body. After visiting the loop body av_ contains | |
| 1229 // the assigned variables of the loop body. | |
| 1230 BitVector saved_av(av_); | |
| 1231 av_.Clear(); | |
| 1232 Visit(stmt->body()); | |
| 1233 | |
| 1234 Variable* var = FindSmiLoopVariable(stmt); | |
| 1235 if (var != NULL && !av_.Contains(BitIndex(var))) { | |
| 1236 stmt->set_loop_variable(var); | |
| 1237 } | |
| 1238 | |
| 1239 av_.Union(saved_av); | |
| 1240 } | |
| 1241 | |
| 1242 | |
| 1243 void AssignedVariablesAnalyzer::VisitForInStatement(ForInStatement* stmt) { | |
| 1244 ProcessExpression(stmt->each()); | |
| 1245 ProcessExpression(stmt->enumerable()); | |
| 1246 Visit(stmt->body()); | |
| 1247 } | |
| 1248 | |
| 1249 | |
| 1250 void AssignedVariablesAnalyzer::VisitTryCatchStatement( | |
| 1251 TryCatchStatement* stmt) { | |
| 1252 Visit(stmt->try_block()); | |
| 1253 Visit(stmt->catch_block()); | |
| 1254 } | |
| 1255 | |
| 1256 | |
| 1257 void AssignedVariablesAnalyzer::VisitTryFinallyStatement( | |
| 1258 TryFinallyStatement* stmt) { | |
| 1259 Visit(stmt->try_block()); | |
| 1260 Visit(stmt->finally_block()); | |
| 1261 } | |
| 1262 | |
| 1263 | |
| 1264 void AssignedVariablesAnalyzer::VisitDebuggerStatement( | |
| 1265 DebuggerStatement* stmt) { | |
| 1266 // Nothing to do. | |
| 1267 } | |
| 1268 | |
| 1269 | |
| 1270 void AssignedVariablesAnalyzer::VisitFunctionLiteral(FunctionLiteral* expr) { | |
| 1271 // Nothing to do. | |
| 1272 ASSERT(av_.IsEmpty()); | |
| 1273 } | |
| 1274 | |
| 1275 | |
| 1276 void AssignedVariablesAnalyzer::VisitFunctionBoilerplateLiteral( | |
| 1277 FunctionBoilerplateLiteral* expr) { | |
| 1278 // Nothing to do. | |
| 1279 ASSERT(av_.IsEmpty()); | |
| 1280 } | |
| 1281 | |
| 1282 | |
| 1283 void AssignedVariablesAnalyzer::VisitConditional(Conditional* expr) { | |
| 1284 ASSERT(av_.IsEmpty()); | |
| 1285 | |
| 1286 Visit(expr->condition()); | |
| 1287 | |
| 1288 BitVector result(av_); | |
| 1289 av_.Clear(); | |
| 1290 Visit(expr->then_expression()); | |
| 1291 result.Union(av_); | |
| 1292 | |
| 1293 av_.Clear(); | |
| 1294 Visit(expr->else_expression()); | |
| 1295 av_.Union(result); | |
| 1296 } | |
| 1297 | |
| 1298 | |
| 1299 void AssignedVariablesAnalyzer::VisitSlot(Slot* expr) { | |
| 1300 UNREACHABLE(); | |
| 1301 } | |
| 1302 | |
| 1303 | |
| 1304 void AssignedVariablesAnalyzer::VisitVariableProxy(VariableProxy* expr) { | |
| 1305 // Nothing to do. | |
| 1306 ASSERT(av_.IsEmpty()); | |
| 1307 } | |
| 1308 | |
| 1309 | |
| 1310 void AssignedVariablesAnalyzer::VisitLiteral(Literal* expr) { | |
| 1311 // Nothing to do. | |
| 1312 ASSERT(av_.IsEmpty()); | |
| 1313 } | |
| 1314 | |
| 1315 | |
| 1316 void AssignedVariablesAnalyzer::VisitRegExpLiteral(RegExpLiteral* expr) { | |
| 1317 // Nothing to do. | |
| 1318 ASSERT(av_.IsEmpty()); | |
| 1319 } | |
| 1320 | |
| 1321 | |
| 1322 void AssignedVariablesAnalyzer::VisitObjectLiteral(ObjectLiteral* expr) { | |
| 1323 ASSERT(av_.IsEmpty()); | |
| 1324 BitVector result(av_.length()); | |
| 1325 for (int i = 0; i < expr->properties()->length(); i++) { | |
| 1326 Visit(expr->properties()->at(i)->value()); | |
| 1327 result.Union(av_); | |
| 1328 av_.Clear(); | |
| 1329 } | |
| 1330 av_.CopyFrom(result); | |
| 1331 } | |
| 1332 | |
| 1333 | |
| 1334 void AssignedVariablesAnalyzer::VisitArrayLiteral(ArrayLiteral* expr) { | |
| 1335 ASSERT(av_.IsEmpty()); | |
| 1336 BitVector result(av_.length()); | |
| 1337 for (int i = 0; i < expr->values()->length(); i++) { | |
| 1338 Visit(expr->values()->at(i)); | |
| 1339 result.Union(av_); | |
| 1340 av_.Clear(); | |
| 1341 } | |
| 1342 av_.CopyFrom(result); | |
| 1343 } | |
| 1344 | |
| 1345 | |
| 1346 void AssignedVariablesAnalyzer::VisitCatchExtensionObject( | |
| 1347 CatchExtensionObject* expr) { | |
| 1348 ASSERT(av_.IsEmpty()); | |
| 1349 Visit(expr->key()); | |
| 1350 ProcessExpression(expr->value()); | |
| 1351 } | |
| 1352 | |
| 1353 | |
| 1354 void AssignedVariablesAnalyzer::VisitAssignment(Assignment* expr) { | |
| 1355 ASSERT(av_.IsEmpty()); | |
| 1356 | |
| 1357 Visit(expr->target()); | |
| 1358 | |
| 1359 ProcessExpression(expr->value()); | |
| 1360 | |
| 1361 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); | |
| 1362 if (var != NULL) RecordAssignedVar(var); | |
| 1363 | |
| 1364 // If we have a variable as a receiver in a property store, check if | |
| 1365 // we can mark it as trivial. | |
| 1366 if (expr->target()->AsProperty() != NULL) { | |
| 1367 MarkIfTrivial(expr->target()->AsProperty()->obj()); | |
| 1368 } | |
| 1369 } | |
| 1370 | |
| 1371 | |
| 1372 void AssignedVariablesAnalyzer::VisitThrow(Throw* expr) { | |
| 1373 ASSERT(av_.IsEmpty()); | |
| 1374 Visit(expr->exception()); | |
| 1375 } | |
| 1376 | |
| 1377 | |
| 1378 void AssignedVariablesAnalyzer::VisitProperty(Property* expr) { | |
| 1379 ASSERT(av_.IsEmpty()); | |
| 1380 Visit(expr->obj()); | |
| 1381 ProcessExpression(expr->key()); | |
| 1382 | |
| 1383 // In case we have a variable as a receiver, check if we can mark | |
| 1384 // it as trivial. | |
| 1385 MarkIfTrivial(expr->obj()); | |
| 1386 } | |
| 1387 | |
| 1388 | |
| 1389 void AssignedVariablesAnalyzer::VisitCall(Call* expr) { | |
| 1390 ASSERT(av_.IsEmpty()); | |
| 1391 Visit(expr->expression()); | |
| 1392 BitVector result(av_); | |
| 1393 for (int i = 0; i < expr->arguments()->length(); i++) { | |
| 1394 av_.Clear(); | |
| 1395 Visit(expr->arguments()->at(i)); | |
| 1396 result.Union(av_); | |
| 1397 } | |
| 1398 av_.CopyFrom(result); | |
| 1399 } | |
| 1400 | |
| 1401 | |
| 1402 void AssignedVariablesAnalyzer::VisitCallNew(CallNew* expr) { | |
| 1403 ASSERT(av_.IsEmpty()); | |
| 1404 Visit(expr->expression()); | |
| 1405 BitVector result(av_); | |
| 1406 for (int i = 0; i < expr->arguments()->length(); i++) { | |
| 1407 av_.Clear(); | |
| 1408 Visit(expr->arguments()->at(i)); | |
| 1409 result.Union(av_); | |
| 1410 } | |
| 1411 av_.CopyFrom(result); | |
| 1412 } | |
| 1413 | |
| 1414 | |
| 1415 void AssignedVariablesAnalyzer::VisitCallRuntime(CallRuntime* expr) { | |
| 1416 ASSERT(av_.IsEmpty()); | |
| 1417 BitVector result(av_); | |
| 1418 for (int i = 0; i < expr->arguments()->length(); i++) { | |
| 1419 av_.Clear(); | |
| 1420 Visit(expr->arguments()->at(i)); | |
| 1421 result.Union(av_); | |
| 1422 } | |
| 1423 av_.CopyFrom(result); | |
| 1424 } | |
| 1425 | |
| 1426 | |
| 1427 void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) { | |
| 1428 ASSERT(av_.IsEmpty()); | |
| 1429 Visit(expr->expression()); | |
| 1430 } | |
| 1431 | |
| 1432 | |
| 1433 void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) { | |
| 1434 ASSERT(av_.IsEmpty()); | |
| 1435 | |
| 1436 Visit(expr->expression()); | |
| 1437 | |
| 1438 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); | |
| 1439 if (var != NULL) RecordAssignedVar(var); | |
| 1440 } | |
| 1441 | |
| 1442 | |
| 1443 void AssignedVariablesAnalyzer::VisitBinaryOperation(BinaryOperation* expr) { | |
| 1444 ASSERT(av_.IsEmpty()); | |
| 1445 Visit(expr->left()); | |
| 1446 | |
| 1447 ProcessExpression(expr->right()); | |
| 1448 | |
| 1449 // In case we have a variable on the left side, check if we can mark | |
| 1450 // it as trivial. | |
| 1451 MarkIfTrivial(expr->left()); | |
| 1452 } | |
| 1453 | |
| 1454 | |
| 1455 void AssignedVariablesAnalyzer::VisitCompareOperation(CompareOperation* expr) { | |
| 1456 ASSERT(av_.IsEmpty()); | |
| 1457 Visit(expr->left()); | |
| 1458 | |
| 1459 ProcessExpression(expr->right()); | |
| 1460 | |
| 1461 // In case we have a variable on the left side, check if we can mark | |
| 1462 // it as trivial. | |
| 1463 MarkIfTrivial(expr->left()); | |
| 1464 } | |
| 1465 | |
| 1466 | |
| 1467 void AssignedVariablesAnalyzer::VisitThisFunction(ThisFunction* expr) { | |
| 1468 // Nothing to do. | |
| 1469 ASSERT(av_.IsEmpty()); | |
| 1470 } | |
| 1471 | |
| 1472 | |
| 1473 void AssignedVariablesAnalyzer::VisitDeclaration(Declaration* decl) { | |
| 1474 UNREACHABLE(); | |
| 1475 } | |
| 1476 | |
| 1477 | |
| 1478 #ifdef DEBUG | 1038 #ifdef DEBUG |
| 1479 | 1039 |
| 1480 // Print a textual representation of an instruction in a flow graph. Using | 1040 // Print a textual representation of an instruction in a flow graph. Using |
| 1481 // the AstVisitor is overkill because there is no recursion here. It is | 1041 // the AstVisitor is overkill because there is no recursion here. It is |
| 1482 // only used for printing in debug mode. | 1042 // only used for printing in debug mode. |
| 1483 class TextInstructionPrinter: public AstVisitor { | 1043 class TextInstructionPrinter: public AstVisitor { |
| 1484 public: | 1044 public: |
| 1485 TextInstructionPrinter() {} | 1045 TextInstructionPrinter() {} |
| 1486 | 1046 |
| 1487 private: | 1047 private: |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1830 for (int i = postorder->length() - 1; i >= 0; i--) { | 1390 for (int i = postorder->length() - 1; i >= 0; i--) { |
| 1831 postorder->at(i)->PrintText(); | 1391 postorder->at(i)->PrintText(); |
| 1832 } | 1392 } |
| 1833 } | 1393 } |
| 1834 | 1394 |
| 1835 | 1395 |
| 1836 #endif // defined(DEBUG) | 1396 #endif // defined(DEBUG) |
| 1837 | 1397 |
| 1838 | 1398 |
| 1839 } } // namespace v8::internal | 1399 } } // namespace v8::internal |
| OLD | NEW |