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" |
31 | 32 |
32 namespace v8 { | 33 namespace v8 { |
33 namespace internal { | 34 namespace internal { |
34 | 35 |
35 | 36 |
36 void FlowGraph::AppendInstruction(AstNode* instruction) { | 37 void FlowGraph::AppendInstruction(AstNode* instruction) { |
37 // Add a (non-null) AstNode to the end of the graph fragment. | 38 // Add a (non-null) AstNode to the end of the graph fragment. |
38 ASSERT(instruction != NULL); | 39 ASSERT(instruction != NULL); |
39 if (exit()->IsExitNode()) return; | 40 if (exit()->IsExitNode()) return; |
40 if (!exit()->IsBlockNode()) AppendNode(new BlockNode()); | 41 if (!exit()->IsBlockNode()) AppendNode(new BlockNode()); |
(...skipping 987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1028 void LivenessAnalyzer::VisitCompareOperation(CompareOperation* expr) { | 1029 void LivenessAnalyzer::VisitCompareOperation(CompareOperation* expr) { |
1029 UNREACHABLE(); | 1030 UNREACHABLE(); |
1030 } | 1031 } |
1031 | 1032 |
1032 | 1033 |
1033 void LivenessAnalyzer::VisitThisFunction(ThisFunction* expr) { | 1034 void LivenessAnalyzer::VisitThisFunction(ThisFunction* expr) { |
1034 UNREACHABLE(); | 1035 UNREACHABLE(); |
1035 } | 1036 } |
1036 | 1037 |
1037 | 1038 |
| 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_arguments() && |
| 1128 (var->is_this() || !av_.Contains(BitIndex(var)))) { |
| 1129 expr->AsVariableProxy()->set_is_trivial(true); |
| 1130 } |
| 1131 } |
| 1132 |
| 1133 |
| 1134 void AssignedVariablesAnalyzer::ProcessExpression(Expression* expr) { |
| 1135 BitVector saved_av(av_); |
| 1136 av_.Clear(); |
| 1137 Visit(expr); |
| 1138 av_.Union(saved_av); |
| 1139 } |
| 1140 |
| 1141 void AssignedVariablesAnalyzer::VisitBlock(Block* stmt) { |
| 1142 VisitStatements(stmt->statements()); |
| 1143 } |
| 1144 |
| 1145 |
| 1146 void AssignedVariablesAnalyzer::VisitExpressionStatement( |
| 1147 ExpressionStatement* stmt) { |
| 1148 ProcessExpression(stmt->expression()); |
| 1149 } |
| 1150 |
| 1151 |
| 1152 void AssignedVariablesAnalyzer::VisitEmptyStatement(EmptyStatement* stmt) { |
| 1153 // Do nothing. |
| 1154 } |
| 1155 |
| 1156 |
| 1157 void AssignedVariablesAnalyzer::VisitIfStatement(IfStatement* stmt) { |
| 1158 ProcessExpression(stmt->condition()); |
| 1159 Visit(stmt->then_statement()); |
| 1160 Visit(stmt->else_statement()); |
| 1161 } |
| 1162 |
| 1163 |
| 1164 void AssignedVariablesAnalyzer::VisitContinueStatement( |
| 1165 ContinueStatement* stmt) { |
| 1166 // Nothing to do. |
| 1167 } |
| 1168 |
| 1169 |
| 1170 void AssignedVariablesAnalyzer::VisitBreakStatement(BreakStatement* stmt) { |
| 1171 // Nothing to do. |
| 1172 } |
| 1173 |
| 1174 |
| 1175 void AssignedVariablesAnalyzer::VisitReturnStatement(ReturnStatement* stmt) { |
| 1176 ProcessExpression(stmt->expression()); |
| 1177 } |
| 1178 |
| 1179 |
| 1180 void AssignedVariablesAnalyzer::VisitWithEnterStatement( |
| 1181 WithEnterStatement* stmt) { |
| 1182 ProcessExpression(stmt->expression()); |
| 1183 } |
| 1184 |
| 1185 |
| 1186 void AssignedVariablesAnalyzer::VisitWithExitStatement( |
| 1187 WithExitStatement* stmt) { |
| 1188 // Nothing to do. |
| 1189 } |
| 1190 |
| 1191 |
| 1192 void AssignedVariablesAnalyzer::VisitSwitchStatement(SwitchStatement* stmt) { |
| 1193 BitVector result(av_); |
| 1194 av_.Clear(); |
| 1195 Visit(stmt->tag()); |
| 1196 result.Union(av_); |
| 1197 for (int i = 0; i < stmt->cases()->length(); i++) { |
| 1198 CaseClause* clause = stmt->cases()->at(i); |
| 1199 if (!clause->is_default()) { |
| 1200 av_.Clear(); |
| 1201 Visit(clause->label()); |
| 1202 result.Union(av_); |
| 1203 } |
| 1204 VisitStatements(clause->statements()); |
| 1205 } |
| 1206 av_.Union(result); |
| 1207 } |
| 1208 |
| 1209 |
| 1210 void AssignedVariablesAnalyzer::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 1211 ProcessExpression(stmt->cond()); |
| 1212 Visit(stmt->body()); |
| 1213 } |
| 1214 |
| 1215 |
| 1216 void AssignedVariablesAnalyzer::VisitWhileStatement(WhileStatement* stmt) { |
| 1217 ProcessExpression(stmt->cond()); |
| 1218 Visit(stmt->body()); |
| 1219 } |
| 1220 |
| 1221 |
| 1222 void AssignedVariablesAnalyzer::VisitForStatement(ForStatement* stmt) { |
| 1223 if (stmt->init() != NULL) Visit(stmt->init()); |
| 1224 |
| 1225 if (stmt->cond() != NULL) ProcessExpression(stmt->cond()); |
| 1226 |
| 1227 if (stmt->next() != NULL) Visit(stmt->next()); |
| 1228 |
| 1229 // Process loop body. After visiting the loop body av_ contains |
| 1230 // the assigned variables of the loop body. |
| 1231 BitVector saved_av(av_); |
| 1232 av_.Clear(); |
| 1233 Visit(stmt->body()); |
| 1234 |
| 1235 Variable* var = FindSmiLoopVariable(stmt); |
| 1236 if (var != NULL && !av_.Contains(BitIndex(var))) { |
| 1237 stmt->set_loop_variable(var); |
| 1238 } |
| 1239 |
| 1240 av_.Union(saved_av); |
| 1241 } |
| 1242 |
| 1243 |
| 1244 void AssignedVariablesAnalyzer::VisitForInStatement(ForInStatement* stmt) { |
| 1245 ProcessExpression(stmt->each()); |
| 1246 ProcessExpression(stmt->enumerable()); |
| 1247 Visit(stmt->body()); |
| 1248 } |
| 1249 |
| 1250 |
| 1251 void AssignedVariablesAnalyzer::VisitTryCatchStatement( |
| 1252 TryCatchStatement* stmt) { |
| 1253 Visit(stmt->try_block()); |
| 1254 Visit(stmt->catch_block()); |
| 1255 } |
| 1256 |
| 1257 |
| 1258 void AssignedVariablesAnalyzer::VisitTryFinallyStatement( |
| 1259 TryFinallyStatement* stmt) { |
| 1260 Visit(stmt->try_block()); |
| 1261 Visit(stmt->finally_block()); |
| 1262 } |
| 1263 |
| 1264 |
| 1265 void AssignedVariablesAnalyzer::VisitDebuggerStatement( |
| 1266 DebuggerStatement* stmt) { |
| 1267 // Nothing to do. |
| 1268 } |
| 1269 |
| 1270 |
| 1271 void AssignedVariablesAnalyzer::VisitFunctionLiteral(FunctionLiteral* expr) { |
| 1272 // Nothing to do. |
| 1273 ASSERT(av_.IsEmpty()); |
| 1274 } |
| 1275 |
| 1276 |
| 1277 void AssignedVariablesAnalyzer::VisitFunctionBoilerplateLiteral( |
| 1278 FunctionBoilerplateLiteral* expr) { |
| 1279 // Nothing to do. |
| 1280 ASSERT(av_.IsEmpty()); |
| 1281 } |
| 1282 |
| 1283 |
| 1284 void AssignedVariablesAnalyzer::VisitConditional(Conditional* expr) { |
| 1285 ASSERT(av_.IsEmpty()); |
| 1286 |
| 1287 Visit(expr->condition()); |
| 1288 |
| 1289 BitVector result(av_); |
| 1290 av_.Clear(); |
| 1291 Visit(expr->then_expression()); |
| 1292 result.Union(av_); |
| 1293 |
| 1294 av_.Clear(); |
| 1295 Visit(expr->else_expression()); |
| 1296 av_.Union(result); |
| 1297 } |
| 1298 |
| 1299 |
| 1300 void AssignedVariablesAnalyzer::VisitSlot(Slot* expr) { |
| 1301 UNREACHABLE(); |
| 1302 } |
| 1303 |
| 1304 |
| 1305 void AssignedVariablesAnalyzer::VisitVariableProxy(VariableProxy* expr) { |
| 1306 // Nothing to do. |
| 1307 ASSERT(av_.IsEmpty()); |
| 1308 } |
| 1309 |
| 1310 |
| 1311 void AssignedVariablesAnalyzer::VisitLiteral(Literal* expr) { |
| 1312 // Nothing to do. |
| 1313 ASSERT(av_.IsEmpty()); |
| 1314 } |
| 1315 |
| 1316 |
| 1317 void AssignedVariablesAnalyzer::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 1318 // Nothing to do. |
| 1319 ASSERT(av_.IsEmpty()); |
| 1320 } |
| 1321 |
| 1322 |
| 1323 void AssignedVariablesAnalyzer::VisitObjectLiteral(ObjectLiteral* expr) { |
| 1324 ASSERT(av_.IsEmpty()); |
| 1325 BitVector result(av_.length()); |
| 1326 for (int i = 0; i < expr->properties()->length(); i++) { |
| 1327 Visit(expr->properties()->at(i)->value()); |
| 1328 result.Union(av_); |
| 1329 av_.Clear(); |
| 1330 } |
| 1331 av_.CopyFrom(result); |
| 1332 } |
| 1333 |
| 1334 |
| 1335 void AssignedVariablesAnalyzer::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1336 ASSERT(av_.IsEmpty()); |
| 1337 BitVector result(av_.length()); |
| 1338 for (int i = 0; i < expr->values()->length(); i++) { |
| 1339 Visit(expr->values()->at(i)); |
| 1340 result.Union(av_); |
| 1341 av_.Clear(); |
| 1342 } |
| 1343 av_.CopyFrom(result); |
| 1344 } |
| 1345 |
| 1346 |
| 1347 void AssignedVariablesAnalyzer::VisitCatchExtensionObject( |
| 1348 CatchExtensionObject* expr) { |
| 1349 ASSERT(av_.IsEmpty()); |
| 1350 Visit(expr->key()); |
| 1351 ProcessExpression(expr->value()); |
| 1352 } |
| 1353 |
| 1354 |
| 1355 void AssignedVariablesAnalyzer::VisitAssignment(Assignment* expr) { |
| 1356 ASSERT(av_.IsEmpty()); |
| 1357 |
| 1358 Visit(expr->target()); |
| 1359 |
| 1360 ProcessExpression(expr->value()); |
| 1361 |
| 1362 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
| 1363 if (var != NULL) RecordAssignedVar(var); |
| 1364 |
| 1365 // If we have a variable as a receiver in a property store, check if |
| 1366 // we can mark it as trivial. |
| 1367 if (expr->target()->AsProperty() != NULL) { |
| 1368 MarkIfTrivial(expr->target()->AsProperty()->obj()); |
| 1369 } |
| 1370 } |
| 1371 |
| 1372 |
| 1373 void AssignedVariablesAnalyzer::VisitThrow(Throw* expr) { |
| 1374 ASSERT(av_.IsEmpty()); |
| 1375 Visit(expr->exception()); |
| 1376 } |
| 1377 |
| 1378 |
| 1379 void AssignedVariablesAnalyzer::VisitProperty(Property* expr) { |
| 1380 ASSERT(av_.IsEmpty()); |
| 1381 Visit(expr->obj()); |
| 1382 ProcessExpression(expr->key()); |
| 1383 |
| 1384 // In case we have a variable as a receiver, check if we can mark |
| 1385 // it as trivial. |
| 1386 MarkIfTrivial(expr->obj()); |
| 1387 } |
| 1388 |
| 1389 |
| 1390 void AssignedVariablesAnalyzer::VisitCall(Call* expr) { |
| 1391 ASSERT(av_.IsEmpty()); |
| 1392 Visit(expr->expression()); |
| 1393 BitVector result(av_); |
| 1394 for (int i = 0; i < expr->arguments()->length(); i++) { |
| 1395 av_.Clear(); |
| 1396 Visit(expr->arguments()->at(i)); |
| 1397 result.Union(av_); |
| 1398 } |
| 1399 av_.CopyFrom(result); |
| 1400 } |
| 1401 |
| 1402 |
| 1403 void AssignedVariablesAnalyzer::VisitCallNew(CallNew* expr) { |
| 1404 ASSERT(av_.IsEmpty()); |
| 1405 Visit(expr->expression()); |
| 1406 BitVector result(av_); |
| 1407 for (int i = 0; i < expr->arguments()->length(); i++) { |
| 1408 av_.Clear(); |
| 1409 Visit(expr->arguments()->at(i)); |
| 1410 result.Union(av_); |
| 1411 } |
| 1412 av_.CopyFrom(result); |
| 1413 } |
| 1414 |
| 1415 |
| 1416 void AssignedVariablesAnalyzer::VisitCallRuntime(CallRuntime* expr) { |
| 1417 ASSERT(av_.IsEmpty()); |
| 1418 BitVector result(av_); |
| 1419 for (int i = 0; i < expr->arguments()->length(); i++) { |
| 1420 av_.Clear(); |
| 1421 Visit(expr->arguments()->at(i)); |
| 1422 result.Union(av_); |
| 1423 } |
| 1424 av_.CopyFrom(result); |
| 1425 } |
| 1426 |
| 1427 |
| 1428 void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) { |
| 1429 ASSERT(av_.IsEmpty()); |
| 1430 Visit(expr->expression()); |
| 1431 } |
| 1432 |
| 1433 |
| 1434 void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) { |
| 1435 ASSERT(av_.IsEmpty()); |
| 1436 |
| 1437 Visit(expr->expression()); |
| 1438 |
| 1439 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
| 1440 if (var != NULL) RecordAssignedVar(var); |
| 1441 } |
| 1442 |
| 1443 |
| 1444 void AssignedVariablesAnalyzer::VisitBinaryOperation(BinaryOperation* expr) { |
| 1445 ASSERT(av_.IsEmpty()); |
| 1446 Visit(expr->left()); |
| 1447 |
| 1448 ProcessExpression(expr->right()); |
| 1449 |
| 1450 // In case we have a variable on the left side, check if we can mark |
| 1451 // it as trivial. |
| 1452 MarkIfTrivial(expr->left()); |
| 1453 } |
| 1454 |
| 1455 |
| 1456 void AssignedVariablesAnalyzer::VisitCompareOperation(CompareOperation* expr) { |
| 1457 ASSERT(av_.IsEmpty()); |
| 1458 Visit(expr->left()); |
| 1459 |
| 1460 ProcessExpression(expr->right()); |
| 1461 |
| 1462 // In case we have a variable on the left side, check if we can mark |
| 1463 // it as trivial. |
| 1464 MarkIfTrivial(expr->left()); |
| 1465 } |
| 1466 |
| 1467 |
| 1468 void AssignedVariablesAnalyzer::VisitThisFunction(ThisFunction* expr) { |
| 1469 // Nothing to do. |
| 1470 ASSERT(av_.IsEmpty()); |
| 1471 } |
| 1472 |
| 1473 |
| 1474 void AssignedVariablesAnalyzer::VisitDeclaration(Declaration* decl) { |
| 1475 UNREACHABLE(); |
| 1476 } |
| 1477 |
| 1478 |
1038 #ifdef DEBUG | 1479 #ifdef DEBUG |
1039 | 1480 |
1040 // Print a textual representation of an instruction in a flow graph. Using | 1481 // Print a textual representation of an instruction in a flow graph. Using |
1041 // the AstVisitor is overkill because there is no recursion here. It is | 1482 // the AstVisitor is overkill because there is no recursion here. It is |
1042 // only used for printing in debug mode. | 1483 // only used for printing in debug mode. |
1043 class TextInstructionPrinter: public AstVisitor { | 1484 class TextInstructionPrinter: public AstVisitor { |
1044 public: | 1485 public: |
1045 TextInstructionPrinter() {} | 1486 TextInstructionPrinter() {} |
1046 | 1487 |
1047 private: | 1488 private: |
(...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1390 for (int i = postorder->length() - 1; i >= 0; i--) { | 1831 for (int i = postorder->length() - 1; i >= 0; i--) { |
1391 postorder->at(i)->PrintText(); | 1832 postorder->at(i)->PrintText(); |
1392 } | 1833 } |
1393 } | 1834 } |
1394 | 1835 |
1395 | 1836 |
1396 #endif // defined(DEBUG) | 1837 #endif // defined(DEBUG) |
1397 | 1838 |
1398 | 1839 |
1399 } } // namespace v8::internal | 1840 } } // namespace v8::internal |
OLD | NEW |