OLD | NEW |
---|---|
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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 #include "src/builtins/builtins.h" | 5 #include "src/builtins/builtins.h" |
6 #include "src/builtins/builtins-utils.h" | 6 #include "src/builtins/builtins-utils.h" |
7 | 7 |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/elements.h" | 9 #include "src/elements.h" |
10 | 10 |
(...skipping 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1262 void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) { | 1262 void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) { |
1263 typedef compiler::Node Node; | 1263 typedef compiler::Node Node; |
1264 typedef CodeStubAssembler::Label Label; | 1264 typedef CodeStubAssembler::Label Label; |
1265 typedef CodeStubAssembler::Variable Variable; | 1265 typedef CodeStubAssembler::Variable Variable; |
1266 | 1266 |
1267 Node* array = assembler->Parameter(0); | 1267 Node* array = assembler->Parameter(0); |
1268 Node* search_element = assembler->Parameter(1); | 1268 Node* search_element = assembler->Parameter(1); |
1269 Node* start_from = assembler->Parameter(2); | 1269 Node* start_from = assembler->Parameter(2); |
1270 Node* context = assembler->Parameter(3 + 2); | 1270 Node* context = assembler->Parameter(3 + 2); |
1271 | 1271 |
1272 Node* int32_zero = assembler->Int32Constant(0); | 1272 Node* intptr_zero = assembler->IntPtrConstant(0); |
1273 Node* int32_one = assembler->Int32Constant(1); | 1273 Node* intptr_one = assembler->IntPtrConstant(1); |
1274 | 1274 |
1275 Node* the_hole = assembler->TheHoleConstant(); | 1275 Node* the_hole = assembler->TheHoleConstant(); |
1276 Node* undefined = assembler->UndefinedConstant(); | 1276 Node* undefined = assembler->UndefinedConstant(); |
1277 Node* heap_number_map = assembler->HeapNumberMapConstant(); | 1277 Node* heap_number_map = assembler->HeapNumberMapConstant(); |
1278 | 1278 |
1279 Variable len_var(assembler, MachineRepresentation::kWord32), | 1279 Variable len_var(assembler, MachineType::PointerRepresentation()), |
1280 index_var(assembler, MachineRepresentation::kWord32), | 1280 index_var(assembler, MachineType::PointerRepresentation()), |
1281 start_from_var(assembler, MachineRepresentation::kWord32); | 1281 start_from_var(assembler, MachineType::PointerRepresentation()); |
1282 | 1282 |
1283 Label init_k(assembler), return_true(assembler), return_false(assembler), | 1283 Label init_k(assembler), return_true(assembler), return_false(assembler), |
1284 call_runtime(assembler); | 1284 call_runtime(assembler); |
1285 | 1285 |
1286 Label init_len(assembler); | 1286 Label init_len(assembler); |
1287 | 1287 |
1288 index_var.Bind(int32_zero); | 1288 index_var.Bind(intptr_zero); |
1289 len_var.Bind(int32_zero); | 1289 len_var.Bind(intptr_zero); |
1290 | 1290 |
1291 // Take slow path if not a JSArray, if retrieving elements requires | 1291 // Take slow path if not a JSArray, if retrieving elements requires |
1292 // traversing prototype, or if access checks are required. | 1292 // traversing prototype, or if access checks are required. |
1293 assembler->BranchIfFastJSArray(array, context, &init_len, &call_runtime); | 1293 assembler->BranchIfFastJSArray(array, context, &init_len, &call_runtime); |
1294 | 1294 |
1295 assembler->Bind(&init_len); | 1295 assembler->Bind(&init_len); |
1296 { | 1296 { |
1297 // Handle case where JSArray length is not an Smi in the runtime | 1297 // Handle case where JSArray length is not an Smi in the runtime |
1298 Node* len = assembler->LoadObjectField(array, JSArray::kLengthOffset); | 1298 Node* len = assembler->LoadObjectField(array, JSArray::kLengthOffset); |
1299 assembler->GotoUnless(assembler->WordIsSmi(len), &call_runtime); | 1299 assembler->GotoUnless(assembler->WordIsSmi(len), &call_runtime); |
1300 | 1300 |
1301 len_var.Bind(assembler->SmiToWord(len)); | 1301 len_var.Bind(assembler->SmiToWord(len)); |
1302 assembler->Branch(assembler->Word32Equal(len_var.value(), int32_zero), | 1302 assembler->Branch(assembler->WordEqual(len_var.value(), intptr_zero), |
1303 &return_false, &init_k); | 1303 &return_false, &init_k); |
1304 } | 1304 } |
1305 | 1305 |
1306 assembler->Bind(&init_k); | 1306 assembler->Bind(&init_k); |
1307 { | 1307 { |
1308 Label done(assembler), init_k_smi(assembler), init_k_heap_num(assembler), | 1308 Label done(assembler), init_k_smi(assembler), init_k_heap_num(assembler), |
1309 init_k_zero(assembler), init_k_n(assembler); | 1309 init_k_zero(assembler), init_k_n(assembler); |
1310 Callable call_to_integer = CodeFactory::ToInteger(assembler->isolate()); | 1310 Callable call_to_integer = CodeFactory::ToInteger(assembler->isolate()); |
1311 Node* tagged_n = assembler->CallStub(call_to_integer, context, start_from); | 1311 Node* tagged_n = assembler->CallStub(call_to_integer, context, start_from); |
1312 | 1312 |
1313 assembler->Branch(assembler->WordIsSmi(tagged_n), &init_k_smi, | 1313 assembler->Branch(assembler->WordIsSmi(tagged_n), &init_k_smi, |
1314 &init_k_heap_num); | 1314 &init_k_heap_num); |
1315 | 1315 |
1316 assembler->Bind(&init_k_smi); | 1316 assembler->Bind(&init_k_smi); |
1317 { | 1317 { |
1318 start_from_var.Bind(assembler->SmiToWord32(tagged_n)); | 1318 start_from_var.Bind(assembler->SmiUntag(tagged_n)); |
1319 assembler->Goto(&init_k_n); | 1319 assembler->Goto(&init_k_n); |
1320 } | 1320 } |
1321 | 1321 |
1322 assembler->Bind(&init_k_heap_num); | 1322 assembler->Bind(&init_k_heap_num); |
1323 { | 1323 { |
1324 Label do_return_false(assembler); | 1324 Label do_return_false(assembler); |
1325 Node* fp_len = assembler->ChangeInt32ToFloat64(len_var.value()); | 1325 // This round is lossless for all valid lengths. |
Igor Sheludko
2016/09/08 11:07:51
This is not trivial.
| |
1326 Node* fp_len = assembler->RoundIntPtrToFloat64(len_var.value()); | |
1326 Node* fp_n = assembler->LoadHeapNumberValue(tagged_n); | 1327 Node* fp_n = assembler->LoadHeapNumberValue(tagged_n); |
1327 assembler->GotoIf(assembler->Float64GreaterThanOrEqual(fp_n, fp_len), | 1328 assembler->GotoIf(assembler->Float64GreaterThanOrEqual(fp_n, fp_len), |
1328 &do_return_false); | 1329 &do_return_false); |
1329 start_from_var.Bind(assembler->TruncateFloat64ToWord32(fp_n)); | 1330 start_from_var.Bind(assembler->ChangeInt32ToIntPtr( |
1331 assembler->TruncateFloat64ToWord32(fp_n))); | |
1330 assembler->Goto(&init_k_n); | 1332 assembler->Goto(&init_k_n); |
1331 | 1333 |
1332 assembler->Bind(&do_return_false); | 1334 assembler->Bind(&do_return_false); |
1333 { | 1335 { |
1334 index_var.Bind(int32_zero); | 1336 index_var.Bind(intptr_zero); |
1335 assembler->Goto(&return_false); | 1337 assembler->Goto(&return_false); |
1336 } | 1338 } |
1337 } | 1339 } |
1338 | 1340 |
1339 assembler->Bind(&init_k_n); | 1341 assembler->Bind(&init_k_n); |
1340 { | 1342 { |
1341 Label if_positive(assembler), if_negative(assembler), done(assembler); | 1343 Label if_positive(assembler), if_negative(assembler), done(assembler); |
1342 assembler->Branch( | 1344 assembler->Branch( |
1343 assembler->Int32LessThan(start_from_var.value(), int32_zero), | 1345 assembler->IntPtrLessThan(start_from_var.value(), intptr_zero), |
1344 &if_negative, &if_positive); | 1346 &if_negative, &if_positive); |
1345 | 1347 |
1346 assembler->Bind(&if_positive); | 1348 assembler->Bind(&if_positive); |
1347 { | 1349 { |
1348 index_var.Bind(start_from_var.value()); | 1350 index_var.Bind(start_from_var.value()); |
1349 assembler->Goto(&done); | 1351 assembler->Goto(&done); |
1350 } | 1352 } |
1351 | 1353 |
1352 assembler->Bind(&if_negative); | 1354 assembler->Bind(&if_negative); |
1353 { | 1355 { |
1354 index_var.Bind( | 1356 index_var.Bind( |
1355 assembler->Int32Add(len_var.value(), start_from_var.value())); | 1357 assembler->IntPtrAdd(len_var.value(), start_from_var.value())); |
1356 assembler->Branch( | 1358 assembler->Branch( |
1357 assembler->Int32LessThan(index_var.value(), int32_zero), | 1359 assembler->IntPtrLessThan(index_var.value(), intptr_zero), |
1358 &init_k_zero, &done); | 1360 &init_k_zero, &done); |
1359 } | 1361 } |
1360 | 1362 |
1361 assembler->Bind(&init_k_zero); | 1363 assembler->Bind(&init_k_zero); |
1362 { | 1364 { |
1363 index_var.Bind(int32_zero); | 1365 index_var.Bind(intptr_zero); |
1364 assembler->Goto(&done); | 1366 assembler->Goto(&done); |
1365 } | 1367 } |
1366 | 1368 |
1367 assembler->Bind(&done); | 1369 assembler->Bind(&done); |
1368 } | 1370 } |
1369 } | 1371 } |
1370 | 1372 |
1371 static int32_t kElementsKind[] = { | 1373 static int32_t kElementsKind[] = { |
1372 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS, | 1374 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS, |
1373 FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, | 1375 FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1409 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); | 1411 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); |
1410 assembler->Goto(&heap_num_loop); | 1412 assembler->Goto(&heap_num_loop); |
1411 | 1413 |
1412 assembler->Bind(¬_heap_num); | 1414 assembler->Bind(¬_heap_num); |
1413 Node* search_type = assembler->LoadMapInstanceType(map); | 1415 Node* search_type = assembler->LoadMapInstanceType(map); |
1414 assembler->GotoIf( | 1416 assembler->GotoIf( |
1415 assembler->Int32LessThan( | 1417 assembler->Int32LessThan( |
1416 search_type, assembler->Int32Constant(FIRST_NONSTRING_TYPE)), | 1418 search_type, assembler->Int32Constant(FIRST_NONSTRING_TYPE)), |
1417 &string_loop); | 1419 &string_loop); |
1418 assembler->GotoIf( | 1420 assembler->GotoIf( |
1419 assembler->WordEqual(search_type, | 1421 assembler->Word32Equal(search_type, |
1420 assembler->Int32Constant(SIMD128_VALUE_TYPE)), | 1422 assembler->Int32Constant(SIMD128_VALUE_TYPE)), |
1421 &simd_loop); | 1423 &simd_loop); |
1422 assembler->Goto(&ident_loop); | 1424 assembler->Goto(&ident_loop); |
1423 | 1425 |
1424 assembler->Bind(&ident_loop); | 1426 assembler->Bind(&ident_loop); |
1425 { | 1427 { |
1426 assembler->GotoUnless( | 1428 assembler->GotoUnless( |
1427 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1429 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1428 &return_false); | 1430 &return_false); |
1429 Node* element_k = | 1431 Node* element_k = assembler->LoadFixedArrayElement( |
1430 assembler->LoadFixedArrayElement(elements, index_var.value()); | 1432 elements, index_var.value(), 0, INTPTR_PARAMETERS); |
1431 assembler->GotoIf(assembler->WordEqual(element_k, search_element), | 1433 assembler->GotoIf(assembler->WordEqual(element_k, search_element), |
1432 &return_true); | 1434 &return_true); |
1433 | 1435 |
1434 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1436 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1435 assembler->Goto(&ident_loop); | 1437 assembler->Goto(&ident_loop); |
1436 } | 1438 } |
1437 | 1439 |
1438 assembler->Bind(&undef_loop); | 1440 assembler->Bind(&undef_loop); |
1439 { | 1441 { |
1440 assembler->GotoUnless( | 1442 assembler->GotoUnless( |
1441 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1443 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1442 &return_false); | 1444 &return_false); |
1443 Node* element_k = | 1445 Node* element_k = assembler->LoadFixedArrayElement( |
1444 assembler->LoadFixedArrayElement(elements, index_var.value()); | 1446 elements, index_var.value(), 0, INTPTR_PARAMETERS); |
1445 assembler->GotoIf(assembler->WordEqual(element_k, undefined), | 1447 assembler->GotoIf(assembler->WordEqual(element_k, undefined), |
1446 &return_true); | 1448 &return_true); |
1447 assembler->GotoIf(assembler->WordEqual(element_k, the_hole), | 1449 assembler->GotoIf(assembler->WordEqual(element_k, the_hole), |
1448 &return_true); | 1450 &return_true); |
1449 | 1451 |
1450 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1452 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1451 assembler->Goto(&undef_loop); | 1453 assembler->Goto(&undef_loop); |
1452 } | 1454 } |
1453 | 1455 |
1454 assembler->Bind(&heap_num_loop); | 1456 assembler->Bind(&heap_num_loop); |
1455 { | 1457 { |
1456 Label nan_loop(assembler, &index_var), | 1458 Label nan_loop(assembler, &index_var), |
1457 not_nan_loop(assembler, &index_var); | 1459 not_nan_loop(assembler, &index_var); |
1458 assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop, | 1460 assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop, |
1459 ¬_nan_loop); | 1461 ¬_nan_loop); |
1460 | 1462 |
1461 assembler->Bind(¬_nan_loop); | 1463 assembler->Bind(¬_nan_loop); |
1462 { | 1464 { |
1463 Label continue_loop(assembler), not_smi(assembler); | 1465 Label continue_loop(assembler), not_smi(assembler); |
1464 assembler->GotoUnless( | 1466 assembler->GotoUnless( |
1465 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1467 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1466 &return_false); | 1468 &return_false); |
1467 Node* element_k = | 1469 Node* element_k = assembler->LoadFixedArrayElement( |
1468 assembler->LoadFixedArrayElement(elements, index_var.value()); | 1470 elements, index_var.value(), 0, INTPTR_PARAMETERS); |
1469 assembler->GotoUnless(assembler->WordIsSmi(element_k), ¬_smi); | 1471 assembler->GotoUnless(assembler->WordIsSmi(element_k), ¬_smi); |
1470 assembler->Branch( | 1472 assembler->Branch( |
1471 assembler->Float64Equal(search_num.value(), | 1473 assembler->Float64Equal(search_num.value(), |
1472 assembler->SmiToFloat64(element_k)), | 1474 assembler->SmiToFloat64(element_k)), |
1473 &return_true, &continue_loop); | 1475 &return_true, &continue_loop); |
1474 | 1476 |
1475 assembler->Bind(¬_smi); | 1477 assembler->Bind(¬_smi); |
1476 assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k), | 1478 assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k), |
1477 heap_number_map), | 1479 heap_number_map), |
1478 &continue_loop); | 1480 &continue_loop); |
1479 assembler->BranchIfFloat64Equal( | 1481 assembler->BranchIfFloat64Equal( |
1480 search_num.value(), assembler->LoadHeapNumberValue(element_k), | 1482 search_num.value(), assembler->LoadHeapNumberValue(element_k), |
1481 &return_true, &continue_loop); | 1483 &return_true, &continue_loop); |
1482 | 1484 |
1483 assembler->Bind(&continue_loop); | 1485 assembler->Bind(&continue_loop); |
1484 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1486 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1485 assembler->Goto(¬_nan_loop); | 1487 assembler->Goto(¬_nan_loop); |
1486 } | 1488 } |
1487 | 1489 |
1488 assembler->Bind(&nan_loop); | 1490 assembler->Bind(&nan_loop); |
1489 { | 1491 { |
1490 Label continue_loop(assembler); | 1492 Label continue_loop(assembler); |
1491 assembler->GotoUnless( | 1493 assembler->GotoUnless( |
1492 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1494 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1493 &return_false); | 1495 &return_false); |
1494 Node* element_k = | 1496 Node* element_k = assembler->LoadFixedArrayElement( |
1495 assembler->LoadFixedArrayElement(elements, index_var.value()); | 1497 elements, index_var.value(), 0, INTPTR_PARAMETERS); |
1496 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop); | 1498 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop); |
1497 assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k), | 1499 assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k), |
1498 heap_number_map), | 1500 heap_number_map), |
1499 &continue_loop); | 1501 &continue_loop); |
1500 assembler->BranchIfFloat64IsNaN( | 1502 assembler->BranchIfFloat64IsNaN( |
1501 assembler->LoadHeapNumberValue(element_k), &return_true, | 1503 assembler->LoadHeapNumberValue(element_k), &return_true, |
1502 &continue_loop); | 1504 &continue_loop); |
1503 | 1505 |
1504 assembler->Bind(&continue_loop); | 1506 assembler->Bind(&continue_loop); |
1505 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1507 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1506 assembler->Goto(&nan_loop); | 1508 assembler->Goto(&nan_loop); |
1507 } | 1509 } |
1508 } | 1510 } |
1509 | 1511 |
1510 assembler->Bind(&string_loop); | 1512 assembler->Bind(&string_loop); |
1511 { | 1513 { |
1512 Label continue_loop(assembler); | 1514 Label continue_loop(assembler); |
1513 assembler->GotoUnless( | 1515 assembler->GotoUnless( |
1514 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1516 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1515 &return_false); | 1517 &return_false); |
1516 Node* element_k = | 1518 Node* element_k = assembler->LoadFixedArrayElement( |
1517 assembler->LoadFixedArrayElement(elements, index_var.value()); | 1519 elements, index_var.value(), 0, INTPTR_PARAMETERS); |
1518 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop); | 1520 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop); |
1519 assembler->GotoUnless(assembler->Int32LessThan( | 1521 assembler->GotoUnless(assembler->Int32LessThan( |
1520 assembler->LoadInstanceType(element_k), | 1522 assembler->LoadInstanceType(element_k), |
1521 assembler->Int32Constant(FIRST_NONSTRING_TYPE)), | 1523 assembler->Int32Constant(FIRST_NONSTRING_TYPE)), |
1522 &continue_loop); | 1524 &continue_loop); |
1523 | 1525 |
1524 // TODO(bmeurer): Consider inlining the StringEqual logic here. | 1526 // TODO(bmeurer): Consider inlining the StringEqual logic here. |
1525 Callable callable = CodeFactory::StringEqual(assembler->isolate()); | 1527 Callable callable = CodeFactory::StringEqual(assembler->isolate()); |
1526 Node* result = | 1528 Node* result = |
1527 assembler->CallStub(callable, context, search_element, element_k); | 1529 assembler->CallStub(callable, context, search_element, element_k); |
1528 assembler->Branch( | 1530 assembler->Branch( |
1529 assembler->WordEqual(assembler->BooleanConstant(true), result), | 1531 assembler->WordEqual(assembler->BooleanConstant(true), result), |
1530 &return_true, &continue_loop); | 1532 &return_true, &continue_loop); |
1531 | 1533 |
1532 assembler->Bind(&continue_loop); | 1534 assembler->Bind(&continue_loop); |
1533 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1535 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1534 assembler->Goto(&string_loop); | 1536 assembler->Goto(&string_loop); |
1535 } | 1537 } |
1536 | 1538 |
1537 assembler->Bind(&simd_loop); | 1539 assembler->Bind(&simd_loop); |
1538 { | 1540 { |
1539 Label continue_loop(assembler, &index_var), | 1541 Label continue_loop(assembler, &index_var), |
1540 loop_body(assembler, &index_var); | 1542 loop_body(assembler, &index_var); |
1541 Node* map = assembler->LoadMap(search_element); | 1543 Node* map = assembler->LoadMap(search_element); |
1542 | 1544 |
1543 assembler->Goto(&loop_body); | 1545 assembler->Goto(&loop_body); |
1544 assembler->Bind(&loop_body); | 1546 assembler->Bind(&loop_body); |
1545 assembler->GotoUnless( | 1547 assembler->GotoUnless( |
1546 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1548 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1547 &return_false); | 1549 &return_false); |
1548 | 1550 |
1549 Node* element_k = | 1551 Node* element_k = assembler->LoadFixedArrayElement( |
1550 assembler->LoadFixedArrayElement(elements, index_var.value()); | 1552 elements, index_var.value(), 0, INTPTR_PARAMETERS); |
1551 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop); | 1553 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop); |
1552 | 1554 |
1553 Node* map_k = assembler->LoadMap(element_k); | 1555 Node* map_k = assembler->LoadMap(element_k); |
1554 assembler->BranchIfSimd128Equal(search_element, map, element_k, map_k, | 1556 assembler->BranchIfSimd128Equal(search_element, map, element_k, map_k, |
1555 &return_true, &continue_loop); | 1557 &return_true, &continue_loop); |
1556 | 1558 |
1557 assembler->Bind(&continue_loop); | 1559 assembler->Bind(&continue_loop); |
1558 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1560 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1559 assembler->Goto(&loop_body); | 1561 assembler->Goto(&loop_body); |
1560 } | 1562 } |
1561 } | 1563 } |
1562 | 1564 |
1563 assembler->Bind(&if_packed_doubles); | 1565 assembler->Bind(&if_packed_doubles); |
1564 { | 1566 { |
1565 Label nan_loop(assembler, &index_var), not_nan_loop(assembler, &index_var), | 1567 Label nan_loop(assembler, &index_var), not_nan_loop(assembler, &index_var), |
1566 hole_loop(assembler, &index_var), search_notnan(assembler); | 1568 hole_loop(assembler, &index_var), search_notnan(assembler); |
1567 Variable search_num(assembler, MachineRepresentation::kFloat64); | 1569 Variable search_num(assembler, MachineRepresentation::kFloat64); |
1568 | 1570 |
1569 assembler->GotoUnless(assembler->WordIsSmi(search_element), &search_notnan); | 1571 assembler->GotoUnless(assembler->WordIsSmi(search_element), &search_notnan); |
1570 search_num.Bind(assembler->SmiToFloat64(search_element)); | 1572 search_num.Bind(assembler->SmiToFloat64(search_element)); |
1571 assembler->Goto(¬_nan_loop); | 1573 assembler->Goto(¬_nan_loop); |
1572 | 1574 |
1573 assembler->Bind(&search_notnan); | 1575 assembler->Bind(&search_notnan); |
1574 assembler->GotoIf(assembler->WordNotEqual( | 1576 assembler->GotoIf(assembler->WordNotEqual( |
1575 assembler->LoadMap(search_element), heap_number_map), | 1577 assembler->LoadMap(search_element), heap_number_map), |
1576 &return_false); | 1578 &return_false); |
1577 | 1579 |
1578 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); | 1580 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); |
1579 | 1581 |
1580 assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop, | 1582 assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop, |
1581 ¬_nan_loop); | 1583 ¬_nan_loop); |
1582 | 1584 |
1583 // Search for HeapNumber | 1585 // Search for HeapNumber |
1584 assembler->Bind(¬_nan_loop); | 1586 assembler->Bind(¬_nan_loop); |
1585 { | 1587 { |
1586 Label continue_loop(assembler); | 1588 Label continue_loop(assembler); |
1587 assembler->GotoUnless( | 1589 assembler->GotoUnless( |
1588 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1590 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1589 &return_false); | 1591 &return_false); |
1590 Node* element_k = assembler->LoadFixedDoubleArrayElement( | 1592 Node* element_k = assembler->LoadFixedDoubleArrayElement( |
1591 elements, index_var.value(), MachineType::Float64()); | 1593 elements, index_var.value(), MachineType::Float64(), 0, |
1594 INTPTR_PARAMETERS); | |
1592 assembler->BranchIfFloat64Equal(element_k, search_num.value(), | 1595 assembler->BranchIfFloat64Equal(element_k, search_num.value(), |
1593 &return_true, &continue_loop); | 1596 &return_true, &continue_loop); |
1594 assembler->Bind(&continue_loop); | 1597 assembler->Bind(&continue_loop); |
1595 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1598 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1596 assembler->Goto(¬_nan_loop); | 1599 assembler->Goto(¬_nan_loop); |
1597 } | 1600 } |
1598 | 1601 |
1599 // Search for NaN | 1602 // Search for NaN |
1600 assembler->Bind(&nan_loop); | 1603 assembler->Bind(&nan_loop); |
1601 { | 1604 { |
1602 Label continue_loop(assembler); | 1605 Label continue_loop(assembler); |
1603 assembler->GotoUnless( | 1606 assembler->GotoUnless( |
1604 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1607 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1605 &return_false); | 1608 &return_false); |
1606 Node* element_k = assembler->LoadFixedDoubleArrayElement( | 1609 Node* element_k = assembler->LoadFixedDoubleArrayElement( |
1607 elements, index_var.value(), MachineType::Float64()); | 1610 elements, index_var.value(), MachineType::Float64(), 0, |
1611 INTPTR_PARAMETERS); | |
1608 assembler->BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); | 1612 assembler->BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); |
1609 assembler->Bind(&continue_loop); | 1613 assembler->Bind(&continue_loop); |
1610 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1614 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1611 assembler->Goto(&nan_loop); | 1615 assembler->Goto(&nan_loop); |
1612 } | 1616 } |
1613 } | 1617 } |
1614 | 1618 |
1615 assembler->Bind(&if_holey_doubles); | 1619 assembler->Bind(&if_holey_doubles); |
1616 { | 1620 { |
1617 Label nan_loop(assembler, &index_var), not_nan_loop(assembler, &index_var), | 1621 Label nan_loop(assembler, &index_var), not_nan_loop(assembler, &index_var), |
1618 hole_loop(assembler, &index_var), search_notnan(assembler); | 1622 hole_loop(assembler, &index_var), search_notnan(assembler); |
1619 Variable search_num(assembler, MachineRepresentation::kFloat64); | 1623 Variable search_num(assembler, MachineRepresentation::kFloat64); |
1620 | 1624 |
(...skipping 11 matching lines...) Expand all Loading... | |
1632 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); | 1636 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); |
1633 | 1637 |
1634 assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop, | 1638 assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop, |
1635 ¬_nan_loop); | 1639 ¬_nan_loop); |
1636 | 1640 |
1637 // Search for HeapNumber | 1641 // Search for HeapNumber |
1638 assembler->Bind(¬_nan_loop); | 1642 assembler->Bind(¬_nan_loop); |
1639 { | 1643 { |
1640 Label continue_loop(assembler); | 1644 Label continue_loop(assembler); |
1641 assembler->GotoUnless( | 1645 assembler->GotoUnless( |
1642 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1646 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1643 &return_false); | 1647 &return_false); |
1644 | 1648 |
1645 if (kPointerSize == kDoubleSize) { | 1649 if (kPointerSize == kDoubleSize) { |
1646 Node* element = assembler->LoadFixedDoubleArrayElement( | 1650 Node* element = assembler->LoadFixedDoubleArrayElement( |
1647 elements, index_var.value(), MachineType::Uint64()); | 1651 elements, index_var.value(), MachineType::Uint64(), 0, |
1652 INTPTR_PARAMETERS); | |
1648 Node* the_hole = assembler->Int64Constant(kHoleNanInt64); | 1653 Node* the_hole = assembler->Int64Constant(kHoleNanInt64); |
1649 assembler->GotoIf(assembler->Word64Equal(element, the_hole), | 1654 assembler->GotoIf(assembler->Word64Equal(element, the_hole), |
1650 &continue_loop); | 1655 &continue_loop); |
1651 } else { | 1656 } else { |
1652 Node* element_upper = assembler->LoadFixedDoubleArrayElement( | 1657 Node* element_upper = assembler->LoadFixedDoubleArrayElement( |
1653 elements, index_var.value(), MachineType::Uint32(), | 1658 elements, index_var.value(), MachineType::Uint32(), |
1654 kIeeeDoubleExponentWordOffset); | 1659 kIeeeDoubleExponentWordOffset, INTPTR_PARAMETERS); |
1655 assembler->GotoIf( | 1660 assembler->GotoIf( |
1656 assembler->Word32Equal(element_upper, | 1661 assembler->Word32Equal(element_upper, |
1657 assembler->Int32Constant(kHoleNanUpper32)), | 1662 assembler->Int32Constant(kHoleNanUpper32)), |
1658 &continue_loop); | 1663 &continue_loop); |
1659 } | 1664 } |
1660 | 1665 |
1661 Node* element_k = assembler->LoadFixedDoubleArrayElement( | 1666 Node* element_k = assembler->LoadFixedDoubleArrayElement( |
1662 elements, index_var.value(), MachineType::Float64()); | 1667 elements, index_var.value(), MachineType::Float64(), 0, |
1668 INTPTR_PARAMETERS); | |
1663 assembler->BranchIfFloat64Equal(element_k, search_num.value(), | 1669 assembler->BranchIfFloat64Equal(element_k, search_num.value(), |
1664 &return_true, &continue_loop); | 1670 &return_true, &continue_loop); |
1665 assembler->Bind(&continue_loop); | 1671 assembler->Bind(&continue_loop); |
1666 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1672 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1667 assembler->Goto(¬_nan_loop); | 1673 assembler->Goto(¬_nan_loop); |
1668 } | 1674 } |
1669 | 1675 |
1670 // Search for NaN | 1676 // Search for NaN |
1671 assembler->Bind(&nan_loop); | 1677 assembler->Bind(&nan_loop); |
1672 { | 1678 { |
1673 Label continue_loop(assembler); | 1679 Label continue_loop(assembler); |
1674 assembler->GotoUnless( | 1680 assembler->GotoUnless( |
1675 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1681 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1676 &return_false); | 1682 &return_false); |
1677 | 1683 |
1678 if (kPointerSize == kDoubleSize) { | 1684 if (kPointerSize == kDoubleSize) { |
1679 Node* element = assembler->LoadFixedDoubleArrayElement( | 1685 Node* element = assembler->LoadFixedDoubleArrayElement( |
1680 elements, index_var.value(), MachineType::Uint64()); | 1686 elements, index_var.value(), MachineType::Uint64(), 0, |
1687 INTPTR_PARAMETERS); | |
1681 Node* the_hole = assembler->Int64Constant(kHoleNanInt64); | 1688 Node* the_hole = assembler->Int64Constant(kHoleNanInt64); |
1682 assembler->GotoIf(assembler->Word64Equal(element, the_hole), | 1689 assembler->GotoIf(assembler->Word64Equal(element, the_hole), |
1683 &continue_loop); | 1690 &continue_loop); |
1684 } else { | 1691 } else { |
1685 Node* element_upper = assembler->LoadFixedDoubleArrayElement( | 1692 Node* element_upper = assembler->LoadFixedDoubleArrayElement( |
1686 elements, index_var.value(), MachineType::Uint32(), | 1693 elements, index_var.value(), MachineType::Uint32(), |
1687 kIeeeDoubleExponentWordOffset); | 1694 kIeeeDoubleExponentWordOffset, INTPTR_PARAMETERS); |
1688 assembler->GotoIf( | 1695 assembler->GotoIf( |
1689 assembler->Word32Equal(element_upper, | 1696 assembler->Word32Equal(element_upper, |
1690 assembler->Int32Constant(kHoleNanUpper32)), | 1697 assembler->Int32Constant(kHoleNanUpper32)), |
1691 &continue_loop); | 1698 &continue_loop); |
1692 } | 1699 } |
1693 | 1700 |
1694 Node* element_k = assembler->LoadFixedDoubleArrayElement( | 1701 Node* element_k = assembler->LoadFixedDoubleArrayElement( |
1695 elements, index_var.value(), MachineType::Float64()); | 1702 elements, index_var.value(), MachineType::Float64(), 0, |
1703 INTPTR_PARAMETERS); | |
1696 assembler->BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); | 1704 assembler->BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop); |
1697 assembler->Bind(&continue_loop); | 1705 assembler->Bind(&continue_loop); |
1698 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1706 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1699 assembler->Goto(&nan_loop); | 1707 assembler->Goto(&nan_loop); |
1700 } | 1708 } |
1701 | 1709 |
1702 // Search for the Hole | 1710 // Search for the Hole |
1703 assembler->Bind(&hole_loop); | 1711 assembler->Bind(&hole_loop); |
1704 { | 1712 { |
1705 assembler->GotoUnless( | 1713 assembler->GotoUnless( |
1706 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1714 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1707 &return_false); | 1715 &return_false); |
1708 | 1716 |
1709 if (kPointerSize == kDoubleSize) { | 1717 if (kPointerSize == kDoubleSize) { |
1710 Node* element = assembler->LoadFixedDoubleArrayElement( | 1718 Node* element = assembler->LoadFixedDoubleArrayElement( |
1711 elements, index_var.value(), MachineType::Uint64()); | 1719 elements, index_var.value(), MachineType::Uint64(), 0, |
1720 INTPTR_PARAMETERS); | |
1712 Node* the_hole = assembler->Int64Constant(kHoleNanInt64); | 1721 Node* the_hole = assembler->Int64Constant(kHoleNanInt64); |
1713 assembler->GotoIf(assembler->Word64Equal(element, the_hole), | 1722 assembler->GotoIf(assembler->Word64Equal(element, the_hole), |
1714 &return_true); | 1723 &return_true); |
1715 } else { | 1724 } else { |
1716 Node* element_upper = assembler->LoadFixedDoubleArrayElement( | 1725 Node* element_upper = assembler->LoadFixedDoubleArrayElement( |
1717 elements, index_var.value(), MachineType::Uint32(), | 1726 elements, index_var.value(), MachineType::Uint32(), |
1718 kIeeeDoubleExponentWordOffset); | 1727 kIeeeDoubleExponentWordOffset, INTPTR_PARAMETERS); |
1719 assembler->GotoIf( | 1728 assembler->GotoIf( |
1720 assembler->Word32Equal(element_upper, | 1729 assembler->Word32Equal(element_upper, |
1721 assembler->Int32Constant(kHoleNanUpper32)), | 1730 assembler->Int32Constant(kHoleNanUpper32)), |
1722 &return_true); | 1731 &return_true); |
1723 } | 1732 } |
1724 | 1733 |
1725 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1734 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1726 assembler->Goto(&hole_loop); | 1735 assembler->Goto(&hole_loop); |
1727 } | 1736 } |
1728 } | 1737 } |
1729 | 1738 |
1730 assembler->Bind(&return_true); | 1739 assembler->Bind(&return_true); |
1731 assembler->Return(assembler->BooleanConstant(true)); | 1740 assembler->Return(assembler->BooleanConstant(true)); |
1732 | 1741 |
1733 assembler->Bind(&return_false); | 1742 assembler->Bind(&return_false); |
1734 assembler->Return(assembler->BooleanConstant(false)); | 1743 assembler->Return(assembler->BooleanConstant(false)); |
1735 | 1744 |
1736 assembler->Bind(&call_runtime); | 1745 assembler->Bind(&call_runtime); |
1737 assembler->Return(assembler->CallRuntime(Runtime::kArrayIncludes_Slow, | 1746 assembler->Return(assembler->CallRuntime(Runtime::kArrayIncludes_Slow, |
1738 context, array, search_element, | 1747 context, array, search_element, |
1739 start_from)); | 1748 start_from)); |
1740 } | 1749 } |
1741 | 1750 |
1742 void Builtins::Generate_ArrayIndexOf(CodeStubAssembler* assembler) { | 1751 void Builtins::Generate_ArrayIndexOf(CodeStubAssembler* assembler) { |
1743 typedef compiler::Node Node; | 1752 typedef compiler::Node Node; |
1744 typedef CodeStubAssembler::Label Label; | 1753 typedef CodeStubAssembler::Label Label; |
1745 typedef CodeStubAssembler::Variable Variable; | 1754 typedef CodeStubAssembler::Variable Variable; |
1746 | 1755 |
1747 Node* array = assembler->Parameter(0); | 1756 Node* array = assembler->Parameter(0); |
1748 Node* search_element = assembler->Parameter(1); | 1757 Node* search_element = assembler->Parameter(1); |
1749 Node* start_from = assembler->Parameter(2); | 1758 Node* start_from = assembler->Parameter(2); |
1750 Node* context = assembler->Parameter(3 + 2); | 1759 Node* context = assembler->Parameter(3 + 2); |
1751 | 1760 |
1752 Node* int32_zero = assembler->Int32Constant(0); | 1761 Node* intptr_zero = assembler->IntPtrConstant(0); |
1753 Node* int32_one = assembler->Int32Constant(1); | 1762 Node* intptr_one = assembler->IntPtrConstant(1); |
1754 | 1763 |
1755 Node* undefined = assembler->UndefinedConstant(); | 1764 Node* undefined = assembler->UndefinedConstant(); |
1756 Node* heap_number_map = assembler->HeapNumberMapConstant(); | 1765 Node* heap_number_map = assembler->HeapNumberMapConstant(); |
1757 | 1766 |
1758 Variable len_var(assembler, MachineRepresentation::kWord32), | 1767 Variable len_var(assembler, MachineType::PointerRepresentation()), |
1759 index_var(assembler, MachineRepresentation::kWord32), | 1768 index_var(assembler, MachineType::PointerRepresentation()), |
1760 start_from_var(assembler, MachineRepresentation::kWord32); | 1769 start_from_var(assembler, MachineType::PointerRepresentation()); |
1761 | 1770 |
1762 Label init_k(assembler), return_found(assembler), return_not_found(assembler), | 1771 Label init_k(assembler), return_found(assembler), return_not_found(assembler), |
1763 call_runtime(assembler); | 1772 call_runtime(assembler); |
1764 | 1773 |
1765 Label init_len(assembler); | 1774 Label init_len(assembler); |
1766 | 1775 |
1767 index_var.Bind(int32_zero); | 1776 index_var.Bind(intptr_zero); |
1768 len_var.Bind(int32_zero); | 1777 len_var.Bind(intptr_zero); |
1769 | 1778 |
1770 // Take slow path if not a JSArray, if retrieving elements requires | 1779 // Take slow path if not a JSArray, if retrieving elements requires |
1771 // traversing prototype, or if access checks are required. | 1780 // traversing prototype, or if access checks are required. |
1772 assembler->BranchIfFastJSArray(array, context, &init_len, &call_runtime); | 1781 assembler->BranchIfFastJSArray(array, context, &init_len, &call_runtime); |
1773 | 1782 |
1774 assembler->Bind(&init_len); | 1783 assembler->Bind(&init_len); |
1775 { | 1784 { |
1776 // Handle case where JSArray length is not an Smi in the runtime | 1785 // Handle case where JSArray length is not an Smi in the runtime |
1777 Node* len = assembler->LoadObjectField(array, JSArray::kLengthOffset); | 1786 Node* len = assembler->LoadObjectField(array, JSArray::kLengthOffset); |
1778 assembler->GotoUnless(assembler->WordIsSmi(len), &call_runtime); | 1787 assembler->GotoUnless(assembler->WordIsSmi(len), &call_runtime); |
1779 | 1788 |
1780 len_var.Bind(assembler->SmiToWord(len)); | 1789 len_var.Bind(assembler->SmiToWord(len)); |
1781 assembler->Branch(assembler->Word32Equal(len_var.value(), int32_zero), | 1790 assembler->Branch(assembler->WordEqual(len_var.value(), intptr_zero), |
1782 &return_not_found, &init_k); | 1791 &return_not_found, &init_k); |
1783 } | 1792 } |
1784 | 1793 |
1785 assembler->Bind(&init_k); | 1794 assembler->Bind(&init_k); |
1786 { | 1795 { |
1787 Label done(assembler), init_k_smi(assembler), init_k_heap_num(assembler), | 1796 Label done(assembler), init_k_smi(assembler), init_k_heap_num(assembler), |
1788 init_k_zero(assembler), init_k_n(assembler); | 1797 init_k_zero(assembler), init_k_n(assembler); |
1789 Callable call_to_integer = CodeFactory::ToInteger(assembler->isolate()); | 1798 Callable call_to_integer = CodeFactory::ToInteger(assembler->isolate()); |
1790 Node* tagged_n = assembler->CallStub(call_to_integer, context, start_from); | 1799 Node* tagged_n = assembler->CallStub(call_to_integer, context, start_from); |
1791 | 1800 |
1792 assembler->Branch(assembler->WordIsSmi(tagged_n), &init_k_smi, | 1801 assembler->Branch(assembler->WordIsSmi(tagged_n), &init_k_smi, |
1793 &init_k_heap_num); | 1802 &init_k_heap_num); |
1794 | 1803 |
1795 assembler->Bind(&init_k_smi); | 1804 assembler->Bind(&init_k_smi); |
1796 { | 1805 { |
1797 start_from_var.Bind(assembler->SmiToWord32(tagged_n)); | 1806 start_from_var.Bind(assembler->SmiUntag(tagged_n)); |
1798 assembler->Goto(&init_k_n); | 1807 assembler->Goto(&init_k_n); |
1799 } | 1808 } |
1800 | 1809 |
1801 assembler->Bind(&init_k_heap_num); | 1810 assembler->Bind(&init_k_heap_num); |
1802 { | 1811 { |
1803 Label do_return_not_found(assembler); | 1812 Label do_return_not_found(assembler); |
1804 Node* fp_len = assembler->ChangeInt32ToFloat64(len_var.value()); | 1813 // This round is lossless for all valid lengths. |
Igor Sheludko
2016/09/08 11:07:51
This is not trivial.
| |
1814 Node* fp_len = assembler->RoundIntPtrToFloat64(len_var.value()); | |
1805 Node* fp_n = assembler->LoadHeapNumberValue(tagged_n); | 1815 Node* fp_n = assembler->LoadHeapNumberValue(tagged_n); |
1806 assembler->GotoIf(assembler->Float64GreaterThanOrEqual(fp_n, fp_len), | 1816 assembler->GotoIf(assembler->Float64GreaterThanOrEqual(fp_n, fp_len), |
1807 &do_return_not_found); | 1817 &do_return_not_found); |
1808 start_from_var.Bind(assembler->TruncateFloat64ToWord32(fp_n)); | 1818 start_from_var.Bind(assembler->ChangeInt32ToIntPtr( |
1819 assembler->TruncateFloat64ToWord32(fp_n))); | |
1809 assembler->Goto(&init_k_n); | 1820 assembler->Goto(&init_k_n); |
1810 | 1821 |
1811 assembler->Bind(&do_return_not_found); | 1822 assembler->Bind(&do_return_not_found); |
1812 { | 1823 { |
1813 index_var.Bind(int32_zero); | 1824 index_var.Bind(intptr_zero); |
1814 assembler->Goto(&return_not_found); | 1825 assembler->Goto(&return_not_found); |
1815 } | 1826 } |
1816 } | 1827 } |
1817 | 1828 |
1818 assembler->Bind(&init_k_n); | 1829 assembler->Bind(&init_k_n); |
1819 { | 1830 { |
1820 Label if_positive(assembler), if_negative(assembler), done(assembler); | 1831 Label if_positive(assembler), if_negative(assembler), done(assembler); |
1821 assembler->Branch( | 1832 assembler->Branch( |
1822 assembler->Int32LessThan(start_from_var.value(), int32_zero), | 1833 assembler->IntPtrLessThan(start_from_var.value(), intptr_zero), |
1823 &if_negative, &if_positive); | 1834 &if_negative, &if_positive); |
1824 | 1835 |
1825 assembler->Bind(&if_positive); | 1836 assembler->Bind(&if_positive); |
1826 { | 1837 { |
1827 index_var.Bind(start_from_var.value()); | 1838 index_var.Bind(start_from_var.value()); |
1828 assembler->Goto(&done); | 1839 assembler->Goto(&done); |
1829 } | 1840 } |
1830 | 1841 |
1831 assembler->Bind(&if_negative); | 1842 assembler->Bind(&if_negative); |
1832 { | 1843 { |
1833 index_var.Bind( | 1844 index_var.Bind( |
1834 assembler->Int32Add(len_var.value(), start_from_var.value())); | 1845 assembler->IntPtrAdd(len_var.value(), start_from_var.value())); |
1835 assembler->Branch( | 1846 assembler->Branch( |
1836 assembler->Int32LessThan(index_var.value(), int32_zero), | 1847 assembler->IntPtrLessThan(index_var.value(), intptr_zero), |
1837 &init_k_zero, &done); | 1848 &init_k_zero, &done); |
1838 } | 1849 } |
1839 | 1850 |
1840 assembler->Bind(&init_k_zero); | 1851 assembler->Bind(&init_k_zero); |
1841 { | 1852 { |
1842 index_var.Bind(int32_zero); | 1853 index_var.Bind(intptr_zero); |
1843 assembler->Goto(&done); | 1854 assembler->Goto(&done); |
1844 } | 1855 } |
1845 | 1856 |
1846 assembler->Bind(&done); | 1857 assembler->Bind(&done); |
1847 } | 1858 } |
1848 } | 1859 } |
1849 | 1860 |
1850 static int32_t kElementsKind[] = { | 1861 static int32_t kElementsKind[] = { |
1851 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS, | 1862 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS, |
1852 FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, | 1863 FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS, |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1888 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); | 1899 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); |
1889 assembler->Goto(&heap_num_loop); | 1900 assembler->Goto(&heap_num_loop); |
1890 | 1901 |
1891 assembler->Bind(¬_heap_num); | 1902 assembler->Bind(¬_heap_num); |
1892 Node* search_type = assembler->LoadMapInstanceType(map); | 1903 Node* search_type = assembler->LoadMapInstanceType(map); |
1893 assembler->GotoIf( | 1904 assembler->GotoIf( |
1894 assembler->Int32LessThan( | 1905 assembler->Int32LessThan( |
1895 search_type, assembler->Int32Constant(FIRST_NONSTRING_TYPE)), | 1906 search_type, assembler->Int32Constant(FIRST_NONSTRING_TYPE)), |
1896 &string_loop); | 1907 &string_loop); |
1897 assembler->GotoIf( | 1908 assembler->GotoIf( |
1898 assembler->WordEqual(search_type, | 1909 assembler->Word32Equal(search_type, |
1899 assembler->Int32Constant(SIMD128_VALUE_TYPE)), | 1910 assembler->Int32Constant(SIMD128_VALUE_TYPE)), |
1900 &simd_loop); | 1911 &simd_loop); |
1901 assembler->Goto(&ident_loop); | 1912 assembler->Goto(&ident_loop); |
1902 | 1913 |
1903 assembler->Bind(&ident_loop); | 1914 assembler->Bind(&ident_loop); |
1904 { | 1915 { |
1905 assembler->GotoUnless( | 1916 assembler->GotoUnless( |
1906 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1917 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1907 &return_not_found); | 1918 &return_not_found); |
1908 Node* element_k = | 1919 Node* element_k = assembler->LoadFixedArrayElement( |
1909 assembler->LoadFixedArrayElement(elements, index_var.value()); | 1920 elements, index_var.value(), 0, INTPTR_PARAMETERS); |
1910 assembler->GotoIf(assembler->WordEqual(element_k, search_element), | 1921 assembler->GotoIf(assembler->WordEqual(element_k, search_element), |
1911 &return_found); | 1922 &return_found); |
1912 | 1923 |
1913 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1924 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1914 assembler->Goto(&ident_loop); | 1925 assembler->Goto(&ident_loop); |
1915 } | 1926 } |
1916 | 1927 |
1917 assembler->Bind(&undef_loop); | 1928 assembler->Bind(&undef_loop); |
1918 { | 1929 { |
1919 assembler->GotoUnless( | 1930 assembler->GotoUnless( |
1920 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1931 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1921 &return_not_found); | 1932 &return_not_found); |
1922 Node* element_k = | 1933 Node* element_k = assembler->LoadFixedArrayElement( |
1923 assembler->LoadFixedArrayElement(elements, index_var.value()); | 1934 elements, index_var.value(), 0, INTPTR_PARAMETERS); |
1924 assembler->GotoIf(assembler->WordEqual(element_k, undefined), | 1935 assembler->GotoIf(assembler->WordEqual(element_k, undefined), |
1925 &return_found); | 1936 &return_found); |
1926 | 1937 |
1927 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1938 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1928 assembler->Goto(&undef_loop); | 1939 assembler->Goto(&undef_loop); |
1929 } | 1940 } |
1930 | 1941 |
1931 assembler->Bind(&heap_num_loop); | 1942 assembler->Bind(&heap_num_loop); |
1932 { | 1943 { |
1933 Label not_nan_loop(assembler, &index_var); | 1944 Label not_nan_loop(assembler, &index_var); |
1934 assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found, | 1945 assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found, |
1935 ¬_nan_loop); | 1946 ¬_nan_loop); |
1936 | 1947 |
1937 assembler->Bind(¬_nan_loop); | 1948 assembler->Bind(¬_nan_loop); |
1938 { | 1949 { |
1939 Label continue_loop(assembler), not_smi(assembler); | 1950 Label continue_loop(assembler), not_smi(assembler); |
1940 assembler->GotoUnless( | 1951 assembler->GotoUnless( |
1941 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1952 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1942 &return_not_found); | 1953 &return_not_found); |
1943 Node* element_k = | 1954 Node* element_k = assembler->LoadFixedArrayElement( |
1944 assembler->LoadFixedArrayElement(elements, index_var.value()); | 1955 elements, index_var.value(), 0, INTPTR_PARAMETERS); |
1945 assembler->GotoUnless(assembler->WordIsSmi(element_k), ¬_smi); | 1956 assembler->GotoUnless(assembler->WordIsSmi(element_k), ¬_smi); |
1946 assembler->Branch( | 1957 assembler->Branch( |
1947 assembler->Float64Equal(search_num.value(), | 1958 assembler->Float64Equal(search_num.value(), |
1948 assembler->SmiToFloat64(element_k)), | 1959 assembler->SmiToFloat64(element_k)), |
1949 &return_found, &continue_loop); | 1960 &return_found, &continue_loop); |
1950 | 1961 |
1951 assembler->Bind(¬_smi); | 1962 assembler->Bind(¬_smi); |
1952 assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k), | 1963 assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k), |
1953 heap_number_map), | 1964 heap_number_map), |
1954 &continue_loop); | 1965 &continue_loop); |
1955 assembler->BranchIfFloat64Equal( | 1966 assembler->BranchIfFloat64Equal( |
1956 search_num.value(), assembler->LoadHeapNumberValue(element_k), | 1967 search_num.value(), assembler->LoadHeapNumberValue(element_k), |
1957 &return_found, &continue_loop); | 1968 &return_found, &continue_loop); |
1958 | 1969 |
1959 assembler->Bind(&continue_loop); | 1970 assembler->Bind(&continue_loop); |
1960 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1971 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1961 assembler->Goto(¬_nan_loop); | 1972 assembler->Goto(¬_nan_loop); |
1962 } | 1973 } |
1963 } | 1974 } |
1964 | 1975 |
1965 assembler->Bind(&string_loop); | 1976 assembler->Bind(&string_loop); |
1966 { | 1977 { |
1967 Label continue_loop(assembler); | 1978 Label continue_loop(assembler); |
1968 assembler->GotoUnless( | 1979 assembler->GotoUnless( |
1969 assembler->Int32LessThan(index_var.value(), len_var.value()), | 1980 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
1970 &return_not_found); | 1981 &return_not_found); |
1971 Node* element_k = | 1982 Node* element_k = assembler->LoadFixedArrayElement( |
1972 assembler->LoadFixedArrayElement(elements, index_var.value()); | 1983 elements, index_var.value(), 0, INTPTR_PARAMETERS); |
1973 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop); | 1984 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop); |
1974 assembler->GotoUnless(assembler->Int32LessThan( | 1985 assembler->GotoUnless(assembler->Int32LessThan( |
1975 assembler->LoadInstanceType(element_k), | 1986 assembler->LoadInstanceType(element_k), |
1976 assembler->Int32Constant(FIRST_NONSTRING_TYPE)), | 1987 assembler->Int32Constant(FIRST_NONSTRING_TYPE)), |
1977 &continue_loop); | 1988 &continue_loop); |
1978 | 1989 |
1979 // TODO(bmeurer): Consider inlining the StringEqual logic here. | 1990 // TODO(bmeurer): Consider inlining the StringEqual logic here. |
1980 Callable callable = CodeFactory::StringEqual(assembler->isolate()); | 1991 Callable callable = CodeFactory::StringEqual(assembler->isolate()); |
1981 Node* result = | 1992 Node* result = |
1982 assembler->CallStub(callable, context, search_element, element_k); | 1993 assembler->CallStub(callable, context, search_element, element_k); |
1983 assembler->Branch( | 1994 assembler->Branch( |
1984 assembler->WordEqual(assembler->BooleanConstant(true), result), | 1995 assembler->WordEqual(assembler->BooleanConstant(true), result), |
1985 &return_found, &continue_loop); | 1996 &return_found, &continue_loop); |
1986 | 1997 |
1987 assembler->Bind(&continue_loop); | 1998 assembler->Bind(&continue_loop); |
1988 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 1999 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
1989 assembler->Goto(&string_loop); | 2000 assembler->Goto(&string_loop); |
1990 } | 2001 } |
1991 | 2002 |
1992 assembler->Bind(&simd_loop); | 2003 assembler->Bind(&simd_loop); |
1993 { | 2004 { |
1994 Label continue_loop(assembler, &index_var), | 2005 Label continue_loop(assembler, &index_var), |
1995 loop_body(assembler, &index_var); | 2006 loop_body(assembler, &index_var); |
1996 Node* map = assembler->LoadMap(search_element); | 2007 Node* map = assembler->LoadMap(search_element); |
1997 | 2008 |
1998 assembler->Goto(&loop_body); | 2009 assembler->Goto(&loop_body); |
1999 assembler->Bind(&loop_body); | 2010 assembler->Bind(&loop_body); |
2000 assembler->GotoUnless( | 2011 assembler->GotoUnless( |
2001 assembler->Int32LessThan(index_var.value(), len_var.value()), | 2012 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
2002 &return_not_found); | 2013 &return_not_found); |
2003 | 2014 |
2004 Node* element_k = | 2015 Node* element_k = assembler->LoadFixedArrayElement( |
2005 assembler->LoadFixedArrayElement(elements, index_var.value()); | 2016 elements, index_var.value(), 0, INTPTR_PARAMETERS); |
2006 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop); | 2017 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop); |
2007 | 2018 |
2008 Node* map_k = assembler->LoadMap(element_k); | 2019 Node* map_k = assembler->LoadMap(element_k); |
2009 assembler->BranchIfSimd128Equal(search_element, map, element_k, map_k, | 2020 assembler->BranchIfSimd128Equal(search_element, map, element_k, map_k, |
2010 &return_found, &continue_loop); | 2021 &return_found, &continue_loop); |
2011 | 2022 |
2012 assembler->Bind(&continue_loop); | 2023 assembler->Bind(&continue_loop); |
2013 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 2024 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
2014 assembler->Goto(&loop_body); | 2025 assembler->Goto(&loop_body); |
2015 } | 2026 } |
2016 } | 2027 } |
2017 | 2028 |
2018 assembler->Bind(&if_packed_doubles); | 2029 assembler->Bind(&if_packed_doubles); |
2019 { | 2030 { |
2020 Label not_nan_loop(assembler, &index_var), search_notnan(assembler); | 2031 Label not_nan_loop(assembler, &index_var), search_notnan(assembler); |
2021 Variable search_num(assembler, MachineRepresentation::kFloat64); | 2032 Variable search_num(assembler, MachineRepresentation::kFloat64); |
2022 | 2033 |
2023 assembler->GotoUnless(assembler->WordIsSmi(search_element), &search_notnan); | 2034 assembler->GotoUnless(assembler->WordIsSmi(search_element), &search_notnan); |
2024 search_num.Bind(assembler->SmiToFloat64(search_element)); | 2035 search_num.Bind(assembler->SmiToFloat64(search_element)); |
2025 assembler->Goto(¬_nan_loop); | 2036 assembler->Goto(¬_nan_loop); |
2026 | 2037 |
2027 assembler->Bind(&search_notnan); | 2038 assembler->Bind(&search_notnan); |
2028 assembler->GotoIf(assembler->WordNotEqual( | 2039 assembler->GotoIf(assembler->WordNotEqual( |
2029 assembler->LoadMap(search_element), heap_number_map), | 2040 assembler->LoadMap(search_element), heap_number_map), |
2030 &return_not_found); | 2041 &return_not_found); |
2031 | 2042 |
2032 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); | 2043 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); |
2033 | 2044 |
2034 assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found, | 2045 assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found, |
2035 ¬_nan_loop); | 2046 ¬_nan_loop); |
2036 | 2047 |
2037 // Search for HeapNumber | 2048 // Search for HeapNumber |
2038 assembler->Bind(¬_nan_loop); | 2049 assembler->Bind(¬_nan_loop); |
2039 { | 2050 { |
2040 Label continue_loop(assembler); | 2051 Label continue_loop(assembler); |
2041 assembler->GotoUnless( | 2052 assembler->GotoUnless( |
2042 assembler->Int32LessThan(index_var.value(), len_var.value()), | 2053 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
2043 &return_not_found); | 2054 &return_not_found); |
2044 Node* element_k = assembler->LoadFixedDoubleArrayElement( | 2055 Node* element_k = assembler->LoadFixedDoubleArrayElement( |
2045 elements, index_var.value(), MachineType::Float64()); | 2056 elements, index_var.value(), MachineType::Float64(), 0, |
2057 INTPTR_PARAMETERS); | |
2046 assembler->BranchIfFloat64Equal(element_k, search_num.value(), | 2058 assembler->BranchIfFloat64Equal(element_k, search_num.value(), |
2047 &return_found, &continue_loop); | 2059 &return_found, &continue_loop); |
2048 assembler->Bind(&continue_loop); | 2060 assembler->Bind(&continue_loop); |
2049 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 2061 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
2050 assembler->Goto(¬_nan_loop); | 2062 assembler->Goto(¬_nan_loop); |
2051 } | 2063 } |
2052 } | 2064 } |
2053 | 2065 |
2054 assembler->Bind(&if_holey_doubles); | 2066 assembler->Bind(&if_holey_doubles); |
2055 { | 2067 { |
2056 Label not_nan_loop(assembler, &index_var), search_notnan(assembler); | 2068 Label not_nan_loop(assembler, &index_var), search_notnan(assembler); |
2057 Variable search_num(assembler, MachineRepresentation::kFloat64); | 2069 Variable search_num(assembler, MachineRepresentation::kFloat64); |
2058 | 2070 |
2059 assembler->GotoUnless(assembler->WordIsSmi(search_element), &search_notnan); | 2071 assembler->GotoUnless(assembler->WordIsSmi(search_element), &search_notnan); |
2060 search_num.Bind(assembler->SmiToFloat64(search_element)); | 2072 search_num.Bind(assembler->SmiToFloat64(search_element)); |
2061 assembler->Goto(¬_nan_loop); | 2073 assembler->Goto(¬_nan_loop); |
2062 | 2074 |
2063 assembler->Bind(&search_notnan); | 2075 assembler->Bind(&search_notnan); |
2064 assembler->GotoIf(assembler->WordNotEqual( | 2076 assembler->GotoIf(assembler->WordNotEqual( |
2065 assembler->LoadMap(search_element), heap_number_map), | 2077 assembler->LoadMap(search_element), heap_number_map), |
2066 &return_not_found); | 2078 &return_not_found); |
2067 | 2079 |
2068 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); | 2080 search_num.Bind(assembler->LoadHeapNumberValue(search_element)); |
2069 | 2081 |
2070 assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found, | 2082 assembler->BranchIfFloat64IsNaN(search_num.value(), &return_not_found, |
2071 ¬_nan_loop); | 2083 ¬_nan_loop); |
2072 | 2084 |
2073 // Search for HeapNumber | 2085 // Search for HeapNumber |
2074 assembler->Bind(¬_nan_loop); | 2086 assembler->Bind(¬_nan_loop); |
2075 { | 2087 { |
2076 Label continue_loop(assembler); | 2088 Label continue_loop(assembler); |
2077 assembler->GotoUnless( | 2089 assembler->GotoUnless( |
2078 assembler->Int32LessThan(index_var.value(), len_var.value()), | 2090 assembler->UintPtrLessThan(index_var.value(), len_var.value()), |
2079 &return_not_found); | 2091 &return_not_found); |
2080 | 2092 |
2081 if (kPointerSize == kDoubleSize) { | 2093 if (kPointerSize == kDoubleSize) { |
2082 Node* element = assembler->LoadFixedDoubleArrayElement( | 2094 Node* element = assembler->LoadFixedDoubleArrayElement( |
2083 elements, index_var.value(), MachineType::Uint64()); | 2095 elements, index_var.value(), MachineType::Uint64(), 0, |
2096 INTPTR_PARAMETERS); | |
2084 Node* the_hole = assembler->Int64Constant(kHoleNanInt64); | 2097 Node* the_hole = assembler->Int64Constant(kHoleNanInt64); |
2085 assembler->GotoIf(assembler->Word64Equal(element, the_hole), | 2098 assembler->GotoIf(assembler->Word64Equal(element, the_hole), |
2086 &continue_loop); | 2099 &continue_loop); |
2087 } else { | 2100 } else { |
2088 Node* element_upper = assembler->LoadFixedDoubleArrayElement( | 2101 Node* element_upper = assembler->LoadFixedDoubleArrayElement( |
2089 elements, index_var.value(), MachineType::Uint32(), | 2102 elements, index_var.value(), MachineType::Uint32(), |
2090 kIeeeDoubleExponentWordOffset); | 2103 kIeeeDoubleExponentWordOffset, INTPTR_PARAMETERS); |
2091 assembler->GotoIf( | 2104 assembler->GotoIf( |
2092 assembler->Word32Equal(element_upper, | 2105 assembler->Word32Equal(element_upper, |
2093 assembler->Int32Constant(kHoleNanUpper32)), | 2106 assembler->Int32Constant(kHoleNanUpper32)), |
2094 &continue_loop); | 2107 &continue_loop); |
2095 } | 2108 } |
2096 | 2109 |
2097 Node* element_k = assembler->LoadFixedDoubleArrayElement( | 2110 Node* element_k = assembler->LoadFixedDoubleArrayElement( |
2098 elements, index_var.value(), MachineType::Float64()); | 2111 elements, index_var.value(), MachineType::Float64(), 0, |
2112 INTPTR_PARAMETERS); | |
2099 assembler->BranchIfFloat64Equal(element_k, search_num.value(), | 2113 assembler->BranchIfFloat64Equal(element_k, search_num.value(), |
2100 &return_found, &continue_loop); | 2114 &return_found, &continue_loop); |
2101 assembler->Bind(&continue_loop); | 2115 assembler->Bind(&continue_loop); |
2102 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one)); | 2116 index_var.Bind(assembler->IntPtrAdd(index_var.value(), intptr_one)); |
2103 assembler->Goto(¬_nan_loop); | 2117 assembler->Goto(¬_nan_loop); |
2104 } | 2118 } |
2105 } | 2119 } |
2106 | 2120 |
2107 assembler->Bind(&return_found); | 2121 assembler->Bind(&return_found); |
2108 assembler->Return(assembler->ChangeInt32ToTagged(index_var.value())); | 2122 assembler->Return(assembler->ChangeInt32ToTagged(index_var.value())); |
2109 | 2123 |
2110 assembler->Bind(&return_not_found); | 2124 assembler->Bind(&return_not_found); |
2111 assembler->Return(assembler->NumberConstant(-1)); | 2125 assembler->Return(assembler->NumberConstant(-1)); |
2112 | 2126 |
2113 assembler->Bind(&call_runtime); | 2127 assembler->Bind(&call_runtime); |
2114 assembler->Return(assembler->CallRuntime(Runtime::kArrayIndexOf, context, | 2128 assembler->Return(assembler->CallRuntime(Runtime::kArrayIndexOf, context, |
2115 array, search_element, start_from)); | 2129 array, search_element, start_from)); |
2116 } | 2130 } |
2117 | 2131 |
2118 } // namespace internal | 2132 } // namespace internal |
2119 } // namespace v8 | 2133 } // namespace v8 |
OLD | NEW |