Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Side by Side Diff: src/builtins/builtins-array.cc

Issue 2205883003: Reland [builtins] implement Array.prototype.includes in TurboFan (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix compiler warning Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
8 #include "src/code-factory.h"
7 #include "src/elements.h" 9 #include "src/elements.h"
8 10
9 namespace v8 { 11 namespace v8 {
10 namespace internal { 12 namespace internal {
11 13
12 namespace { 14 namespace {
13 15
14 inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) { 16 inline bool ClampedToInteger(Isolate* isolate, Object* object, int* out) {
15 // This is an extended version of ECMA-262 7.1.11 handling signed values 17 // This is an extended version of ECMA-262 7.1.11 handling signed values
16 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt] 18 // Try to convert object to a number and clamp values to [kMinInt, kMaxInt]
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 map != context->fast_aliased_arguments_map()) { 50 map != context->fast_aliased_arguments_map()) {
49 return false; 51 return false;
50 } 52 }
51 DCHECK(object->HasFastElements() || object->HasFastArgumentsElements()); 53 DCHECK(object->HasFastElements() || object->HasFastArgumentsElements());
52 Object* len_obj = object->InObjectPropertyAt(JSArgumentsObject::kLengthIndex); 54 Object* len_obj = object->InObjectPropertyAt(JSArgumentsObject::kLengthIndex);
53 if (!len_obj->IsSmi()) return false; 55 if (!len_obj->IsSmi()) return false;
54 *out = Max(0, Smi::cast(len_obj)->value()); 56 *out = Max(0, Smi::cast(len_obj)->value());
55 return *out <= object->elements()->length(); 57 return *out <= object->elements()->length();
56 } 58 }
57 59
58 inline bool PrototypeHasNoElements(Isolate* isolate, JSObject* object) {
59 DisallowHeapAllocation no_gc;
60 HeapObject* prototype = HeapObject::cast(object->map()->prototype());
61 HeapObject* null = isolate->heap()->null_value();
62 HeapObject* empty = isolate->heap()->empty_fixed_array();
63 while (prototype != null) {
64 Map* map = prototype->map();
65 if (map->instance_type() <= LAST_CUSTOM_ELEMENTS_RECEIVER) return false;
66 if (JSObject::cast(prototype)->elements() != empty) return false;
67 prototype = HeapObject::cast(map->prototype());
68 }
69 return true;
70 }
71
72 inline bool IsJSArrayFastElementMovingAllowed(Isolate* isolate, 60 inline bool IsJSArrayFastElementMovingAllowed(Isolate* isolate,
73 JSArray* receiver) { 61 JSArray* receiver) {
74 return PrototypeHasNoElements(isolate, receiver); 62 return JSObject::PrototypeHasNoElements(isolate, receiver);
75 } 63 }
76 64
77 inline bool HasSimpleElements(JSObject* current) { 65 inline bool HasSimpleElements(JSObject* current) {
78 return current->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER && 66 return current->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER &&
79 !current->GetElementsAccessor()->HasAccessors(current); 67 !current->GetElementsAccessor()->HasAccessors(current);
80 } 68 }
81 69
82 inline bool HasOnlySimpleReceiverElements(Isolate* isolate, 70 inline bool HasOnlySimpleReceiverElements(Isolate* isolate,
83 JSObject* receiver) { 71 JSObject* receiver) {
84 // Check that we have no accessors on the receiver's elements. 72 // Check that we have no accessors on the receiver's elements.
85 if (!HasSimpleElements(receiver)) return false; 73 if (!HasSimpleElements(receiver)) return false;
86 return PrototypeHasNoElements(isolate, receiver); 74 return JSObject::PrototypeHasNoElements(isolate, receiver);
87 } 75 }
88 76
89 inline bool HasOnlySimpleElements(Isolate* isolate, JSReceiver* receiver) { 77 inline bool HasOnlySimpleElements(Isolate* isolate, JSReceiver* receiver) {
90 DisallowHeapAllocation no_gc; 78 DisallowHeapAllocation no_gc;
91 PrototypeIterator iter(isolate, receiver, kStartAtReceiver); 79 PrototypeIterator iter(isolate, receiver, kStartAtReceiver);
92 for (; !iter.IsAtEnd(); iter.Advance()) { 80 for (; !iter.IsAtEnd(); iter.Advance()) {
93 if (iter.GetCurrent()->IsJSProxy()) return false; 81 if (iter.GetCurrent()->IsJSProxy()) return false;
94 JSObject* current = iter.GetCurrent<JSObject>(); 82 JSObject* current = iter.GetCurrent<JSObject>();
95 if (!HasSimpleElements(current)) return false; 83 if (!HasSimpleElements(current)) return false;
96 } 84 }
(...skipping 1167 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 assembler->Return(assembler->BooleanConstant(true)); 1252 assembler->Return(assembler->BooleanConstant(true));
1265 1253
1266 assembler->Bind(&return_false); 1254 assembler->Bind(&return_false);
1267 assembler->Return(assembler->BooleanConstant(false)); 1255 assembler->Return(assembler->BooleanConstant(false));
1268 1256
1269 assembler->Bind(&call_runtime); 1257 assembler->Bind(&call_runtime);
1270 assembler->Return( 1258 assembler->Return(
1271 assembler->CallRuntime(Runtime::kArrayIsArray, context, object)); 1259 assembler->CallRuntime(Runtime::kArrayIsArray, context, object));
1272 } 1260 }
1273 1261
1262 void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) {
1263 typedef compiler::Node Node;
1264 typedef CodeStubAssembler::Label Label;
1265 typedef CodeStubAssembler::Variable Variable;
1266
1267 Node* array = assembler->Parameter(0);
1268 Node* search_element = assembler->Parameter(1);
1269 Node* start_from = assembler->Parameter(2);
1270 Node* context = assembler->Parameter(3 + 2);
1271
1272 Node* int32_zero = assembler->Int32Constant(0);
1273 Node* int32_one = assembler->Int32Constant(1);
1274
1275 Node* the_hole = assembler->TheHoleConstant();
1276 Node* undefined = assembler->UndefinedConstant();
1277 Node* heap_number_map = assembler->HeapNumberMapConstant();
1278
1279 Variable len_var(assembler, MachineRepresentation::kWord32),
1280 index_var(assembler, MachineRepresentation::kWord32),
1281 start_from_var(assembler, MachineRepresentation::kWord32);
1282
1283 Label init_k(assembler), return_true(assembler), return_false(assembler),
1284 call_runtime(assembler);
1285
1286 Label init_len(assembler);
1287
1288 index_var.Bind(int32_zero);
1289 len_var.Bind(int32_zero);
1290
1291 // Take slow path if not a JSArray, if retrieving elements requires
1292 // traversing prototype, or if access checks are required.
1293 assembler->BranchIfFastJSArray(array, context, &init_len, &call_runtime);
1294
1295 assembler->Bind(&init_len);
1296 {
1297 // Handle case where JSArray length is not an Smi in the runtime
1298 Node* len = assembler->LoadObjectField(array, JSArray::kLengthOffset);
1299 assembler->GotoUnless(assembler->WordIsSmi(len), &call_runtime);
1300
1301 len_var.Bind(assembler->SmiToWord(len));
1302 assembler->Branch(assembler->Word32Equal(len_var.value(), int32_zero),
1303 &return_false, &init_k);
1304 }
1305
1306 assembler->Bind(&init_k);
1307 {
1308 Label done(assembler), init_k_smi(assembler), init_k_heap_num(assembler),
1309 init_k_zero(assembler), init_k_n(assembler);
1310 Callable call_to_integer = CodeFactory::ToInteger(assembler->isolate());
1311 Node* tagged_n = assembler->CallStub(call_to_integer, context, start_from);
1312
1313 assembler->Branch(assembler->WordIsSmi(tagged_n), &init_k_smi,
1314 &init_k_heap_num);
1315
1316 assembler->Bind(&init_k_smi);
1317 {
1318 start_from_var.Bind(assembler->SmiToWord32(tagged_n));
1319 assembler->Goto(&init_k_n);
1320 }
1321
1322 assembler->Bind(&init_k_heap_num);
1323 {
1324 Label do_return_false(assembler);
1325 Node* fp_len = assembler->ChangeInt32ToFloat64(len_var.value());
1326 Node* fp_n = assembler->LoadHeapNumberValue(tagged_n);
1327 assembler->GotoIf(assembler->Float64GreaterThanOrEqual(fp_n, fp_len),
1328 &do_return_false);
1329 start_from_var.Bind(assembler->TruncateFloat64ToWord32(fp_n));
1330 assembler->Goto(&init_k_n);
1331
1332 assembler->Bind(&do_return_false);
1333 {
1334 index_var.Bind(int32_zero);
1335 assembler->Goto(&return_false);
1336 }
1337 }
1338
1339 assembler->Bind(&init_k_n);
1340 {
1341 Label if_positive(assembler), if_negative(assembler), done(assembler);
1342 assembler->Branch(
1343 assembler->Int32LessThan(start_from_var.value(), int32_zero),
1344 &if_negative, &if_positive);
1345
1346 assembler->Bind(&if_positive);
1347 {
1348 index_var.Bind(start_from_var.value());
1349 assembler->Goto(&done);
1350 }
1351
1352 assembler->Bind(&if_negative);
1353 {
1354 index_var.Bind(
1355 assembler->Int32Add(len_var.value(), start_from_var.value()));
1356 assembler->Branch(
1357 assembler->Int32LessThan(index_var.value(), int32_zero),
1358 &init_k_zero, &done);
1359 }
1360
1361 assembler->Bind(&init_k_zero);
1362 {
1363 index_var.Bind(int32_zero);
1364 assembler->Goto(&done);
1365 }
1366
1367 assembler->Bind(&done);
1368 }
1369 }
1370
1371 static int32_t kElementsKind[] = {
1372 FAST_SMI_ELEMENTS, FAST_HOLEY_SMI_ELEMENTS, FAST_ELEMENTS,
1373 FAST_HOLEY_ELEMENTS, FAST_DOUBLE_ELEMENTS, FAST_HOLEY_DOUBLE_ELEMENTS,
1374 };
1375
1376 Label if_smiorobjects(assembler), if_packed_doubles(assembler),
1377 if_holey_doubles(assembler);
1378 Label* element_kind_handlers[] = {&if_smiorobjects, &if_smiorobjects,
1379 &if_smiorobjects, &if_smiorobjects,
1380 &if_packed_doubles, &if_holey_doubles};
1381
1382 Node* map = assembler->LoadMap(array);
1383 Node* bit_field2 = assembler->LoadMapBitField2(map);
1384 Node* elements_kind =
1385 assembler->BitFieldDecode<Map::ElementsKindBits>(bit_field2);
1386 Node* elements = assembler->LoadElements(array);
1387 assembler->Switch(elements_kind, &return_false, kElementsKind,
1388 element_kind_handlers, arraysize(kElementsKind));
1389
1390 assembler->Bind(&if_smiorobjects);
1391 {
1392 Variable search_num(assembler, MachineRepresentation::kFloat64);
1393 Label ident_loop(assembler, &index_var),
1394 heap_num_loop(assembler, &search_num),
1395 string_loop(assembler, &index_var), simd_loop(assembler),
1396 undef_loop(assembler, &index_var), not_smi(assembler),
1397 not_heap_num(assembler);
1398
1399 assembler->GotoUnless(assembler->WordIsSmi(search_element), &not_smi);
1400 search_num.Bind(assembler->SmiToFloat64(search_element));
1401 assembler->Goto(&heap_num_loop);
1402
1403 assembler->Bind(&not_smi);
1404 assembler->GotoIf(assembler->WordEqual(search_element, undefined),
1405 &undef_loop);
1406 Node* map = assembler->LoadMap(search_element);
1407 assembler->GotoIf(assembler->WordNotEqual(map, heap_number_map),
1408 &not_heap_num);
1409 search_num.Bind(assembler->LoadHeapNumberValue(search_element));
1410 assembler->Goto(&heap_num_loop);
1411
1412 assembler->Bind(&not_heap_num);
1413 Node* search_type = assembler->LoadMapInstanceType(map);
1414 assembler->GotoIf(
1415 assembler->Int32LessThan(
1416 search_type, assembler->Int32Constant(FIRST_NONSTRING_TYPE)),
1417 &string_loop);
1418 assembler->GotoIf(
1419 assembler->WordEqual(search_type,
1420 assembler->Int32Constant(SIMD128_VALUE_TYPE)),
1421 &simd_loop);
1422 assembler->Goto(&ident_loop);
1423
1424 assembler->Bind(&ident_loop);
1425 {
1426 assembler->GotoUnless(
1427 assembler->Int32LessThan(index_var.value(), len_var.value()),
1428 &return_false);
1429 Node* element_k =
1430 assembler->LoadFixedArrayElement(elements, index_var.value());
1431 assembler->GotoIf(assembler->WordEqual(element_k, search_element),
1432 &return_true);
1433
1434 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1435 assembler->Goto(&ident_loop);
1436 }
1437
1438 assembler->Bind(&undef_loop);
1439 {
1440 assembler->GotoUnless(
1441 assembler->Int32LessThan(index_var.value(), len_var.value()),
1442 &return_false);
1443 Node* element_k =
1444 assembler->LoadFixedArrayElement(elements, index_var.value());
1445 assembler->GotoIf(assembler->WordEqual(element_k, undefined),
1446 &return_true);
1447 assembler->GotoIf(assembler->WordEqual(element_k, the_hole),
1448 &return_true);
1449
1450 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1451 assembler->Goto(&undef_loop);
1452 }
1453
1454 assembler->Bind(&heap_num_loop);
1455 {
1456 Label nan_loop(assembler, &index_var),
1457 not_nan_loop(assembler, &index_var);
1458 assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop,
1459 &not_nan_loop);
1460
1461 assembler->Bind(&not_nan_loop);
1462 {
1463 Label continue_loop(assembler), not_smi(assembler);
1464 assembler->GotoUnless(
1465 assembler->Int32LessThan(index_var.value(), len_var.value()),
1466 &return_false);
1467 Node* element_k =
1468 assembler->LoadFixedArrayElement(elements, index_var.value());
1469 assembler->GotoUnless(assembler->WordIsSmi(element_k), &not_smi);
1470 assembler->Branch(
1471 assembler->Float64Equal(search_num.value(),
1472 assembler->SmiToFloat64(element_k)),
1473 &return_true, &continue_loop);
1474
1475 assembler->Bind(&not_smi);
1476 assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k),
1477 heap_number_map),
1478 &continue_loop);
1479 assembler->BranchIfFloat64Equal(
1480 search_num.value(), assembler->LoadHeapNumberValue(element_k),
1481 &return_true, &continue_loop);
1482
1483 assembler->Bind(&continue_loop);
1484 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1485 assembler->Goto(&not_nan_loop);
1486 }
1487
1488 assembler->Bind(&nan_loop);
1489 {
1490 Label continue_loop(assembler);
1491 assembler->GotoUnless(
1492 assembler->Int32LessThan(index_var.value(), len_var.value()),
1493 &return_false);
1494 Node* element_k =
1495 assembler->LoadFixedArrayElement(elements, index_var.value());
1496 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop);
1497 assembler->GotoIf(assembler->WordNotEqual(assembler->LoadMap(element_k),
1498 heap_number_map),
1499 &continue_loop);
1500 assembler->BranchIfFloat64IsNaN(
1501 assembler->LoadHeapNumberValue(element_k), &return_true,
1502 &continue_loop);
1503
1504 assembler->Bind(&continue_loop);
1505 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1506 assembler->Goto(&nan_loop);
1507 }
1508 }
1509
1510 assembler->Bind(&string_loop);
1511 {
1512 Label continue_loop(assembler);
1513 assembler->GotoUnless(
1514 assembler->Int32LessThan(index_var.value(), len_var.value()),
1515 &return_false);
1516 Node* element_k =
1517 assembler->LoadFixedArrayElement(elements, index_var.value());
1518 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop);
1519 assembler->GotoUnless(assembler->Int32LessThan(
1520 assembler->LoadMapInstanceType(element_k),
1521 assembler->Int32Constant(FIRST_NONSTRING_TYPE)),
1522 &continue_loop);
1523
1524 // TODO(bmeurer): Consider inlining the StringEqual logic here.
1525 Callable callable = CodeFactory::StringEqual(assembler->isolate());
1526 Node* result =
1527 assembler->CallStub(callable, context, search_element, element_k);
1528 assembler->Branch(
1529 assembler->WordEqual(assembler->BooleanConstant(true), result),
1530 &return_true, &continue_loop);
1531
1532 assembler->Bind(&continue_loop);
1533 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1534 assembler->Goto(&string_loop);
1535 }
1536
1537 assembler->Bind(&simd_loop);
1538 {
1539 Label continue_loop(assembler, &index_var),
1540 loop_body(assembler, &index_var);
1541 Node* map = assembler->LoadMap(search_element);
1542
1543 assembler->Goto(&loop_body);
1544 assembler->Bind(&loop_body);
1545 assembler->GotoUnless(
1546 assembler->Int32LessThan(index_var.value(), len_var.value()),
1547 &return_false);
1548
1549 Node* element_k =
1550 assembler->LoadFixedArrayElement(elements, index_var.value());
1551 assembler->GotoIf(assembler->WordIsSmi(element_k), &continue_loop);
1552
1553 Node* map_k = assembler->LoadMap(element_k);
1554 assembler->BranchIfSimd128Equal(search_element, map, element_k, map_k,
1555 &return_true, &continue_loop);
1556
1557 assembler->Bind(&continue_loop);
1558 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1559 assembler->Goto(&loop_body);
1560 }
1561 }
1562
1563 assembler->Bind(&if_packed_doubles);
1564 {
1565 Label nan_loop(assembler, &index_var), not_nan_loop(assembler, &index_var),
1566 hole_loop(assembler, &index_var), search_notnan(assembler);
1567 Variable search_num(assembler, MachineRepresentation::kFloat64);
1568
1569 assembler->GotoUnless(assembler->WordIsSmi(search_element), &search_notnan);
1570 search_num.Bind(assembler->SmiToFloat64(search_element));
1571 assembler->Goto(&not_nan_loop);
1572
1573 assembler->Bind(&search_notnan);
1574 assembler->GotoIf(assembler->WordNotEqual(
1575 assembler->LoadMap(search_element), heap_number_map),
1576 &return_false);
1577
1578 search_num.Bind(assembler->LoadHeapNumberValue(search_element));
1579
1580 assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop,
1581 &not_nan_loop);
1582
1583 // Search for HeapNumber
1584 assembler->Bind(&not_nan_loop);
1585 {
1586 Label continue_loop(assembler);
1587 assembler->GotoUnless(
1588 assembler->Int32LessThan(index_var.value(), len_var.value()),
1589 &return_false);
1590 Node* element_k = assembler->LoadFixedDoubleArrayElement(
1591 elements, index_var.value(), MachineType::Float64());
1592 assembler->BranchIfFloat64Equal(element_k, search_num.value(),
1593 &return_true, &continue_loop);
1594 assembler->Bind(&continue_loop);
1595 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1596 assembler->Goto(&not_nan_loop);
1597 }
1598
1599 // Search for NaN
1600 assembler->Bind(&nan_loop);
1601 {
1602 Label continue_loop(assembler);
1603 assembler->GotoUnless(
1604 assembler->Int32LessThan(index_var.value(), len_var.value()),
1605 &return_false);
1606 Node* element_k = assembler->LoadFixedDoubleArrayElement(
1607 elements, index_var.value(), MachineType::Float64());
1608 assembler->BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop);
1609 assembler->Bind(&continue_loop);
1610 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1611 assembler->Goto(&nan_loop);
1612 }
1613 }
1614
1615 assembler->Bind(&if_holey_doubles);
1616 {
1617 Label nan_loop(assembler, &index_var), not_nan_loop(assembler, &index_var),
1618 hole_loop(assembler, &index_var), search_notnan(assembler);
1619 Variable search_num(assembler, MachineRepresentation::kFloat64);
1620
1621 assembler->GotoUnless(assembler->WordIsSmi(search_element), &search_notnan);
1622 search_num.Bind(assembler->SmiToFloat64(search_element));
1623 assembler->Goto(&not_nan_loop);
1624
1625 assembler->Bind(&search_notnan);
1626 assembler->GotoIf(assembler->WordEqual(search_element, undefined),
1627 &hole_loop);
1628 assembler->GotoIf(assembler->WordNotEqual(
1629 assembler->LoadMap(search_element), heap_number_map),
1630 &return_false);
1631
1632 search_num.Bind(assembler->LoadHeapNumberValue(search_element));
1633
1634 assembler->BranchIfFloat64IsNaN(search_num.value(), &nan_loop,
1635 &not_nan_loop);
1636
1637 // Search for HeapNumber
1638 assembler->Bind(&not_nan_loop);
1639 {
1640 Label continue_loop(assembler);
1641 assembler->GotoUnless(
1642 assembler->Int32LessThan(index_var.value(), len_var.value()),
1643 &return_false);
1644
1645 if (kPointerSize == kDoubleSize) {
1646 Node* element = assembler->LoadFixedDoubleArrayElement(
1647 elements, index_var.value(), MachineType::Uint64());
1648 Node* the_hole = assembler->Int64Constant(kHoleNanInt64);
1649 assembler->GotoIf(assembler->Word64Equal(element, the_hole),
1650 &continue_loop);
1651 } else {
1652 Node* element_upper = assembler->LoadFixedDoubleArrayElement(
1653 elements, index_var.value(), MachineType::Uint32(),
1654 kIeeeDoubleExponentWordOffset);
1655 assembler->GotoIf(
1656 assembler->Word32Equal(element_upper,
1657 assembler->Int32Constant(kHoleNanUpper32)),
1658 &continue_loop);
1659 }
1660
1661 Node* element_k = assembler->LoadFixedDoubleArrayElement(
1662 elements, index_var.value(), MachineType::Float64());
1663 assembler->BranchIfFloat64Equal(element_k, search_num.value(),
1664 &return_true, &continue_loop);
1665 assembler->Bind(&continue_loop);
1666 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1667 assembler->Goto(&not_nan_loop);
1668 }
1669
1670 // Search for NaN
1671 assembler->Bind(&nan_loop);
1672 {
1673 Label continue_loop(assembler);
1674 assembler->GotoUnless(
1675 assembler->Int32LessThan(index_var.value(), len_var.value()),
1676 &return_false);
1677
1678 if (kPointerSize == kDoubleSize) {
1679 Node* element = assembler->LoadFixedDoubleArrayElement(
1680 elements, index_var.value(), MachineType::Uint64());
1681 Node* the_hole = assembler->Int64Constant(kHoleNanInt64);
1682 assembler->GotoIf(assembler->Word64Equal(element, the_hole),
1683 &continue_loop);
1684 } else {
1685 Node* element_upper = assembler->LoadFixedDoubleArrayElement(
1686 elements, index_var.value(), MachineType::Uint32(),
1687 kIeeeDoubleExponentWordOffset);
1688 assembler->GotoIf(
1689 assembler->Word32Equal(element_upper,
1690 assembler->Int32Constant(kHoleNanUpper32)),
1691 &continue_loop);
1692 }
1693
1694 Node* element_k = assembler->LoadFixedDoubleArrayElement(
1695 elements, index_var.value(), MachineType::Float64());
1696 assembler->BranchIfFloat64IsNaN(element_k, &return_true, &continue_loop);
1697 assembler->Bind(&continue_loop);
1698 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1699 assembler->Goto(&nan_loop);
1700 }
1701
1702 // Search for the Hole
1703 assembler->Bind(&hole_loop);
1704 {
1705 assembler->GotoUnless(
1706 assembler->Int32LessThan(index_var.value(), len_var.value()),
1707 &return_false);
1708
1709 if (kPointerSize == kDoubleSize) {
1710 Node* element = assembler->LoadFixedDoubleArrayElement(
1711 elements, index_var.value(), MachineType::Uint64());
1712 Node* the_hole = assembler->Int64Constant(kHoleNanInt64);
1713 assembler->GotoIf(assembler->Word64Equal(element, the_hole),
1714 &return_true);
1715 } else {
1716 Node* element_upper = assembler->LoadFixedDoubleArrayElement(
1717 elements, index_var.value(), MachineType::Uint32(),
1718 kIeeeDoubleExponentWordOffset);
1719 assembler->GotoIf(
1720 assembler->Word32Equal(element_upper,
1721 assembler->Int32Constant(kHoleNanUpper32)),
1722 &return_true);
1723 }
1724
1725 index_var.Bind(assembler->Int32Add(index_var.value(), int32_one));
1726 assembler->Goto(&hole_loop);
1727 }
1728 }
1729
1730 assembler->Bind(&return_true);
1731 assembler->Return(assembler->BooleanConstant(true));
1732
1733 assembler->Bind(&return_false);
1734 assembler->Return(assembler->BooleanConstant(false));
1735
1736 assembler->Bind(&call_runtime);
1737 assembler->Return(assembler->CallRuntime(Runtime::kArrayIncludes_Slow,
1738 context, array, search_element,
1739 start_from));
1740 }
1741
1274 } // namespace internal 1742 } // namespace internal
1275 } // namespace v8 1743 } // namespace v8
OLDNEW
« no previous file with comments | « src/builtins/builtins.h ('k') | src/code-stub-assembler.h » ('j') | src/code-stub-assembler.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698