OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // TODO(jochen): Remove this after the setting is turned on globally. | 5 // TODO(jochen): Remove this after the setting is turned on globally. |
6 #define V8_IMMINENT_DEPRECATION_WARNINGS | 6 #define V8_IMMINENT_DEPRECATION_WARNINGS |
7 | 7 |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "src/compiler/pipeline.h" | 10 #include "src/compiler/pipeline.h" |
(...skipping 1168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 SNPrintF(script, "%s", snippets[i].code_snippet); | 1179 SNPrintF(script, "%s", snippets[i].code_snippet); |
1180 | 1180 |
1181 BytecodeGraphTester tester(isolate, zone, script.start(), "*"); | 1181 BytecodeGraphTester tester(isolate, zone, script.start(), "*"); |
1182 auto callable = tester.GetCallable<Handle<Object>>("f"); | 1182 auto callable = tester.GetCallable<Handle<Object>>("f"); |
1183 Handle<Object> return_value = | 1183 Handle<Object> return_value = |
1184 callable(snippets[i].parameter(0)).ToHandleChecked(); | 1184 callable(snippets[i].parameter(0)).ToHandleChecked(); |
1185 CHECK(return_value->SameValue(*snippets[i].return_value())); | 1185 CHECK(return_value->SameValue(*snippets[i].return_value())); |
1186 } | 1186 } |
1187 } | 1187 } |
1188 | 1188 |
| 1189 |
| 1190 TEST(BytecodeGraphBuilderIf) { |
| 1191 HandleAndZoneScope scope; |
| 1192 Isolate* isolate = scope.main_isolate(); |
| 1193 Zone* zone = scope.main_zone(); |
| 1194 Factory* factory = isolate->factory(); |
| 1195 |
| 1196 ExpectedSnippet<1> snippets[] = { |
| 1197 {"if (p1 > 1) return 1;\n" |
| 1198 "return -1;", |
| 1199 {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}}, |
| 1200 {"if (p1 > 1) return 1;\n" |
| 1201 "return -1;", |
| 1202 {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(1)}}, |
| 1203 {"if (p1 > 1) { return 1; } else { return -1; }", |
| 1204 {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}}, |
| 1205 {"if (p1 > 1) { return 1; } else { return -1; }", |
| 1206 {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(1)}}, |
| 1207 {"if (p1 > 50) {\n" |
| 1208 " return 1;\n" |
| 1209 "} else if (p1 < 10) {\n" |
| 1210 " return 10;\n" |
| 1211 "} else {\n" |
| 1212 " return -10;\n" |
| 1213 "}", |
| 1214 {factory->NewNumberFromInt(1), factory->NewNumberFromInt(51)}}, |
| 1215 {"if (p1 > 50) {\n" |
| 1216 " return 1;\n" |
| 1217 "} else if (p1 < 10) {\n" |
| 1218 " return 10;\n" |
| 1219 "} else {\n" |
| 1220 " return 100;\n" |
| 1221 "}", |
| 1222 {factory->NewNumberFromInt(10), factory->NewNumberFromInt(9)}}, |
| 1223 {"if (p1 > 50) {\n" |
| 1224 " return 1;\n" |
| 1225 "} else if (p1 < 10) {\n" |
| 1226 " return 10;\n" |
| 1227 "} else {\n" |
| 1228 " return 100;\n" |
| 1229 "}", |
| 1230 {factory->NewNumberFromInt(100), factory->NewNumberFromInt(10)}}, |
| 1231 {"if (p1 >= 0) {\n" |
| 1232 " if (p1 > 10) { return 2; } else { return 1; }\n" |
| 1233 "} else {\n" |
| 1234 " if (p1 < -10) { return -2; } else { return -1; }\n" |
| 1235 "}", |
| 1236 {factory->NewNumberFromInt(2), factory->NewNumberFromInt(100)}}, |
| 1237 {"if (p1 >= 0) {\n" |
| 1238 " if (p1 > 10) { return 2; } else { return 1; }\n" |
| 1239 "} else {\n" |
| 1240 " if (p1 < -10) { return -2; } else { return -1; }\n" |
| 1241 "}", |
| 1242 {factory->NewNumberFromInt(1), factory->NewNumberFromInt(10)}}, |
| 1243 {"if (p1 >= 0) {\n" |
| 1244 " if (p1 > 10) { return 2; } else { return 1; }\n" |
| 1245 "} else {\n" |
| 1246 " if (p1 < -10) { return -2; } else { return -1; }\n" |
| 1247 "}", |
| 1248 {factory->NewNumberFromInt(-2), factory->NewNumberFromInt(-11)}}, |
| 1249 {"if (p1 >= 0) {\n" |
| 1250 " if (p1 > 10) { return 2; } else { return 1; }\n" |
| 1251 "} else {\n" |
| 1252 " if (p1 < -10) { return -2; } else { return -1; }\n" |
| 1253 "}", |
| 1254 {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(-10)}}, |
| 1255 }; |
| 1256 |
| 1257 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
| 1258 for (size_t i = 0; i < num_snippets; i++) { |
| 1259 ScopedVector<char> script(2048); |
| 1260 SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName, |
| 1261 snippets[i].code_snippet, kFunctionName); |
| 1262 |
| 1263 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1264 auto callable = tester.GetCallable<Handle<Object>>(); |
| 1265 Handle<Object> return_value = |
| 1266 callable(snippets[i].parameter(0)).ToHandleChecked(); |
| 1267 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1268 } |
| 1269 } |
| 1270 |
| 1271 |
| 1272 TEST(BytecodeGraphBuilderConditionalOperator) { |
| 1273 HandleAndZoneScope scope; |
| 1274 Isolate* isolate = scope.main_isolate(); |
| 1275 Zone* zone = scope.main_zone(); |
| 1276 Factory* factory = isolate->factory(); |
| 1277 |
| 1278 ExpectedSnippet<1> snippets[] = { |
| 1279 {"return (p1 > 1) ? 1 : -1;", |
| 1280 {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}}, |
| 1281 {"return (p1 > 1) ? 1 : -1;", |
| 1282 {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(0)}}, |
| 1283 {"return (p1 > 50) ? 1 : ((p1 < 10) ? 10 : -10);", |
| 1284 {factory->NewNumberFromInt(10), factory->NewNumberFromInt(2)}}, |
| 1285 {"return (p1 > 50) ? 1 : ((p1 < 10) ? 10 : -10);", |
| 1286 {factory->NewNumberFromInt(-10), factory->NewNumberFromInt(20)}}, |
| 1287 }; |
| 1288 |
| 1289 size_t num_snippets = sizeof(snippets) / sizeof(snippets[0]); |
| 1290 for (size_t i = 0; i < num_snippets; i++) { |
| 1291 ScopedVector<char> script(2048); |
| 1292 SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName, |
| 1293 snippets[i].code_snippet, kFunctionName); |
| 1294 |
| 1295 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1296 auto callable = tester.GetCallable<Handle<Object>>(); |
| 1297 Handle<Object> return_value = |
| 1298 callable(snippets[i].parameter(0)).ToHandleChecked(); |
| 1299 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1300 } |
| 1301 } |
| 1302 |
| 1303 |
| 1304 TEST(BytecodeGraphBuilderSwitch) { |
| 1305 HandleAndZoneScope scope; |
| 1306 Isolate* isolate = scope.main_isolate(); |
| 1307 Zone* zone = scope.main_zone(); |
| 1308 Factory* factory = isolate->factory(); |
| 1309 |
| 1310 const char* switch_code = |
| 1311 "switch (p1) {\n" |
| 1312 " case 1: return 0;\n" |
| 1313 " case 2: return 1;\n" |
| 1314 " case 3:\n" |
| 1315 " case 4: return 2;\n" |
| 1316 " case 9: break;\n" |
| 1317 " default: return 3;\n" |
| 1318 "}\n" |
| 1319 "return 9;"; |
| 1320 |
| 1321 ExpectedSnippet<1> snippets[] = { |
| 1322 {switch_code, |
| 1323 {factory->NewNumberFromInt(0), factory->NewNumberFromInt(1)}}, |
| 1324 {switch_code, |
| 1325 {factory->NewNumberFromInt(1), factory->NewNumberFromInt(2)}}, |
| 1326 {switch_code, |
| 1327 {factory->NewNumberFromInt(2), factory->NewNumberFromInt(3)}}, |
| 1328 {switch_code, |
| 1329 {factory->NewNumberFromInt(2), factory->NewNumberFromInt(4)}}, |
| 1330 {switch_code, |
| 1331 {factory->NewNumberFromInt(9), factory->NewNumberFromInt(9)}}, |
| 1332 {switch_code, |
| 1333 {factory->NewNumberFromInt(3), factory->NewNumberFromInt(5)}}, |
| 1334 {switch_code, |
| 1335 {factory->NewNumberFromInt(3), factory->NewNumberFromInt(6)}}, |
| 1336 }; |
| 1337 |
| 1338 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 1339 ScopedVector<char> script(2048); |
| 1340 SNPrintF(script, "function %s(p1) { %s };\n%s(0);", kFunctionName, |
| 1341 snippets[i].code_snippet, kFunctionName); |
| 1342 |
| 1343 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1344 auto callable = tester.GetCallable<Handle<Object>>(); |
| 1345 Handle<Object> return_value = |
| 1346 callable(snippets[i].parameter(0)).ToHandleChecked(); |
| 1347 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1348 } |
| 1349 } |
| 1350 |
| 1351 |
| 1352 TEST(BytecodeGraphBuilderNestedSwitch) { |
| 1353 HandleAndZoneScope scope; |
| 1354 Isolate* isolate = scope.main_isolate(); |
| 1355 Zone* zone = scope.main_zone(); |
| 1356 Factory* factory = isolate->factory(); |
| 1357 |
| 1358 const char* switch_code = |
| 1359 "switch (p1) {\n" |
| 1360 " case 0: {" |
| 1361 " switch (p2) { case 0: return 0; case 1: return 1; case 2: break; }\n" |
| 1362 " return -1;" |
| 1363 " }\n" |
| 1364 " case 1: {" |
| 1365 " switch (p2) { case 0: return 2; case 1: return 3; }\n" |
| 1366 " }\n" |
| 1367 " case 2: break;" |
| 1368 " }\n" |
| 1369 "return -2;"; |
| 1370 |
| 1371 ExpectedSnippet<2> snippets[] = { |
| 1372 {switch_code, |
| 1373 {factory->NewNumberFromInt(0), factory->NewNumberFromInt(0), |
| 1374 factory->NewNumberFromInt(0)}}, |
| 1375 {switch_code, |
| 1376 {factory->NewNumberFromInt(1), factory->NewNumberFromInt(0), |
| 1377 factory->NewNumberFromInt(1)}}, |
| 1378 {switch_code, |
| 1379 {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(0), |
| 1380 factory->NewNumberFromInt(2)}}, |
| 1381 {switch_code, |
| 1382 {factory->NewNumberFromInt(-1), factory->NewNumberFromInt(0), |
| 1383 factory->NewNumberFromInt(3)}}, |
| 1384 {switch_code, |
| 1385 {factory->NewNumberFromInt(2), factory->NewNumberFromInt(1), |
| 1386 factory->NewNumberFromInt(0)}}, |
| 1387 {switch_code, |
| 1388 {factory->NewNumberFromInt(3), factory->NewNumberFromInt(1), |
| 1389 factory->NewNumberFromInt(1)}}, |
| 1390 {switch_code, |
| 1391 {factory->NewNumberFromInt(-2), factory->NewNumberFromInt(1), |
| 1392 factory->NewNumberFromInt(2)}}, |
| 1393 {switch_code, |
| 1394 {factory->NewNumberFromInt(-2), factory->NewNumberFromInt(2), |
| 1395 factory->NewNumberFromInt(0)}}, |
| 1396 }; |
| 1397 |
| 1398 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 1399 ScopedVector<char> script(2048); |
| 1400 SNPrintF(script, "function %s(p1, p2) { %s };\n%s(0, 0);", kFunctionName, |
| 1401 snippets[i].code_snippet, kFunctionName); |
| 1402 |
| 1403 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1404 auto callable = tester.GetCallable<Handle<Object>, Handle<Object>>(); |
| 1405 Handle<Object> return_value = |
| 1406 callable(snippets[i].parameter(0), snippets[i].parameter(1)) |
| 1407 .ToHandleChecked(); |
| 1408 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1409 } |
| 1410 } |
| 1411 |
| 1412 |
| 1413 TEST(BytecodeGraphBuilderWhile) { |
| 1414 HandleAndZoneScope scope; |
| 1415 Isolate* isolate = scope.main_isolate(); |
| 1416 Zone* zone = scope.main_zone(); |
| 1417 Factory* factory = isolate->factory(); |
| 1418 |
| 1419 ExpectedSnippet<0> snippets[] = { |
| 1420 {"var x = 1; while (x < 1) { x *= 100; } return x;", |
| 1421 {factory->NewNumberFromInt(1)}}, |
| 1422 {"var x = 1, y = 0; while (x < 7) { y += x * x; x += 1; } return y;", |
| 1423 {factory->NewNumberFromInt(91)}}, |
| 1424 {"var x = 1; while (true) { x += 1; if (x == 10) break; } return x;", |
| 1425 {factory->NewNumberFromInt(10)}}, |
| 1426 {"var x = 1; while (false) { x += 1; } return x;", |
| 1427 {factory->NewNumberFromInt(1)}}, |
| 1428 {"var x = 0;\n" |
| 1429 "while (true) {\n" |
| 1430 " while (x < 10) {\n" |
| 1431 " x = x * x + 1;\n" |
| 1432 " }" |
| 1433 " x += 1;\n" |
| 1434 " break;\n" |
| 1435 "}\n" |
| 1436 "return x;", |
| 1437 {factory->NewNumberFromInt(27)}}, |
| 1438 {"var x = 1, y = 0;\n" |
| 1439 "while (x < 7) {\n" |
| 1440 " x += 1;\n" |
| 1441 " if (x == 2) continue;\n" |
| 1442 " if (x == 3) continue;\n" |
| 1443 " y += x * x;\n" |
| 1444 " if (x == 4) break;\n" |
| 1445 "}\n" |
| 1446 "return y;", |
| 1447 {factory->NewNumberFromInt(16)}}}; |
| 1448 |
| 1449 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 1450 ScopedVector<char> script(1024); |
| 1451 SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, |
| 1452 snippets[i].code_snippet, kFunctionName); |
| 1453 |
| 1454 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1455 auto callable = tester.GetCallable<>(); |
| 1456 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1457 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1458 } |
| 1459 } |
| 1460 |
| 1461 |
| 1462 TEST(BytecodeGraphBuilderDo) { |
| 1463 HandleAndZoneScope scope; |
| 1464 Isolate* isolate = scope.main_isolate(); |
| 1465 Zone* zone = scope.main_zone(); |
| 1466 Factory* factory = isolate->factory(); |
| 1467 |
| 1468 ExpectedSnippet<0> snippets[] = { |
| 1469 {"var x = 1; do { x *= 100; } while (x < 100); return x;", |
| 1470 {factory->NewNumberFromInt(100)}}, |
| 1471 {"var x = 1; do { x = x * x + 1; } while (x < 7) return x;", |
| 1472 {factory->NewNumberFromInt(26)}}, |
| 1473 {"var x = 1; do { x += 1; } while (false); return x;", |
| 1474 {factory->NewNumberFromInt(2)}}, |
| 1475 {"var x = 1, y = 0;\n" |
| 1476 "do {\n" |
| 1477 " x += 1;\n" |
| 1478 " if (x == 2) continue;\n" |
| 1479 " if (x == 3) continue;\n" |
| 1480 " y += x * x;\n" |
| 1481 " if (x == 4) break;\n" |
| 1482 "} while (x < 7);\n" |
| 1483 "return y;", |
| 1484 {factory->NewNumberFromInt(16)}}}; |
| 1485 |
| 1486 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 1487 ScopedVector<char> script(1024); |
| 1488 SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, |
| 1489 snippets[i].code_snippet, kFunctionName); |
| 1490 |
| 1491 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1492 auto callable = tester.GetCallable<>(); |
| 1493 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1494 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1495 } |
| 1496 } |
| 1497 |
| 1498 |
| 1499 TEST(BytecodeGraphBuilderFor) { |
| 1500 HandleAndZoneScope scope; |
| 1501 Isolate* isolate = scope.main_isolate(); |
| 1502 Zone* zone = scope.main_zone(); |
| 1503 Factory* factory = isolate->factory(); |
| 1504 |
| 1505 ExpectedSnippet<0> snippets[] = { |
| 1506 {"for (var x = 0;; x = 2 * x + 1) { if (x > 10) return x; }", |
| 1507 {factory->NewNumberFromInt(15)}}, |
| 1508 {"for (var x = 0; true; x = 2 * x + 1) { if (x > 100) return x; }", |
| 1509 {factory->NewNumberFromInt(127)}}, |
| 1510 {"for (var x = 0; false; x = 2 * x + 1) { if (x > 100) return x; } " |
| 1511 "return 0;", |
| 1512 {factory->NewNumberFromInt(0)}}, |
| 1513 {"for (var x = 0; x < 200; x = 2 * x + 1) { x = x; } return x;", |
| 1514 {factory->NewNumberFromInt(255)}}, |
| 1515 {"for (var x = 0; x < 200; x = 2 * x + 1) {} return x;", |
| 1516 {factory->NewNumberFromInt(255)}}, |
| 1517 {"var sum = 0;\n" |
| 1518 "for (var x = 0; x < 200; x += 1) {\n" |
| 1519 " if (x % 2) continue;\n" |
| 1520 " if (sum > 10) break;\n" |
| 1521 " sum += x;\n" |
| 1522 "}\n" |
| 1523 "return sum;", |
| 1524 {factory->NewNumberFromInt(12)}}, |
| 1525 {"var sum = 0;\n" |
| 1526 "for (var x = 1; x < 10; x += 2) {\n" |
| 1527 " for (var y = x; y < x + 2; y++) {\n" |
| 1528 " sum += y * y;\n" |
| 1529 " }\n" |
| 1530 "}\n" |
| 1531 "return sum;", |
| 1532 {factory->NewNumberFromInt(385)}}}; |
| 1533 |
| 1534 for (size_t i = 0; i < arraysize(snippets); i++) { |
| 1535 ScopedVector<char> script(1024); |
| 1536 SNPrintF(script, "function %s() { %s }\n%s();", kFunctionName, |
| 1537 snippets[i].code_snippet, kFunctionName); |
| 1538 |
| 1539 BytecodeGraphTester tester(isolate, zone, script.start()); |
| 1540 auto callable = tester.GetCallable<>(); |
| 1541 Handle<Object> return_value = callable().ToHandleChecked(); |
| 1542 CHECK(return_value->SameValue(*snippets[i].return_value())); |
| 1543 } |
| 1544 } |
| 1545 |
1189 } // namespace compiler | 1546 } // namespace compiler |
1190 } // namespace internal | 1547 } // namespace internal |
1191 } // namespace v8 | 1548 } // namespace v8 |
OLD | NEW |