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 ASSERT(instruction != NULL); | 38 ASSERT(instruction != NULL); |
38 if (is_empty() || !exit()->IsBlockNode()) { | 39 if (is_empty() || !exit()->IsBlockNode()) { |
39 AppendNode(new BlockNode()); | 40 AppendNode(new BlockNode()); |
40 } | 41 } |
(...skipping 1050 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1091 void LivenessAnalyzer::VisitCompareOperation(CompareOperation* expr) { | 1092 void LivenessAnalyzer::VisitCompareOperation(CompareOperation* expr) { |
1092 UNREACHABLE(); | 1093 UNREACHABLE(); |
1093 } | 1094 } |
1094 | 1095 |
1095 | 1096 |
1096 void LivenessAnalyzer::VisitThisFunction(ThisFunction* expr) { | 1097 void LivenessAnalyzer::VisitThisFunction(ThisFunction* expr) { |
1097 UNREACHABLE(); | 1098 UNREACHABLE(); |
1098 } | 1099 } |
1099 | 1100 |
1100 | 1101 |
| 1102 AssignedVariablesAnalyzer::AssignedVariablesAnalyzer(FunctionLiteral* fun) |
| 1103 : fun_(fun), |
| 1104 av_(fun->scope()->num_parameters() + fun->scope()->num_stack_slots()) {} |
| 1105 |
| 1106 |
| 1107 void AssignedVariablesAnalyzer::Analyze() { |
| 1108 ASSERT(av_.length() > 0); |
| 1109 VisitStatements(fun_->body()); |
| 1110 } |
| 1111 |
| 1112 |
| 1113 Variable* AssignedVariablesAnalyzer::FindSmiLoopVariable(ForStatement* stmt) { |
| 1114 // The loop must have all necessary parts. |
| 1115 if (stmt->init() == NULL || stmt->cond() == NULL || stmt->next() == NULL) { |
| 1116 return NULL; |
| 1117 } |
| 1118 // The initialization statement has to be a simple assignment. |
| 1119 Assignment* init = stmt->init()->StatementAsSimpleAssignment(); |
| 1120 if (init == NULL) return NULL; |
| 1121 |
| 1122 // We only deal with local variables. |
| 1123 Variable* loop_var = init->target()->AsVariableProxy()->AsVariable(); |
| 1124 if (!loop_var->IsStackAllocated()) return NULL; |
| 1125 |
| 1126 // The initial value has to be a smi. |
| 1127 Literal* init_lit = init->value()->AsLiteral(); |
| 1128 if (init_lit == NULL || !init_lit->handle()->IsSmi()) return NULL; |
| 1129 int init_value = Smi::cast(*init_lit->handle())->value(); |
| 1130 |
| 1131 // The condition must be a compare of variable with <, <=, >, or >=. |
| 1132 CompareOperation* cond = stmt->cond()->AsCompareOperation(); |
| 1133 if (cond == NULL) return NULL; |
| 1134 if (cond->op() != Token::LT |
| 1135 && cond->op() != Token::LTE |
| 1136 && cond->op() != Token::GT |
| 1137 && cond->op() != Token::GTE) return NULL; |
| 1138 |
| 1139 // The lhs must be the same variable as in the init expression. |
| 1140 if (cond->left()->AsVariableProxy()->AsVariable() != loop_var) return NULL; |
| 1141 |
| 1142 // The rhs must be a smi. |
| 1143 Literal* term_lit = cond->right()->AsLiteral(); |
| 1144 if (term_lit == NULL || !term_lit->handle()->IsSmi()) return NULL; |
| 1145 int term_value = Smi::cast(*term_lit->handle())->value(); |
| 1146 |
| 1147 // The count operation updates the same variable as in the init expression. |
| 1148 CountOperation* update = stmt->next()->StatementAsCountOperation(); |
| 1149 if (update == NULL) return NULL; |
| 1150 if (update->expression()->AsVariableProxy()->AsVariable() != loop_var) { |
| 1151 return NULL; |
| 1152 } |
| 1153 |
| 1154 // The direction of the count operation must agree with the start and the end |
| 1155 // value. We currently do not allow the initial value to be the same as the |
| 1156 // terminal value. This _would_ be ok as long as the loop body never executes |
| 1157 // or executes exactly one time. |
| 1158 if (init_value == term_value) return NULL; |
| 1159 if (init_value < term_value && update->op() != Token::INC) return NULL; |
| 1160 if (init_value > term_value && update->op() != Token::DEC) return NULL; |
| 1161 |
| 1162 // Found a smi loop variable. |
| 1163 return loop_var; |
| 1164 } |
| 1165 |
| 1166 int AssignedVariablesAnalyzer::BitIndex(Variable* var) { |
| 1167 ASSERT(var != NULL); |
| 1168 ASSERT(var->IsStackAllocated()); |
| 1169 Slot* slot = var->slot(); |
| 1170 if (slot->type() == Slot::PARAMETER) { |
| 1171 return slot->index(); |
| 1172 } else { |
| 1173 return fun_->scope()->num_parameters() + slot->index(); |
| 1174 } |
| 1175 } |
| 1176 |
| 1177 |
| 1178 void AssignedVariablesAnalyzer::RecordAssignedVar(Variable* var) { |
| 1179 ASSERT(var != NULL); |
| 1180 if (var->IsStackAllocated()) { |
| 1181 av_.Add(BitIndex(var)); |
| 1182 } |
| 1183 } |
| 1184 |
| 1185 |
| 1186 void AssignedVariablesAnalyzer::MarkIfTrivial(Expression* expr) { |
| 1187 Variable* var = expr->AsVariableProxy()->AsVariable(); |
| 1188 if (var != NULL && |
| 1189 var->IsStackAllocated() && |
| 1190 (var->is_this() || !av_.Contains(BitIndex(var)))) { |
| 1191 expr->AsVariableProxy()->set_is_trivial(true); |
| 1192 } |
| 1193 } |
| 1194 |
| 1195 |
| 1196 void AssignedVariablesAnalyzer::ProcessExpression(Expression* expr) { |
| 1197 BitVector saved_av(av_); |
| 1198 av_.Clear(); |
| 1199 Visit(expr); |
| 1200 av_.Union(saved_av); |
| 1201 } |
| 1202 |
| 1203 void AssignedVariablesAnalyzer::VisitBlock(Block* stmt) { |
| 1204 VisitStatements(stmt->statements()); |
| 1205 } |
| 1206 |
| 1207 |
| 1208 void AssignedVariablesAnalyzer::VisitExpressionStatement( |
| 1209 ExpressionStatement* stmt) { |
| 1210 ProcessExpression(stmt->expression()); |
| 1211 } |
| 1212 |
| 1213 |
| 1214 void AssignedVariablesAnalyzer::VisitEmptyStatement(EmptyStatement* stmt) { |
| 1215 // Do nothing. |
| 1216 } |
| 1217 |
| 1218 |
| 1219 void AssignedVariablesAnalyzer::VisitIfStatement(IfStatement* stmt) { |
| 1220 ProcessExpression(stmt->condition()); |
| 1221 Visit(stmt->then_statement()); |
| 1222 Visit(stmt->else_statement()); |
| 1223 } |
| 1224 |
| 1225 |
| 1226 void AssignedVariablesAnalyzer::VisitContinueStatement( |
| 1227 ContinueStatement* stmt) { |
| 1228 // Nothing to do. |
| 1229 } |
| 1230 |
| 1231 |
| 1232 void AssignedVariablesAnalyzer::VisitBreakStatement(BreakStatement* stmt) { |
| 1233 // Nothing to do. |
| 1234 } |
| 1235 |
| 1236 |
| 1237 void AssignedVariablesAnalyzer::VisitReturnStatement(ReturnStatement* stmt) { |
| 1238 ProcessExpression(stmt->expression()); |
| 1239 } |
| 1240 |
| 1241 |
| 1242 void AssignedVariablesAnalyzer::VisitWithEnterStatement( |
| 1243 WithEnterStatement* stmt) { |
| 1244 ProcessExpression(stmt->expression()); |
| 1245 } |
| 1246 |
| 1247 |
| 1248 void AssignedVariablesAnalyzer::VisitWithExitStatement( |
| 1249 WithExitStatement* stmt) { |
| 1250 // Nothing to do. |
| 1251 } |
| 1252 |
| 1253 |
| 1254 void AssignedVariablesAnalyzer::VisitSwitchStatement(SwitchStatement* stmt) { |
| 1255 BitVector result(av_); |
| 1256 av_.Clear(); |
| 1257 Visit(stmt->tag()); |
| 1258 result.Union(av_); |
| 1259 for (int i = 0; i < stmt->cases()->length(); i++) { |
| 1260 CaseClause* clause = stmt->cases()->at(i); |
| 1261 if (!clause->is_default()) { |
| 1262 av_.Clear(); |
| 1263 Visit(clause->label()); |
| 1264 result.Union(av_); |
| 1265 } |
| 1266 VisitStatements(clause->statements()); |
| 1267 } |
| 1268 av_.Union(result); |
| 1269 } |
| 1270 |
| 1271 |
| 1272 void AssignedVariablesAnalyzer::VisitDoWhileStatement(DoWhileStatement* stmt) { |
| 1273 ProcessExpression(stmt->cond()); |
| 1274 Visit(stmt->body()); |
| 1275 } |
| 1276 |
| 1277 |
| 1278 void AssignedVariablesAnalyzer::VisitWhileStatement(WhileStatement* stmt) { |
| 1279 ProcessExpression(stmt->cond()); |
| 1280 Visit(stmt->body()); |
| 1281 } |
| 1282 |
| 1283 |
| 1284 void AssignedVariablesAnalyzer::VisitForStatement(ForStatement* stmt) { |
| 1285 if (stmt->init() != NULL) Visit(stmt->init()); |
| 1286 |
| 1287 if (stmt->cond() != NULL) ProcessExpression(stmt->cond()); |
| 1288 |
| 1289 if (stmt->next() != NULL) Visit(stmt->next()); |
| 1290 |
| 1291 // Process loop body. After visiting the loop body av_ contains |
| 1292 // the assigned variables of the loop body. |
| 1293 BitVector saved_av(av_); |
| 1294 av_.Clear(); |
| 1295 Visit(stmt->body()); |
| 1296 |
| 1297 Variable* var = FindSmiLoopVariable(stmt); |
| 1298 if (var != NULL && !av_.Contains(BitIndex(var))) { |
| 1299 stmt->set_loop_variable(var); |
| 1300 } |
| 1301 |
| 1302 av_.Union(saved_av); |
| 1303 } |
| 1304 |
| 1305 |
| 1306 void AssignedVariablesAnalyzer::VisitForInStatement(ForInStatement* stmt) { |
| 1307 ProcessExpression(stmt->each()); |
| 1308 ProcessExpression(stmt->enumerable()); |
| 1309 Visit(stmt->body()); |
| 1310 } |
| 1311 |
| 1312 |
| 1313 void AssignedVariablesAnalyzer::VisitTryCatchStatement( |
| 1314 TryCatchStatement* stmt) { |
| 1315 Visit(stmt->try_block()); |
| 1316 Visit(stmt->catch_block()); |
| 1317 } |
| 1318 |
| 1319 |
| 1320 void AssignedVariablesAnalyzer::VisitTryFinallyStatement( |
| 1321 TryFinallyStatement* stmt) { |
| 1322 Visit(stmt->try_block()); |
| 1323 Visit(stmt->finally_block()); |
| 1324 } |
| 1325 |
| 1326 |
| 1327 void AssignedVariablesAnalyzer::VisitDebuggerStatement( |
| 1328 DebuggerStatement* stmt) { |
| 1329 // Nothing to do. |
| 1330 } |
| 1331 |
| 1332 |
| 1333 void AssignedVariablesAnalyzer::VisitFunctionLiteral(FunctionLiteral* expr) { |
| 1334 // Nothing to do. |
| 1335 ASSERT(av_.IsEmpty()); |
| 1336 } |
| 1337 |
| 1338 |
| 1339 void AssignedVariablesAnalyzer::VisitFunctionBoilerplateLiteral( |
| 1340 FunctionBoilerplateLiteral* expr) { |
| 1341 // Nothing to do. |
| 1342 ASSERT(av_.IsEmpty()); |
| 1343 } |
| 1344 |
| 1345 |
| 1346 void AssignedVariablesAnalyzer::VisitConditional(Conditional* expr) { |
| 1347 ASSERT(av_.IsEmpty()); |
| 1348 |
| 1349 Visit(expr->condition()); |
| 1350 |
| 1351 BitVector result(av_); |
| 1352 av_.Clear(); |
| 1353 Visit(expr->then_expression()); |
| 1354 result.Union(av_); |
| 1355 |
| 1356 av_.Clear(); |
| 1357 Visit(expr->else_expression()); |
| 1358 av_.Union(result); |
| 1359 } |
| 1360 |
| 1361 |
| 1362 void AssignedVariablesAnalyzer::VisitSlot(Slot* expr) { |
| 1363 UNREACHABLE(); |
| 1364 } |
| 1365 |
| 1366 |
| 1367 void AssignedVariablesAnalyzer::VisitVariableProxy(VariableProxy* expr) { |
| 1368 // Nothing to do. |
| 1369 ASSERT(av_.IsEmpty()); |
| 1370 } |
| 1371 |
| 1372 |
| 1373 void AssignedVariablesAnalyzer::VisitLiteral(Literal* expr) { |
| 1374 // Nothing to do. |
| 1375 ASSERT(av_.IsEmpty()); |
| 1376 } |
| 1377 |
| 1378 |
| 1379 void AssignedVariablesAnalyzer::VisitRegExpLiteral(RegExpLiteral* expr) { |
| 1380 // Nothing to do. |
| 1381 ASSERT(av_.IsEmpty()); |
| 1382 } |
| 1383 |
| 1384 |
| 1385 void AssignedVariablesAnalyzer::VisitObjectLiteral(ObjectLiteral* expr) { |
| 1386 ASSERT(av_.IsEmpty()); |
| 1387 BitVector result(av_.length()); |
| 1388 for (int i = 0; i < expr->properties()->length(); i++) { |
| 1389 Visit(expr->properties()->at(i)->value()); |
| 1390 result.Union(av_); |
| 1391 av_.Clear(); |
| 1392 } |
| 1393 av_.CopyFrom(result); |
| 1394 } |
| 1395 |
| 1396 |
| 1397 void AssignedVariablesAnalyzer::VisitArrayLiteral(ArrayLiteral* expr) { |
| 1398 ASSERT(av_.IsEmpty()); |
| 1399 BitVector result(av_.length()); |
| 1400 for (int i = 0; i < expr->values()->length(); i++) { |
| 1401 Visit(expr->values()->at(i)); |
| 1402 result.Union(av_); |
| 1403 av_.Clear(); |
| 1404 } |
| 1405 av_.CopyFrom(result); |
| 1406 } |
| 1407 |
| 1408 |
| 1409 void AssignedVariablesAnalyzer::VisitCatchExtensionObject( |
| 1410 CatchExtensionObject* expr) { |
| 1411 ASSERT(av_.IsEmpty()); |
| 1412 Visit(expr->key()); |
| 1413 ProcessExpression(expr->value()); |
| 1414 } |
| 1415 |
| 1416 |
| 1417 void AssignedVariablesAnalyzer::VisitAssignment(Assignment* expr) { |
| 1418 ASSERT(av_.IsEmpty()); |
| 1419 |
| 1420 Visit(expr->target()); |
| 1421 |
| 1422 ProcessExpression(expr->value()); |
| 1423 |
| 1424 Variable* var = expr->target()->AsVariableProxy()->AsVariable(); |
| 1425 if (var != NULL) RecordAssignedVar(var); |
| 1426 |
| 1427 // If we have a variable as a receiver in a property store, check if |
| 1428 // we can mark it as trivial. |
| 1429 if (expr->target()->AsProperty() != NULL) { |
| 1430 MarkIfTrivial(expr->target()->AsProperty()->obj()); |
| 1431 } |
| 1432 } |
| 1433 |
| 1434 |
| 1435 void AssignedVariablesAnalyzer::VisitThrow(Throw* expr) { |
| 1436 ASSERT(av_.IsEmpty()); |
| 1437 Visit(expr->exception()); |
| 1438 } |
| 1439 |
| 1440 |
| 1441 void AssignedVariablesAnalyzer::VisitProperty(Property* expr) { |
| 1442 ASSERT(av_.IsEmpty()); |
| 1443 Visit(expr->obj()); |
| 1444 ProcessExpression(expr->key()); |
| 1445 |
| 1446 // In case we have a variable as a receiver, check if we can mark |
| 1447 // it as trivial. |
| 1448 MarkIfTrivial(expr->obj()); |
| 1449 } |
| 1450 |
| 1451 |
| 1452 void AssignedVariablesAnalyzer::VisitCall(Call* expr) { |
| 1453 ASSERT(av_.IsEmpty()); |
| 1454 Visit(expr->expression()); |
| 1455 BitVector result(av_); |
| 1456 for (int i = 0; i < expr->arguments()->length(); i++) { |
| 1457 av_.Clear(); |
| 1458 Visit(expr->arguments()->at(i)); |
| 1459 result.Union(av_); |
| 1460 } |
| 1461 av_.CopyFrom(result); |
| 1462 } |
| 1463 |
| 1464 |
| 1465 void AssignedVariablesAnalyzer::VisitCallNew(CallNew* expr) { |
| 1466 ASSERT(av_.IsEmpty()); |
| 1467 Visit(expr->expression()); |
| 1468 BitVector result(av_); |
| 1469 for (int i = 0; i < expr->arguments()->length(); i++) { |
| 1470 av_.Clear(); |
| 1471 Visit(expr->arguments()->at(i)); |
| 1472 result.Union(av_); |
| 1473 } |
| 1474 av_.CopyFrom(result); |
| 1475 } |
| 1476 |
| 1477 |
| 1478 void AssignedVariablesAnalyzer::VisitCallRuntime(CallRuntime* expr) { |
| 1479 ASSERT(av_.IsEmpty()); |
| 1480 BitVector result(av_); |
| 1481 for (int i = 0; i < expr->arguments()->length(); i++) { |
| 1482 av_.Clear(); |
| 1483 Visit(expr->arguments()->at(i)); |
| 1484 result.Union(av_); |
| 1485 } |
| 1486 av_.CopyFrom(result); |
| 1487 } |
| 1488 |
| 1489 |
| 1490 void AssignedVariablesAnalyzer::VisitUnaryOperation(UnaryOperation* expr) { |
| 1491 ASSERT(av_.IsEmpty()); |
| 1492 Visit(expr->expression()); |
| 1493 } |
| 1494 |
| 1495 |
| 1496 void AssignedVariablesAnalyzer::VisitCountOperation(CountOperation* expr) { |
| 1497 ASSERT(av_.IsEmpty()); |
| 1498 |
| 1499 Visit(expr->expression()); |
| 1500 |
| 1501 Variable* var = expr->expression()->AsVariableProxy()->AsVariable(); |
| 1502 if (var != NULL) RecordAssignedVar(var); |
| 1503 } |
| 1504 |
| 1505 |
| 1506 void AssignedVariablesAnalyzer::VisitBinaryOperation(BinaryOperation* expr) { |
| 1507 ASSERT(av_.IsEmpty()); |
| 1508 Visit(expr->left()); |
| 1509 |
| 1510 ProcessExpression(expr->right()); |
| 1511 |
| 1512 // In case we have a variable on the left side, check if we can mark |
| 1513 // it as trivial. |
| 1514 MarkIfTrivial(expr->left()); |
| 1515 } |
| 1516 |
| 1517 |
| 1518 void AssignedVariablesAnalyzer::VisitCompareOperation(CompareOperation* expr) { |
| 1519 ASSERT(av_.IsEmpty()); |
| 1520 Visit(expr->left()); |
| 1521 |
| 1522 ProcessExpression(expr->right()); |
| 1523 |
| 1524 // In case we have a variable on the left side, check if we can mark |
| 1525 // it as trivial. |
| 1526 MarkIfTrivial(expr->left()); |
| 1527 } |
| 1528 |
| 1529 |
| 1530 void AssignedVariablesAnalyzer::VisitThisFunction(ThisFunction* expr) { |
| 1531 // Nothing to do. |
| 1532 ASSERT(av_.IsEmpty()); |
| 1533 } |
| 1534 |
| 1535 |
| 1536 void AssignedVariablesAnalyzer::VisitDeclaration(Declaration* decl) { |
| 1537 UNREACHABLE(); |
| 1538 } |
| 1539 |
| 1540 |
1101 #ifdef DEBUG | 1541 #ifdef DEBUG |
1102 | 1542 |
1103 // Print a textual representation of an instruction in a flow graph. Using | 1543 // Print a textual representation of an instruction in a flow graph. Using |
1104 // the AstVisitor is overkill because there is no recursion here. It is | 1544 // the AstVisitor is overkill because there is no recursion here. It is |
1105 // only used for printing in debug mode. | 1545 // only used for printing in debug mode. |
1106 class TextInstructionPrinter: public AstVisitor { | 1546 class TextInstructionPrinter: public AstVisitor { |
1107 public: | 1547 public: |
1108 TextInstructionPrinter() {} | 1548 TextInstructionPrinter() {} |
1109 | 1549 |
1110 private: | 1550 private: |
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1458 for (int i = postorder->length() - 1; i >= 0; i--) { | 1898 for (int i = postorder->length() - 1; i >= 0; i--) { |
1459 postorder->at(i)->PrintText(); | 1899 postorder->at(i)->PrintText(); |
1460 } | 1900 } |
1461 } | 1901 } |
1462 | 1902 |
1463 | 1903 |
1464 #endif // defined(DEBUG) | 1904 #endif // defined(DEBUG) |
1465 | 1905 |
1466 | 1906 |
1467 } } // namespace v8::internal | 1907 } } // namespace v8::internal |
OLD | NEW |