Chromium Code Reviews| 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 |