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

Side by Side Diff: src/hydrogen.cc

Issue 78213002: Replace unsafe uses of Add<> with AddUncasted<>. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1294 1294
1295 HValue* current_capacity = AddLoadFixedArrayLength(elements); 1295 HValue* current_capacity = AddLoadFixedArrayLength(elements);
1296 1296
1297 IfBuilder capacity_checker(this); 1297 IfBuilder capacity_checker(this);
1298 1298
1299 capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity, 1299 capacity_checker.If<HCompareNumericAndBranch>(key, current_capacity,
1300 Token::GTE); 1300 Token::GTE);
1301 capacity_checker.Then(); 1301 capacity_checker.Then();
1302 1302
1303 HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap)); 1303 HValue* max_gap = Add<HConstant>(static_cast<int32_t>(JSObject::kMaxGap));
1304 HValue* max_capacity = Add<HAdd>(current_capacity, max_gap); 1304 HValue* max_capacity = AddUncasted<HAdd>(current_capacity, max_gap);
1305 IfBuilder key_checker(this); 1305 IfBuilder key_checker(this);
1306 key_checker.If<HCompareNumericAndBranch>(key, max_capacity, Token::LT); 1306 key_checker.If<HCompareNumericAndBranch>(key, max_capacity, Token::LT);
1307 key_checker.Then(); 1307 key_checker.Then();
1308 key_checker.ElseDeopt("Key out of capacity range"); 1308 key_checker.ElseDeopt("Key out of capacity range");
1309 key_checker.End(); 1309 key_checker.End();
1310 1310
1311 HValue* new_capacity = BuildNewElementsCapacity(key); 1311 HValue* new_capacity = BuildNewElementsCapacity(key);
1312 HValue* new_elements = BuildGrowElementsCapacity(object, elements, 1312 HValue* new_elements = BuildGrowElementsCapacity(object, elements,
1313 kind, kind, length, 1313 kind, kind, length,
1314 new_capacity); 1314 new_capacity);
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
1411 HValue* hash, 1411 HValue* hash,
1412 HValue* mask, 1412 HValue* mask,
1413 int current_probe) { 1413 int current_probe) {
1414 if (current_probe == kNumberDictionaryProbes) { 1414 if (current_probe == kNumberDictionaryProbes) {
1415 return NULL; 1415 return NULL;
1416 } 1416 }
1417 1417
1418 int32_t offset = SeededNumberDictionary::GetProbeOffset(current_probe); 1418 int32_t offset = SeededNumberDictionary::GetProbeOffset(current_probe);
1419 HValue* raw_index = (current_probe == 0) 1419 HValue* raw_index = (current_probe == 0)
1420 ? hash 1420 ? hash
1421 : Add<HAdd>(hash, Add<HConstant>(offset)); 1421 : AddUncasted<HAdd>(hash, Add<HConstant>(offset));
1422 raw_index = Add<HBitwise>(Token::BIT_AND, raw_index, mask); 1422 raw_index = AddUncasted<HBitwise>(Token::BIT_AND, raw_index, mask);
1423 int32_t entry_size = SeededNumberDictionary::kEntrySize; 1423 int32_t entry_size = SeededNumberDictionary::kEntrySize;
1424 raw_index = Add<HMul>(raw_index, Add<HConstant>(entry_size)); 1424 raw_index = AddUncasted<HMul>(raw_index, Add<HConstant>(entry_size));
1425 raw_index->ClearFlag(HValue::kCanOverflow); 1425 raw_index->ClearFlag(HValue::kCanOverflow);
1426 1426
1427 int32_t base_offset = SeededNumberDictionary::kElementsStartIndex; 1427 int32_t base_offset = SeededNumberDictionary::kElementsStartIndex;
1428 HValue* key_index = Add<HAdd>(raw_index, Add<HConstant>(base_offset)); 1428 HValue* key_index = AddUncasted<HAdd>(raw_index, Add<HConstant>(base_offset));
1429 key_index->ClearFlag(HValue::kCanOverflow); 1429 key_index->ClearFlag(HValue::kCanOverflow);
1430 1430
1431 HValue* candidate_key = Add<HLoadKeyed>(elements, key_index, 1431 HValue* candidate_key = Add<HLoadKeyed>(elements, key_index,
1432 static_cast<HValue*>(NULL), 1432 static_cast<HValue*>(NULL),
1433 FAST_SMI_ELEMENTS); 1433 FAST_SMI_ELEMENTS);
1434 1434
1435 IfBuilder key_compare(this); 1435 IfBuilder key_compare(this);
1436 key_compare.IfNot<HCompareObjectEqAndBranch>(key, candidate_key); 1436 key_compare.IfNot<HCompareObjectEqAndBranch>(key, candidate_key);
1437 key_compare.Then(); 1437 key_compare.Then();
1438 { 1438 {
1439 // Key at the current probe doesn't match, try at the next probe. 1439 // Key at the current probe doesn't match, try at the next probe.
1440 HValue* result = BuildUncheckedDictionaryElementLoadHelper( 1440 HValue* result = BuildUncheckedDictionaryElementLoadHelper(
1441 elements, key, hash, mask, current_probe + 1); 1441 elements, key, hash, mask, current_probe + 1);
1442 if (result == NULL) { 1442 if (result == NULL) {
1443 key_compare.Deopt("probes exhausted in keyed load dictionary lookup"); 1443 key_compare.Deopt("probes exhausted in keyed load dictionary lookup");
1444 result = graph()->GetConstantUndefined(); 1444 result = graph()->GetConstantUndefined();
1445 } else { 1445 } else {
1446 Push(result); 1446 Push(result);
1447 } 1447 }
1448 } 1448 }
1449 key_compare.Else(); 1449 key_compare.Else();
1450 { 1450 {
1451 // Key at current probe matches. Details must be zero, otherwise the 1451 // Key at current probe matches. Details must be zero, otherwise the
1452 // dictionary element requires special handling. 1452 // dictionary element requires special handling.
1453 HValue* details_index = Add<HAdd>(raw_index, 1453 HValue* details_index = AddUncasted<HAdd>(
1454 Add<HConstant>(base_offset + 2)); 1454 raw_index, Add<HConstant>(base_offset + 2));
1455 details_index->ClearFlag(HValue::kCanOverflow); 1455 details_index->ClearFlag(HValue::kCanOverflow);
1456 1456
1457 HValue* details = Add<HLoadKeyed>(elements, details_index, 1457 HValue* details = Add<HLoadKeyed>(elements, details_index,
1458 static_cast<HValue*>(NULL), 1458 static_cast<HValue*>(NULL),
1459 FAST_SMI_ELEMENTS); 1459 FAST_SMI_ELEMENTS);
1460 IfBuilder details_compare(this); 1460 IfBuilder details_compare(this);
1461 details_compare.If<HCompareNumericAndBranch>(details, 1461 details_compare.If<HCompareNumericAndBranch>(details,
1462 graph()->GetConstant0(), 1462 graph()->GetConstant0(),
1463 Token::NE); 1463 Token::NE);
1464 details_compare.ThenDeopt("keyed load dictionary element not fast case"); 1464 details_compare.ThenDeopt("keyed load dictionary element not fast case");
1465 1465
1466 details_compare.Else(); 1466 details_compare.Else();
1467 { 1467 {
1468 // Key matches and details are zero --> fast case. Load and return the 1468 // Key matches and details are zero --> fast case. Load and return the
1469 // value. 1469 // value.
1470 HValue* result_index = Add<HAdd>(raw_index, 1470 HValue* result_index = AddUncasted<HAdd>(
1471 Add<HConstant>(base_offset + 1)); 1471 raw_index, Add<HConstant>(base_offset + 1));
1472 result_index->ClearFlag(HValue::kCanOverflow); 1472 result_index->ClearFlag(HValue::kCanOverflow);
1473 1473
1474 Push(Add<HLoadKeyed>(elements, result_index, 1474 Push(Add<HLoadKeyed>(elements, result_index,
1475 static_cast<HValue*>(NULL), 1475 static_cast<HValue*>(NULL),
1476 FAST_ELEMENTS)); 1476 FAST_ELEMENTS));
1477 } 1477 }
1478 details_compare.End(); 1478 details_compare.End();
1479 } 1479 }
1480 key_compare.End(); 1480 key_compare.End();
1481 1481
1482 return Pop(); 1482 return Pop();
1483 } 1483 }
1484 1484
1485 1485
1486 HValue* HGraphBuilder::BuildElementIndexHash(HValue* index) { 1486 HValue* HGraphBuilder::BuildElementIndexHash(HValue* index) {
1487 int32_t seed_value = static_cast<uint32_t>(isolate()->heap()->HashSeed()); 1487 int32_t seed_value = static_cast<uint32_t>(isolate()->heap()->HashSeed());
1488 HValue* seed = Add<HConstant>(seed_value); 1488 HValue* seed = Add<HConstant>(seed_value);
1489 HValue* hash = Add<HBitwise>(Token::BIT_XOR, index, seed); 1489 HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, index, seed);
1490 1490
1491 // hash = ~hash + (hash << 15); 1491 // hash = ~hash + (hash << 15);
1492 HValue* shifted_hash = Add<HShl>(hash, Add<HConstant>(15)); 1492 HValue* shifted_hash = AddUncasted<HShl>(hash, Add<HConstant>(15));
1493 HValue* not_hash = Add<HBitwise>(Token::BIT_XOR, hash, 1493 HValue* not_hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash,
1494 graph()->GetConstantMinus1()); 1494 graph()->GetConstantMinus1());
1495 hash = Add<HAdd>(shifted_hash, not_hash); 1495 hash = AddUncasted<HAdd>(shifted_hash, not_hash);
1496 1496
1497 // hash = hash ^ (hash >> 12); 1497 // hash = hash ^ (hash >> 12);
1498 shifted_hash = Add<HShr>(hash, Add<HConstant>(12)); 1498 shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(12));
1499 hash = Add<HBitwise>(Token::BIT_XOR, hash, shifted_hash); 1499 hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash);
1500 1500
1501 // hash = hash + (hash << 2); 1501 // hash = hash + (hash << 2);
1502 shifted_hash = Add<HShl>(hash, Add<HConstant>(2)); 1502 shifted_hash = AddUncasted<HShl>(hash, Add<HConstant>(2));
1503 hash = Add<HAdd>(hash, shifted_hash); 1503 hash = AddUncasted<HAdd>(hash, shifted_hash);
1504 1504
1505 // hash = hash ^ (hash >> 4); 1505 // hash = hash ^ (hash >> 4);
1506 shifted_hash = Add<HShr>(hash, Add<HConstant>(4)); 1506 shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(4));
1507 hash = Add<HBitwise>(Token::BIT_XOR, hash, shifted_hash); 1507 hash = AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash);
1508 1508
1509 // hash = hash * 2057; 1509 // hash = hash * 2057;
1510 hash = Add<HMul>(hash, Add<HConstant>(2057)); 1510 hash = AddUncasted<HMul>(hash, Add<HConstant>(2057));
1511 hash->ClearFlag(HValue::kCanOverflow); 1511 hash->ClearFlag(HValue::kCanOverflow);
1512 1512
1513 // hash = hash ^ (hash >> 16); 1513 // hash = hash ^ (hash >> 16);
1514 shifted_hash = Add<HShr>(hash, Add<HConstant>(16)); 1514 shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16));
1515 return Add<HBitwise>(Token::BIT_XOR, hash, shifted_hash); 1515 return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash);
1516 } 1516 }
1517 1517
1518 1518
1519 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver, 1519 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver,
1520 HValue* key) { 1520 HValue* key) {
1521 HValue* elements = AddLoadElements(receiver); 1521 HValue* elements = AddLoadElements(receiver);
1522 1522
1523 HValue* hash = BuildElementIndexHash(key); 1523 HValue* hash = BuildElementIndexHash(key);
1524 1524
1525 HValue* capacity = Add<HLoadKeyed>( 1525 HValue* capacity = Add<HLoadKeyed>(
(...skipping 29 matching lines...) Expand all
1555 mask->set_type(HType::Smi()); 1555 mask->set_type(HType::Smi());
1556 mask = Add<HSar>(mask, graph()->GetConstant1()); 1556 mask = Add<HSar>(mask, graph()->GetConstant1());
1557 mask = Add<HSub>(mask, graph()->GetConstant1()); 1557 mask = Add<HSub>(mask, graph()->GetConstant1());
1558 1558
1559 // Check whether object is a smi. 1559 // Check whether object is a smi.
1560 IfBuilder if_objectissmi(this); 1560 IfBuilder if_objectissmi(this);
1561 if_objectissmi.If<HIsSmiAndBranch>(object); 1561 if_objectissmi.If<HIsSmiAndBranch>(object);
1562 if_objectissmi.Then(); 1562 if_objectissmi.Then();
1563 { 1563 {
1564 // Compute hash for smi similar to smi_get_hash(). 1564 // Compute hash for smi similar to smi_get_hash().
1565 HValue* hash = Add<HBitwise>(Token::BIT_AND, object, mask); 1565 HValue* hash = AddUncasted<HBitwise>(Token::BIT_AND, object, mask);
1566 1566
1567 // Load the key. 1567 // Load the key.
1568 HValue* key_index = Add<HShl>(hash, graph()->GetConstant1()); 1568 HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1());
1569 HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, 1569 HValue* key = Add<HLoadKeyed>(number_string_cache, key_index,
1570 static_cast<HValue*>(NULL), 1570 static_cast<HValue*>(NULL),
1571 FAST_ELEMENTS, ALLOW_RETURN_HOLE); 1571 FAST_ELEMENTS, ALLOW_RETURN_HOLE);
1572 1572
1573 // Check if object == key. 1573 // Check if object == key.
1574 IfBuilder if_objectiskey(this); 1574 IfBuilder if_objectiskey(this);
1575 if_objectiskey.If<HCompareObjectEqAndBranch>(object, key); 1575 if_objectiskey.If<HCompareObjectEqAndBranch>(object, key);
1576 if_objectiskey.Then(); 1576 if_objectiskey.Then();
1577 { 1577 {
1578 // Make the key_index available. 1578 // Make the key_index available.
(...skipping 10 matching lines...) Expand all
1589 IfBuilder if_objectisnumber(this); 1589 IfBuilder if_objectisnumber(this);
1590 if_objectisnumber.If<HCompareMap>( 1590 if_objectisnumber.If<HCompareMap>(
1591 object, isolate()->factory()->heap_number_map()); 1591 object, isolate()->factory()->heap_number_map());
1592 if_objectisnumber.Then(); 1592 if_objectisnumber.Then();
1593 { 1593 {
1594 // Compute hash for heap number similar to double_get_hash(). 1594 // Compute hash for heap number similar to double_get_hash().
1595 HValue* low = Add<HLoadNamedField>( 1595 HValue* low = Add<HLoadNamedField>(
1596 object, HObjectAccess::ForHeapNumberValueLowestBits()); 1596 object, HObjectAccess::ForHeapNumberValueLowestBits());
1597 HValue* high = Add<HLoadNamedField>( 1597 HValue* high = Add<HLoadNamedField>(
1598 object, HObjectAccess::ForHeapNumberValueHighestBits()); 1598 object, HObjectAccess::ForHeapNumberValueHighestBits());
1599 HValue* hash = Add<HBitwise>(Token::BIT_XOR, low, high); 1599 HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high);
1600 hash = Add<HBitwise>(Token::BIT_AND, hash, mask); 1600 hash = AddUncasted<HBitwise>(Token::BIT_AND, hash, mask);
1601 1601
1602 // Load the key. 1602 // Load the key.
1603 HValue* key_index = Add<HShl>(hash, graph()->GetConstant1()); 1603 HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1());
1604 HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, 1604 HValue* key = Add<HLoadKeyed>(number_string_cache, key_index,
1605 static_cast<HValue*>(NULL), 1605 static_cast<HValue*>(NULL),
1606 FAST_ELEMENTS, ALLOW_RETURN_HOLE); 1606 FAST_ELEMENTS, ALLOW_RETURN_HOLE);
1607 1607
1608 // Check if key is a heap number (the number string cache contains only 1608 // Check if key is a heap number (the number string cache contains only
1609 // SMIs and heap number, so it is sufficient to do a SMI check here). 1609 // SMIs and heap number, so it is sufficient to do a SMI check here).
1610 IfBuilder if_keyisnotsmi(this); 1610 IfBuilder if_keyisnotsmi(this);
1611 if_keyisnotsmi.IfNot<HIsSmiAndBranch>(key); 1611 if_keyisnotsmi.IfNot<HIsSmiAndBranch>(key);
1612 if_keyisnotsmi.Then(); 1612 if_keyisnotsmi.Then();
1613 { 1613 {
(...skipping 25 matching lines...) Expand all
1639 1639
1640 // Check for cache hit. 1640 // Check for cache hit.
1641 IfBuilder if_found(this, &found); 1641 IfBuilder if_found(this, &found);
1642 if_found.Then(); 1642 if_found.Then();
1643 { 1643 {
1644 // Count number to string operation in native code. 1644 // Count number to string operation in native code.
1645 AddIncrementCounter(isolate()->counters()->number_to_string_native()); 1645 AddIncrementCounter(isolate()->counters()->number_to_string_native());
1646 1646
1647 // Load the value in case of cache hit. 1647 // Load the value in case of cache hit.
1648 HValue* key_index = Pop(); 1648 HValue* key_index = Pop();
1649 HValue* value_index = Add<HAdd>(key_index, graph()->GetConstant1()); 1649 HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1());
1650 Push(Add<HLoadKeyed>(number_string_cache, value_index, 1650 Push(Add<HLoadKeyed>(number_string_cache, value_index,
1651 static_cast<HValue*>(NULL), 1651 static_cast<HValue*>(NULL),
1652 FAST_ELEMENTS, ALLOW_RETURN_HOLE)); 1652 FAST_ELEMENTS, ALLOW_RETURN_HOLE));
1653 } 1653 }
1654 if_found.Else(); 1654 if_found.Else();
1655 { 1655 {
1656 // Cache miss, fallback to runtime. 1656 // Cache miss, fallback to runtime.
1657 Add<HPushArgument>(object); 1657 Add<HPushArgument>(object);
1658 Push(Add<HCallRuntime>( 1658 Push(Add<HCallRuntime>(
1659 isolate()->factory()->empty_string(), 1659 isolate()->factory()->empty_string(),
1660 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), 1660 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache),
1661 1)); 1661 1));
1662 } 1662 }
1663 if_found.End(); 1663 if_found.End();
1664 1664
1665 return Pop(); 1665 return Pop();
1666 } 1666 }
1667 1667
1668 1668
1669 HValue* HGraphBuilder::BuildSeqStringSizeFor(HValue* length, 1669 HValue* HGraphBuilder::BuildSeqStringSizeFor(HValue* length,
1670 String::Encoding encoding) { 1670 String::Encoding encoding) {
1671 STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0); 1671 STATIC_ASSERT((SeqString::kHeaderSize & kObjectAlignmentMask) == 0);
1672 HValue* size = length; 1672 HValue* size = length;
1673 if (encoding == String::TWO_BYTE_ENCODING) { 1673 if (encoding == String::TWO_BYTE_ENCODING) {
1674 size = Add<HShl>(length, graph()->GetConstant1()); 1674 size = AddUncasted<HShl>(length, graph()->GetConstant1());
1675 size->ClearFlag(HValue::kCanOverflow); 1675 size->ClearFlag(HValue::kCanOverflow);
1676 size->SetFlag(HValue::kUint32); 1676 size->SetFlag(HValue::kUint32);
1677 } 1677 }
1678 size = Add<HAdd>(size, Add<HConstant>(static_cast<int32_t>( 1678 size = AddUncasted<HAdd>(size, Add<HConstant>(static_cast<int32_t>(
1679 SeqString::kHeaderSize + kObjectAlignmentMask))); 1679 SeqString::kHeaderSize + kObjectAlignmentMask)));
1680 size->ClearFlag(HValue::kCanOverflow); 1680 size->ClearFlag(HValue::kCanOverflow);
1681 size = Add<HBitwise>( 1681 size = AddUncasted<HBitwise>(
1682 Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>( 1682 Token::BIT_AND, size, Add<HConstant>(static_cast<int32_t>(
1683 ~kObjectAlignmentMask))); 1683 ~kObjectAlignmentMask)));
1684 return size; 1684 return size;
1685 } 1685 }
1686 1686
1687 1687
1688 void HGraphBuilder::BuildCopySeqStringChars(HValue* src, 1688 void HGraphBuilder::BuildCopySeqStringChars(HValue* src,
1689 HValue* src_offset, 1689 HValue* src_offset,
1690 String::Encoding src_encoding, 1690 String::Encoding src_encoding,
1691 HValue* dst, 1691 HValue* dst,
1692 HValue* dst_offset, 1692 HValue* dst_offset,
1693 String::Encoding dst_encoding, 1693 String::Encoding dst_encoding,
1694 HValue* length) { 1694 HValue* length) {
1695 ASSERT(dst_encoding != String::ONE_BYTE_ENCODING || 1695 ASSERT(dst_encoding != String::ONE_BYTE_ENCODING ||
1696 src_encoding == String::ONE_BYTE_ENCODING); 1696 src_encoding == String::ONE_BYTE_ENCODING);
1697 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement); 1697 LoopBuilder loop(this, context(), LoopBuilder::kPostIncrement);
1698 HValue* index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT); 1698 HValue* index = loop.BeginBody(graph()->GetConstant0(), length, Token::LT);
1699 { 1699 {
1700 HValue* src_index = Add<HAdd>(src_offset, index); 1700 HValue* src_index = AddUncasted<HAdd>(src_offset, index);
1701 HValue* value = Add<HSeqStringGetChar>(src_encoding, src, src_index); 1701 HValue* value = Add<HSeqStringGetChar>(src_encoding, src, src_index);
1702 HValue* dst_index = Add<HAdd>(dst_offset, index); 1702 HValue* dst_index = AddUncasted<HAdd>(dst_offset, index);
1703 Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value); 1703 Add<HSeqStringSetChar>(dst_encoding, dst, dst_index, value);
1704 } 1704 }
1705 loop.EndBody(); 1705 loop.EndBody();
1706 } 1706 }
1707 1707
1708 1708
1709 HValue* HGraphBuilder::BuildUncheckedStringAdd(HValue* left, 1709 HValue* HGraphBuilder::BuildUncheckedStringAdd(HValue* left,
1710 HValue* right, 1710 HValue* right,
1711 PretenureFlag pretenure_flag) { 1711 PretenureFlag pretenure_flag) {
1712 // Determine the string lengths. 1712 // Determine the string lengths.
(...skipping 24 matching lines...) Expand all
1737 { 1737 {
1738 // Determine the string instance types. 1738 // Determine the string instance types.
1739 HLoadNamedField* left_instance_type = Add<HLoadNamedField>( 1739 HLoadNamedField* left_instance_type = Add<HLoadNamedField>(
1740 Add<HLoadNamedField>(left, HObjectAccess::ForMap()), 1740 Add<HLoadNamedField>(left, HObjectAccess::ForMap()),
1741 HObjectAccess::ForMapInstanceType()); 1741 HObjectAccess::ForMapInstanceType());
1742 HLoadNamedField* right_instance_type = Add<HLoadNamedField>( 1742 HLoadNamedField* right_instance_type = Add<HLoadNamedField>(
1743 Add<HLoadNamedField>(right, HObjectAccess::ForMap()), 1743 Add<HLoadNamedField>(right, HObjectAccess::ForMap()),
1744 HObjectAccess::ForMapInstanceType()); 1744 HObjectAccess::ForMapInstanceType());
1745 1745
1746 // Compute difference of instance types. 1746 // Compute difference of instance types.
1747 HValue* xored_instance_types = Add<HBitwise>( 1747 HValue* xored_instance_types = AddUncasted<HBitwise>(
1748 Token::BIT_XOR, left_instance_type, right_instance_type); 1748 Token::BIT_XOR, left_instance_type, right_instance_type);
1749 1749
1750 // Compute the length of the resulting string. 1750 // Compute the length of the resulting string.
1751 HValue* length = Add<HAdd>(left_length, right_length); 1751 HValue* length = AddUncasted<HAdd>(left_length, right_length);
1752 1752
1753 // Check if we should create a cons string. 1753 // Check if we should create a cons string.
1754 IfBuilder if_createcons(this); 1754 IfBuilder if_createcons(this);
1755 if_createcons.If<HCompareNumericAndBranch>( 1755 if_createcons.If<HCompareNumericAndBranch>(
1756 length, Add<HConstant>(ConsString::kMinLength), Token::GTE); 1756 length, Add<HConstant>(ConsString::kMinLength), Token::GTE);
1757 if_createcons.Then(); 1757 if_createcons.Then();
1758 { 1758 {
1759 // Allocate the cons string object. HAllocate does not care whether we 1759 // Allocate the cons string object. HAllocate does not care whether we
1760 // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use 1760 // pass CONS_STRING_TYPE or CONS_ASCII_STRING_TYPE here, so we just use
1761 // CONS_STRING_TYPE here. Below we decide whether the cons string is 1761 // CONS_STRING_TYPE here. Below we decide whether the cons string is
1762 // one-byte or two-byte and set the appropriate map. 1762 // one-byte or two-byte and set the appropriate map.
1763 HAllocate* string = Add<HAllocate>(Add<HConstant>(ConsString::kSize), 1763 HAllocate* string = Add<HAllocate>(Add<HConstant>(ConsString::kSize),
1764 HType::String(), pretenure_flag, 1764 HType::String(), pretenure_flag,
1765 CONS_STRING_TYPE); 1765 CONS_STRING_TYPE);
1766 1766
1767 // Compute the intersection of instance types. 1767 // Compute the intersection of instance types.
1768 HValue* anded_instance_types = Add<HBitwise>( 1768 HValue* anded_instance_types = AddUncasted<HBitwise>(
1769 Token::BIT_AND, left_instance_type, right_instance_type); 1769 Token::BIT_AND, left_instance_type, right_instance_type);
1770 1770
1771 // We create a one-byte cons string if 1771 // We create a one-byte cons string if
1772 // 1. both strings are one-byte, or 1772 // 1. both strings are one-byte, or
1773 // 2. at least one of the strings is two-byte, but happens to contain only 1773 // 2. at least one of the strings is two-byte, but happens to contain only
1774 // one-byte characters. 1774 // one-byte characters.
1775 // To do this, we check 1775 // To do this, we check
1776 // 1. if both strings are one-byte, or if the one-byte data hint is set in 1776 // 1. if both strings are one-byte, or if the one-byte data hint is set in
1777 // both strings, or 1777 // both strings, or
1778 // 2. if one of the strings has the one-byte data hint set and the other 1778 // 2. if one of the strings has the one-byte data hint set and the other
1779 // string is one-byte. 1779 // string is one-byte.
1780 IfBuilder if_onebyte(this); 1780 IfBuilder if_onebyte(this);
1781 STATIC_ASSERT(kOneByteStringTag != 0); 1781 STATIC_ASSERT(kOneByteStringTag != 0);
1782 STATIC_ASSERT(kOneByteDataHintMask != 0); 1782 STATIC_ASSERT(kOneByteDataHintMask != 0);
1783 if_onebyte.If<HCompareNumericAndBranch>( 1783 if_onebyte.If<HCompareNumericAndBranch>(
1784 Add<HBitwise>( 1784 AddUncasted<HBitwise>(
1785 Token::BIT_AND, anded_instance_types, 1785 Token::BIT_AND, anded_instance_types,
1786 Add<HConstant>(static_cast<int32_t>( 1786 Add<HConstant>(static_cast<int32_t>(
1787 kStringEncodingMask | kOneByteDataHintMask))), 1787 kStringEncodingMask | kOneByteDataHintMask))),
1788 graph()->GetConstant0(), Token::NE); 1788 graph()->GetConstant0(), Token::NE);
1789 if_onebyte.Or(); 1789 if_onebyte.Or();
1790 STATIC_ASSERT(kOneByteStringTag != 0 && 1790 STATIC_ASSERT(kOneByteStringTag != 0 &&
1791 kOneByteDataHintTag != 0 && 1791 kOneByteDataHintTag != 0 &&
1792 kOneByteDataHintTag != kOneByteStringTag); 1792 kOneByteDataHintTag != kOneByteStringTag);
1793 if_onebyte.If<HCompareNumericAndBranch>( 1793 if_onebyte.If<HCompareNumericAndBranch>(
1794 Add<HBitwise>( 1794 AddUncasted<HBitwise>(
1795 Token::BIT_AND, xored_instance_types, 1795 Token::BIT_AND, xored_instance_types,
1796 Add<HConstant>(static_cast<int32_t>( 1796 Add<HConstant>(static_cast<int32_t>(
1797 kOneByteStringTag | kOneByteDataHintTag))), 1797 kOneByteStringTag | kOneByteDataHintTag))),
1798 Add<HConstant>(static_cast<int32_t>( 1798 Add<HConstant>(static_cast<int32_t>(
1799 kOneByteStringTag | kOneByteDataHintTag)), Token::EQ); 1799 kOneByteStringTag | kOneByteDataHintTag)), Token::EQ);
1800 if_onebyte.Then(); 1800 if_onebyte.Then();
1801 { 1801 {
1802 // We can safely skip the write barrier for storing the map here. 1802 // We can safely skip the write barrier for storing the map here.
1803 Handle<Map> map = isolate()->factory()->cons_ascii_string_map(); 1803 Handle<Map> map = isolate()->factory()->cons_ascii_string_map();
1804 AddStoreMapConstantNoWriteBarrier(string, map); 1804 AddStoreMapConstantNoWriteBarrier(string, map);
(...skipping 13 matching lines...) Expand all
1818 Add<HStoreNamedField>(string, HObjectAccess::ForConsStringFirst(), left); 1818 Add<HStoreNamedField>(string, HObjectAccess::ForConsStringFirst(), left);
1819 Add<HStoreNamedField>(string, HObjectAccess::ForConsStringSecond(), 1819 Add<HStoreNamedField>(string, HObjectAccess::ForConsStringSecond(),
1820 right); 1820 right);
1821 1821
1822 // Cons string is result. 1822 // Cons string is result.
1823 Push(string); 1823 Push(string);
1824 } 1824 }
1825 if_createcons.Else(); 1825 if_createcons.Else();
1826 { 1826 {
1827 // Compute union of instance types. 1827 // Compute union of instance types.
1828 HValue* ored_instance_types = Add<HBitwise>( 1828 HValue* ored_instance_types = AddUncasted<HBitwise>(
1829 Token::BIT_OR, left_instance_type, right_instance_type); 1829 Token::BIT_OR, left_instance_type, right_instance_type);
1830 1830
1831 // Check if both strings have the same encoding and both are 1831 // Check if both strings have the same encoding and both are
1832 // sequential. 1832 // sequential.
1833 IfBuilder if_sameencodingandsequential(this); 1833 IfBuilder if_sameencodingandsequential(this);
1834 if_sameencodingandsequential.If<HCompareNumericAndBranch>( 1834 if_sameencodingandsequential.If<HCompareNumericAndBranch>(
1835 Add<HBitwise>( 1835 AddUncasted<HBitwise>(
1836 Token::BIT_AND, xored_instance_types, 1836 Token::BIT_AND, xored_instance_types,
1837 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))), 1837 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))),
1838 graph()->GetConstant0(), Token::EQ); 1838 graph()->GetConstant0(), Token::EQ);
1839 if_sameencodingandsequential.And(); 1839 if_sameencodingandsequential.And();
1840 STATIC_ASSERT(kSeqStringTag == 0); 1840 STATIC_ASSERT(kSeqStringTag == 0);
1841 if_sameencodingandsequential.If<HCompareNumericAndBranch>( 1841 if_sameencodingandsequential.If<HCompareNumericAndBranch>(
1842 Add<HBitwise>( 1842 AddUncasted<HBitwise>(
1843 Token::BIT_AND, ored_instance_types, 1843 Token::BIT_AND, ored_instance_types,
1844 Add<HConstant>(static_cast<int32_t>(kStringRepresentationMask))), 1844 Add<HConstant>(static_cast<int32_t>(kStringRepresentationMask))),
1845 graph()->GetConstant0(), Token::EQ); 1845 graph()->GetConstant0(), Token::EQ);
1846 if_sameencodingandsequential.Then(); 1846 if_sameencodingandsequential.Then();
1847 { 1847 {
1848 // Check if the result is a one-byte string. 1848 // Check if the result is a one-byte string.
1849 IfBuilder if_onebyte(this); 1849 IfBuilder if_onebyte(this);
1850 STATIC_ASSERT(kOneByteStringTag != 0); 1850 STATIC_ASSERT(kOneByteStringTag != 0);
1851 if_onebyte.If<HCompareNumericAndBranch>( 1851 if_onebyte.If<HCompareNumericAndBranch>(
1852 Add<HBitwise>( 1852 AddUncasted<HBitwise>(
1853 Token::BIT_AND, ored_instance_types, 1853 Token::BIT_AND, ored_instance_types,
1854 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))), 1854 Add<HConstant>(static_cast<int32_t>(kStringEncodingMask))),
1855 graph()->GetConstant0(), Token::NE); 1855 graph()->GetConstant0(), Token::NE);
1856 if_onebyte.Then(); 1856 if_onebyte.Then();
1857 { 1857 {
1858 // Calculate the number of bytes needed for the characters in the 1858 // Calculate the number of bytes needed for the characters in the
1859 // string while observing object alignment. 1859 // string while observing object alignment.
1860 HValue* size = BuildSeqStringSizeFor( 1860 HValue* size = BuildSeqStringSizeFor(
1861 length, String::ONE_BYTE_ENCODING); 1861 length, String::ONE_BYTE_ENCODING);
1862 1862
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
2165 2165
2166 if (IsFastDoubleElementsKind(kind)) { 2166 if (IsFastDoubleElementsKind(kind)) {
2167 elements_size = kDoubleSize; 2167 elements_size = kDoubleSize;
2168 instance_type = FIXED_DOUBLE_ARRAY_TYPE; 2168 instance_type = FIXED_DOUBLE_ARRAY_TYPE;
2169 } else { 2169 } else {
2170 elements_size = kPointerSize; 2170 elements_size = kPointerSize;
2171 instance_type = FIXED_ARRAY_TYPE; 2171 instance_type = FIXED_ARRAY_TYPE;
2172 } 2172 }
2173 2173
2174 HConstant* elements_size_value = Add<HConstant>(elements_size); 2174 HConstant* elements_size_value = Add<HConstant>(elements_size);
2175 HValue* mul = Add<HMul>(capacity, elements_size_value); 2175 HValue* mul = AddUncasted<HMul>(capacity, elements_size_value);
2176 mul->ClearFlag(HValue::kCanOverflow); 2176 mul->ClearFlag(HValue::kCanOverflow);
2177 2177
2178 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize); 2178 HConstant* header_size = Add<HConstant>(FixedArray::kHeaderSize);
2179 HValue* total_size = Add<HAdd>(mul, header_size); 2179 HValue* total_size = AddUncasted<HAdd>(mul, header_size);
2180 total_size->ClearFlag(HValue::kCanOverflow); 2180 total_size->ClearFlag(HValue::kCanOverflow);
2181 2181
2182 return Add<HAllocate>(total_size, HType::JSArray(), 2182 return Add<HAllocate>(total_size, HType::JSArray(),
2183 isolate()->heap()->GetPretenureMode(), instance_type); 2183 isolate()->heap()->GetPretenureMode(), instance_type);
2184 } 2184 }
2185 2185
2186 2186
2187 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements, 2187 void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements,
2188 ElementsKind kind, 2188 ElementsKind kind,
2189 HValue* capacity) { 2189 HValue* capacity) {
(...skipping 2307 matching lines...) Expand 10 before | Expand all | Expand 10 after
4497 BreakAndContinueInfo break_info(stmt, 5); 4497 BreakAndContinueInfo break_info(stmt, 5);
4498 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info)); 4498 CHECK_BAILOUT(VisitLoopBody(stmt, loop_entry, &break_info));
4499 4499
4500 HBasicBlock* body_exit = 4500 HBasicBlock* body_exit =
4501 JoinContinue(stmt, current_block(), break_info.continue_block()); 4501 JoinContinue(stmt, current_block(), break_info.continue_block());
4502 4502
4503 if (body_exit != NULL) { 4503 if (body_exit != NULL) {
4504 set_current_block(body_exit); 4504 set_current_block(body_exit);
4505 4505
4506 HValue* current_index = Pop(); 4506 HValue* current_index = Pop();
4507 Push(Add<HAdd>(current_index, graph()->GetConstant1())); 4507 Push(AddUncasted<HAdd>(current_index, graph()->GetConstant1()));
4508 body_exit = current_block(); 4508 body_exit = current_block();
4509 } 4509 }
4510 4510
4511 HBasicBlock* loop_exit = CreateLoop(stmt, 4511 HBasicBlock* loop_exit = CreateLoop(stmt,
4512 loop_entry, 4512 loop_entry,
4513 body_exit, 4513 body_exit,
4514 loop_successor, 4514 loop_successor,
4515 break_info.break_block()); 4515 break_info.break_block());
4516 4516
4517 set_current_block(loop_exit); 4517 set_current_block(loop_exit);
(...skipping 6115 matching lines...) Expand 10 before | Expand all | Expand 10 after
10633 if (ShouldProduceTraceOutput()) { 10633 if (ShouldProduceTraceOutput()) {
10634 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 10634 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
10635 } 10635 }
10636 10636
10637 #ifdef DEBUG 10637 #ifdef DEBUG
10638 graph_->Verify(false); // No full verify. 10638 graph_->Verify(false); // No full verify.
10639 #endif 10639 #endif
10640 } 10640 }
10641 10641
10642 } } // namespace v8::internal 10642 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698