| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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/hydrogen.h" | 5 #include "src/hydrogen.h" |
| 6 | 6 |
| 7 #include <sstream> | 7 #include <sstream> |
| 8 | 8 |
| 9 #include "src/v8.h" | 9 #include "src/v8.h" |
| 10 | 10 |
| (...skipping 1199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1210 current_block()->FinishExit(instruction, source_position()); | 1210 current_block()->FinishExit(instruction, source_position()); |
| 1211 if (instruction->IsReturn() || instruction->IsAbnormalExit()) { | 1211 if (instruction->IsReturn() || instruction->IsAbnormalExit()) { |
| 1212 set_current_block(NULL); | 1212 set_current_block(NULL); |
| 1213 } | 1213 } |
| 1214 } | 1214 } |
| 1215 | 1215 |
| 1216 | 1216 |
| 1217 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { | 1217 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { |
| 1218 if (FLAG_native_code_counters && counter->Enabled()) { | 1218 if (FLAG_native_code_counters && counter->Enabled()) { |
| 1219 HValue* reference = Add<HConstant>(ExternalReference(counter)); | 1219 HValue* reference = Add<HConstant>(ExternalReference(counter)); |
| 1220 HValue* old_value = Add<HLoadNamedField>( | 1220 HValue* old_value = |
| 1221 reference, static_cast<HValue*>(NULL), HObjectAccess::ForCounter()); | 1221 Add<HLoadNamedField>(reference, nullptr, HObjectAccess::ForCounter()); |
| 1222 HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1()); | 1222 HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1()); |
| 1223 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow | 1223 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow |
| 1224 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), | 1224 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), |
| 1225 new_value, STORE_TO_INITIALIZED_ENTRY); | 1225 new_value, STORE_TO_INITIALIZED_ENTRY); |
| 1226 } | 1226 } |
| 1227 } | 1227 } |
| 1228 | 1228 |
| 1229 | 1229 |
| 1230 void HGraphBuilder::AddSimulate(BailoutId id, | 1230 void HGraphBuilder::AddSimulate(BailoutId id, |
| 1231 RemovableSimulate removable) { | 1231 RemovableSimulate removable) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1245 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { | 1245 HBasicBlock* HGraphBuilder::CreateLoopHeaderBlock() { |
| 1246 HBasicBlock* header = graph()->CreateBasicBlock(); | 1246 HBasicBlock* header = graph()->CreateBasicBlock(); |
| 1247 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); | 1247 HEnvironment* entry_env = environment()->CopyAsLoopHeader(header); |
| 1248 header->SetInitialEnvironment(entry_env); | 1248 header->SetInitialEnvironment(entry_env); |
| 1249 header->AttachLoopInformation(); | 1249 header->AttachLoopInformation(); |
| 1250 return header; | 1250 return header; |
| 1251 } | 1251 } |
| 1252 | 1252 |
| 1253 | 1253 |
| 1254 HValue* HGraphBuilder::BuildGetElementsKind(HValue* object) { | 1254 HValue* HGraphBuilder::BuildGetElementsKind(HValue* object) { |
| 1255 HValue* map = Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), | 1255 HValue* map = Add<HLoadNamedField>(object, nullptr, HObjectAccess::ForMap()); |
| 1256 HObjectAccess::ForMap()); | |
| 1257 | 1256 |
| 1258 HValue* bit_field2 = Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), | 1257 HValue* bit_field2 = |
| 1259 HObjectAccess::ForMapBitField2()); | 1258 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField2()); |
| 1260 return BuildDecodeField<Map::ElementsKindBits>(bit_field2); | 1259 return BuildDecodeField<Map::ElementsKindBits>(bit_field2); |
| 1261 } | 1260 } |
| 1262 | 1261 |
| 1263 | 1262 |
| 1264 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { | 1263 HValue* HGraphBuilder::BuildCheckHeapObject(HValue* obj) { |
| 1265 if (obj->type().IsHeapObject()) return obj; | 1264 if (obj->type().IsHeapObject()) return obj; |
| 1266 return Add<HCheckHeapObject>(obj); | 1265 return Add<HCheckHeapObject>(obj); |
| 1267 } | 1266 } |
| 1268 | 1267 |
| 1269 | 1268 |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1408 isolate()->factory()->empty_fixed_array()); | 1407 isolate()->factory()->empty_fixed_array()); |
| 1409 | 1408 |
| 1410 IfBuilder if_builder(this); | 1409 IfBuilder if_builder(this); |
| 1411 | 1410 |
| 1412 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array); | 1411 if_builder.IfNot<HCompareObjectEqAndBranch>(elements, empty_fixed_array); |
| 1413 | 1412 |
| 1414 if_builder.Then(); | 1413 if_builder.Then(); |
| 1415 | 1414 |
| 1416 HInstruction* elements_length = AddLoadFixedArrayLength(elements); | 1415 HInstruction* elements_length = AddLoadFixedArrayLength(elements); |
| 1417 | 1416 |
| 1418 HInstruction* array_length = is_jsarray | 1417 HInstruction* array_length = |
| 1419 ? Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), | 1418 is_jsarray |
| 1420 HObjectAccess::ForArrayLength(from_kind)) | 1419 ? Add<HLoadNamedField>(object, nullptr, |
| 1421 : elements_length; | 1420 HObjectAccess::ForArrayLength(from_kind)) |
| 1421 : elements_length; |
| 1422 | 1422 |
| 1423 BuildGrowElementsCapacity(object, elements, from_kind, to_kind, | 1423 BuildGrowElementsCapacity(object, elements, from_kind, to_kind, |
| 1424 array_length, elements_length); | 1424 array_length, elements_length); |
| 1425 | 1425 |
| 1426 if_builder.End(); | 1426 if_builder.End(); |
| 1427 } | 1427 } |
| 1428 | 1428 |
| 1429 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map); | 1429 Add<HStoreNamedField>(object, HObjectAccess::ForMap(), map); |
| 1430 } | 1430 } |
| 1431 | 1431 |
| 1432 | 1432 |
| 1433 void HGraphBuilder::BuildJSObjectCheck(HValue* receiver, | 1433 void HGraphBuilder::BuildJSObjectCheck(HValue* receiver, |
| 1434 int bit_field_mask) { | 1434 int bit_field_mask) { |
| 1435 // Check that the object isn't a smi. | 1435 // Check that the object isn't a smi. |
| 1436 Add<HCheckHeapObject>(receiver); | 1436 Add<HCheckHeapObject>(receiver); |
| 1437 | 1437 |
| 1438 // Get the map of the receiver. | 1438 // Get the map of the receiver. |
| 1439 HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | 1439 HValue* map = |
| 1440 HObjectAccess::ForMap()); | 1440 Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap()); |
| 1441 | 1441 |
| 1442 // Check the instance type and if an access check is needed, this can be | 1442 // Check the instance type and if an access check is needed, this can be |
| 1443 // done with a single load, since both bytes are adjacent in the map. | 1443 // done with a single load, since both bytes are adjacent in the map. |
| 1444 HObjectAccess access(HObjectAccess::ForMapInstanceTypeAndBitField()); | 1444 HObjectAccess access(HObjectAccess::ForMapInstanceTypeAndBitField()); |
| 1445 HValue* instance_type_and_bit_field = | 1445 HValue* instance_type_and_bit_field = |
| 1446 Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), access); | 1446 Add<HLoadNamedField>(map, nullptr, access); |
| 1447 | 1447 |
| 1448 HValue* mask = Add<HConstant>(0x00FF | (bit_field_mask << 8)); | 1448 HValue* mask = Add<HConstant>(0x00FF | (bit_field_mask << 8)); |
| 1449 HValue* and_result = AddUncasted<HBitwise>(Token::BIT_AND, | 1449 HValue* and_result = AddUncasted<HBitwise>(Token::BIT_AND, |
| 1450 instance_type_and_bit_field, | 1450 instance_type_and_bit_field, |
| 1451 mask); | 1451 mask); |
| 1452 HValue* sub_result = AddUncasted<HSub>(and_result, | 1452 HValue* sub_result = AddUncasted<HSub>(and_result, |
| 1453 Add<HConstant>(JS_OBJECT_TYPE)); | 1453 Add<HConstant>(JS_OBJECT_TYPE)); |
| 1454 Add<HBoundsCheck>(sub_result, | 1454 Add<HBoundsCheck>(sub_result, |
| 1455 Add<HConstant>(LAST_JS_OBJECT_TYPE + 1 - JS_OBJECT_TYPE)); | 1455 Add<HConstant>(LAST_JS_OBJECT_TYPE + 1 - JS_OBJECT_TYPE)); |
| 1456 } | 1456 } |
| 1457 | 1457 |
| 1458 | 1458 |
| 1459 void HGraphBuilder::BuildKeyedIndexCheck(HValue* key, | 1459 void HGraphBuilder::BuildKeyedIndexCheck(HValue* key, |
| 1460 HIfContinuation* join_continuation) { | 1460 HIfContinuation* join_continuation) { |
| 1461 // The sometimes unintuitively backward ordering of the ifs below is | 1461 // The sometimes unintuitively backward ordering of the ifs below is |
| 1462 // convoluted, but necessary. All of the paths must guarantee that the | 1462 // convoluted, but necessary. All of the paths must guarantee that the |
| 1463 // if-true of the continuation returns a smi element index and the if-false of | 1463 // if-true of the continuation returns a smi element index and the if-false of |
| 1464 // the continuation returns either a symbol or a unique string key. All other | 1464 // the continuation returns either a symbol or a unique string key. All other |
| 1465 // object types cause a deopt to fall back to the runtime. | 1465 // object types cause a deopt to fall back to the runtime. |
| 1466 | 1466 |
| 1467 IfBuilder key_smi_if(this); | 1467 IfBuilder key_smi_if(this); |
| 1468 key_smi_if.If<HIsSmiAndBranch>(key); | 1468 key_smi_if.If<HIsSmiAndBranch>(key); |
| 1469 key_smi_if.Then(); | 1469 key_smi_if.Then(); |
| 1470 { | 1470 { |
| 1471 Push(key); // Nothing to do, just continue to true of continuation. | 1471 Push(key); // Nothing to do, just continue to true of continuation. |
| 1472 } | 1472 } |
| 1473 key_smi_if.Else(); | 1473 key_smi_if.Else(); |
| 1474 { | 1474 { |
| 1475 HValue* map = Add<HLoadNamedField>(key, static_cast<HValue*>(NULL), | 1475 HValue* map = Add<HLoadNamedField>(key, nullptr, HObjectAccess::ForMap()); |
| 1476 HObjectAccess::ForMap()); | |
| 1477 HValue* instance_type = | 1476 HValue* instance_type = |
| 1478 Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), | 1477 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType()); |
| 1479 HObjectAccess::ForMapInstanceType()); | |
| 1480 | 1478 |
| 1481 // Non-unique string, check for a string with a hash code that is actually | 1479 // Non-unique string, check for a string with a hash code that is actually |
| 1482 // an index. | 1480 // an index. |
| 1483 STATIC_ASSERT(LAST_UNIQUE_NAME_TYPE == FIRST_NONSTRING_TYPE); | 1481 STATIC_ASSERT(LAST_UNIQUE_NAME_TYPE == FIRST_NONSTRING_TYPE); |
| 1484 IfBuilder not_string_or_name_if(this); | 1482 IfBuilder not_string_or_name_if(this); |
| 1485 not_string_or_name_if.If<HCompareNumericAndBranch>( | 1483 not_string_or_name_if.If<HCompareNumericAndBranch>( |
| 1486 instance_type, | 1484 instance_type, |
| 1487 Add<HConstant>(LAST_UNIQUE_NAME_TYPE), | 1485 Add<HConstant>(LAST_UNIQUE_NAME_TYPE), |
| 1488 Token::GT); | 1486 Token::GT); |
| 1489 | 1487 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1501 IfBuilder not_symbol_if(this); | 1499 IfBuilder not_symbol_if(this); |
| 1502 not_symbol_if.If<HCompareNumericAndBranch>( | 1500 not_symbol_if.If<HCompareNumericAndBranch>( |
| 1503 instance_type, | 1501 instance_type, |
| 1504 Add<HConstant>(SYMBOL_TYPE), | 1502 Add<HConstant>(SYMBOL_TYPE), |
| 1505 Token::NE); | 1503 Token::NE); |
| 1506 | 1504 |
| 1507 not_symbol_if.Then(); | 1505 not_symbol_if.Then(); |
| 1508 { | 1506 { |
| 1509 // String: check whether the String is a String of an index. If it is, | 1507 // String: check whether the String is a String of an index. If it is, |
| 1510 // extract the index value from the hash. | 1508 // extract the index value from the hash. |
| 1511 HValue* hash = | 1509 HValue* hash = Add<HLoadNamedField>(key, nullptr, |
| 1512 Add<HLoadNamedField>(key, static_cast<HValue*>(NULL), | 1510 HObjectAccess::ForNameHashField()); |
| 1513 HObjectAccess::ForNameHashField()); | |
| 1514 HValue* not_index_mask = Add<HConstant>(static_cast<int>( | 1511 HValue* not_index_mask = Add<HConstant>(static_cast<int>( |
| 1515 String::kContainsCachedArrayIndexMask)); | 1512 String::kContainsCachedArrayIndexMask)); |
| 1516 | 1513 |
| 1517 HValue* not_index_test = AddUncasted<HBitwise>( | 1514 HValue* not_index_test = AddUncasted<HBitwise>( |
| 1518 Token::BIT_AND, hash, not_index_mask); | 1515 Token::BIT_AND, hash, not_index_mask); |
| 1519 | 1516 |
| 1520 IfBuilder string_index_if(this); | 1517 IfBuilder string_index_if(this); |
| 1521 string_index_if.If<HCompareNumericAndBranch>(not_index_test, | 1518 string_index_if.If<HCompareNumericAndBranch>(not_index_test, |
| 1522 graph()->GetConstant0(), | 1519 graph()->GetConstant0(), |
| 1523 Token::EQ); | 1520 Token::EQ); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1562 } | 1559 } |
| 1563 not_string_or_name_if.JoinContinuation(join_continuation); | 1560 not_string_or_name_if.JoinContinuation(join_continuation); |
| 1564 } | 1561 } |
| 1565 key_smi_if.JoinContinuation(join_continuation); | 1562 key_smi_if.JoinContinuation(join_continuation); |
| 1566 } | 1563 } |
| 1567 | 1564 |
| 1568 | 1565 |
| 1569 void HGraphBuilder::BuildNonGlobalObjectCheck(HValue* receiver) { | 1566 void HGraphBuilder::BuildNonGlobalObjectCheck(HValue* receiver) { |
| 1570 // Get the the instance type of the receiver, and make sure that it is | 1567 // Get the the instance type of the receiver, and make sure that it is |
| 1571 // not one of the global object types. | 1568 // not one of the global object types. |
| 1572 HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | 1569 HValue* map = |
| 1573 HObjectAccess::ForMap()); | 1570 Add<HLoadNamedField>(receiver, nullptr, HObjectAccess::ForMap()); |
| 1574 HValue* instance_type = | 1571 HValue* instance_type = |
| 1575 Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), | 1572 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType()); |
| 1576 HObjectAccess::ForMapInstanceType()); | |
| 1577 STATIC_ASSERT(JS_BUILTINS_OBJECT_TYPE == JS_GLOBAL_OBJECT_TYPE + 1); | 1573 STATIC_ASSERT(JS_BUILTINS_OBJECT_TYPE == JS_GLOBAL_OBJECT_TYPE + 1); |
| 1578 HValue* min_global_type = Add<HConstant>(JS_GLOBAL_OBJECT_TYPE); | 1574 HValue* min_global_type = Add<HConstant>(JS_GLOBAL_OBJECT_TYPE); |
| 1579 HValue* max_global_type = Add<HConstant>(JS_BUILTINS_OBJECT_TYPE); | 1575 HValue* max_global_type = Add<HConstant>(JS_BUILTINS_OBJECT_TYPE); |
| 1580 | 1576 |
| 1581 IfBuilder if_global_object(this); | 1577 IfBuilder if_global_object(this); |
| 1582 if_global_object.If<HCompareNumericAndBranch>(instance_type, | 1578 if_global_object.If<HCompareNumericAndBranch>(instance_type, |
| 1583 max_global_type, | 1579 max_global_type, |
| 1584 Token::LTE); | 1580 Token::LTE); |
| 1585 if_global_object.And(); | 1581 if_global_object.And(); |
| 1586 if_global_object.If<HCompareNumericAndBranch>(instance_type, | 1582 if_global_object.If<HCompareNumericAndBranch>(instance_type, |
| 1587 min_global_type, | 1583 min_global_type, |
| 1588 Token::GTE); | 1584 Token::GTE); |
| 1589 if_global_object.ThenDeopt("receiver was a global object"); | 1585 if_global_object.ThenDeopt("receiver was a global object"); |
| 1590 if_global_object.End(); | 1586 if_global_object.End(); |
| 1591 } | 1587 } |
| 1592 | 1588 |
| 1593 | 1589 |
| 1594 void HGraphBuilder::BuildTestForDictionaryProperties( | 1590 void HGraphBuilder::BuildTestForDictionaryProperties( |
| 1595 HValue* object, | 1591 HValue* object, |
| 1596 HIfContinuation* continuation) { | 1592 HIfContinuation* continuation) { |
| 1597 HValue* properties = Add<HLoadNamedField>( | 1593 HValue* properties = Add<HLoadNamedField>( |
| 1598 object, static_cast<HValue*>(NULL), | 1594 object, nullptr, HObjectAccess::ForPropertiesPointer()); |
| 1599 HObjectAccess::ForPropertiesPointer()); | |
| 1600 HValue* properties_map = | 1595 HValue* properties_map = |
| 1601 Add<HLoadNamedField>(properties, static_cast<HValue*>(NULL), | 1596 Add<HLoadNamedField>(properties, nullptr, HObjectAccess::ForMap()); |
| 1602 HObjectAccess::ForMap()); | |
| 1603 HValue* hash_map = Add<HLoadRoot>(Heap::kHashTableMapRootIndex); | 1597 HValue* hash_map = Add<HLoadRoot>(Heap::kHashTableMapRootIndex); |
| 1604 IfBuilder builder(this); | 1598 IfBuilder builder(this); |
| 1605 builder.If<HCompareObjectEqAndBranch>(properties_map, hash_map); | 1599 builder.If<HCompareObjectEqAndBranch>(properties_map, hash_map); |
| 1606 builder.CaptureContinuation(continuation); | 1600 builder.CaptureContinuation(continuation); |
| 1607 } | 1601 } |
| 1608 | 1602 |
| 1609 | 1603 |
| 1610 HValue* HGraphBuilder::BuildKeyedLookupCacheHash(HValue* object, | 1604 HValue* HGraphBuilder::BuildKeyedLookupCacheHash(HValue* object, |
| 1611 HValue* key) { | 1605 HValue* key) { |
| 1612 // Load the map of the receiver, compute the keyed lookup cache hash | 1606 // Load the map of the receiver, compute the keyed lookup cache hash |
| 1613 // based on 32 bits of the map pointer and the string hash. | 1607 // based on 32 bits of the map pointer and the string hash. |
| 1614 HValue* object_map = | 1608 HValue* object_map = |
| 1615 Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), | 1609 Add<HLoadNamedField>(object, nullptr, HObjectAccess::ForMapAsInteger32()); |
| 1616 HObjectAccess::ForMapAsInteger32()); | |
| 1617 HValue* shifted_map = AddUncasted<HShr>( | 1610 HValue* shifted_map = AddUncasted<HShr>( |
| 1618 object_map, Add<HConstant>(KeyedLookupCache::kMapHashShift)); | 1611 object_map, Add<HConstant>(KeyedLookupCache::kMapHashShift)); |
| 1619 HValue* string_hash = | 1612 HValue* string_hash = |
| 1620 Add<HLoadNamedField>(key, static_cast<HValue*>(NULL), | 1613 Add<HLoadNamedField>(key, nullptr, HObjectAccess::ForStringHashField()); |
| 1621 HObjectAccess::ForStringHashField()); | |
| 1622 HValue* shifted_hash = AddUncasted<HShr>( | 1614 HValue* shifted_hash = AddUncasted<HShr>( |
| 1623 string_hash, Add<HConstant>(String::kHashShift)); | 1615 string_hash, Add<HConstant>(String::kHashShift)); |
| 1624 HValue* xor_result = AddUncasted<HBitwise>(Token::BIT_XOR, shifted_map, | 1616 HValue* xor_result = AddUncasted<HBitwise>(Token::BIT_XOR, shifted_map, |
| 1625 shifted_hash); | 1617 shifted_hash); |
| 1626 int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask); | 1618 int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask); |
| 1627 return AddUncasted<HBitwise>(Token::BIT_AND, xor_result, | 1619 return AddUncasted<HBitwise>(Token::BIT_AND, xor_result, |
| 1628 Add<HConstant>(mask)); | 1620 Add<HConstant>(mask)); |
| 1629 } | 1621 } |
| 1630 | 1622 |
| 1631 | 1623 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1659 // hash = hash ^ (hash >> 16); | 1651 // hash = hash ^ (hash >> 16); |
| 1660 shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16)); | 1652 shifted_hash = AddUncasted<HShr>(hash, Add<HConstant>(16)); |
| 1661 return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); | 1653 return AddUncasted<HBitwise>(Token::BIT_XOR, hash, shifted_hash); |
| 1662 } | 1654 } |
| 1663 | 1655 |
| 1664 | 1656 |
| 1665 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver, | 1657 HValue* HGraphBuilder::BuildUncheckedDictionaryElementLoad(HValue* receiver, |
| 1666 HValue* elements, | 1658 HValue* elements, |
| 1667 HValue* key, | 1659 HValue* key, |
| 1668 HValue* hash) { | 1660 HValue* hash) { |
| 1669 HValue* capacity = Add<HLoadKeyed>( | 1661 HValue* capacity = |
| 1670 elements, | 1662 Add<HLoadKeyed>(elements, Add<HConstant>(NameDictionary::kCapacityIndex), |
| 1671 Add<HConstant>(NameDictionary::kCapacityIndex), | 1663 nullptr, FAST_ELEMENTS); |
| 1672 static_cast<HValue*>(NULL), | |
| 1673 FAST_ELEMENTS); | |
| 1674 | 1664 |
| 1675 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); | 1665 HValue* mask = AddUncasted<HSub>(capacity, graph()->GetConstant1()); |
| 1676 mask->ChangeRepresentation(Representation::Integer32()); | 1666 mask->ChangeRepresentation(Representation::Integer32()); |
| 1677 mask->ClearFlag(HValue::kCanOverflow); | 1667 mask->ClearFlag(HValue::kCanOverflow); |
| 1678 | 1668 |
| 1679 HValue* entry = hash; | 1669 HValue* entry = hash; |
| 1680 HValue* count = graph()->GetConstant1(); | 1670 HValue* count = graph()->GetConstant1(); |
| 1681 Push(entry); | 1671 Push(entry); |
| 1682 Push(count); | 1672 Push(count); |
| 1683 | 1673 |
| 1684 HIfContinuation return_or_loop_continuation(graph()->CreateBasicBlock(), | 1674 HIfContinuation return_or_loop_continuation(graph()->CreateBasicBlock(), |
| 1685 graph()->CreateBasicBlock()); | 1675 graph()->CreateBasicBlock()); |
| 1686 HIfContinuation found_key_match_continuation(graph()->CreateBasicBlock(), | 1676 HIfContinuation found_key_match_continuation(graph()->CreateBasicBlock(), |
| 1687 graph()->CreateBasicBlock()); | 1677 graph()->CreateBasicBlock()); |
| 1688 LoopBuilder probe_loop(this); | 1678 LoopBuilder probe_loop(this); |
| 1689 probe_loop.BeginBody(2); // Drop entry, count from last environment to | 1679 probe_loop.BeginBody(2); // Drop entry, count from last environment to |
| 1690 // appease live range building without simulates. | 1680 // appease live range building without simulates. |
| 1691 | 1681 |
| 1692 count = Pop(); | 1682 count = Pop(); |
| 1693 entry = Pop(); | 1683 entry = Pop(); |
| 1694 entry = AddUncasted<HBitwise>(Token::BIT_AND, entry, mask); | 1684 entry = AddUncasted<HBitwise>(Token::BIT_AND, entry, mask); |
| 1695 int entry_size = SeededNumberDictionary::kEntrySize; | 1685 int entry_size = SeededNumberDictionary::kEntrySize; |
| 1696 HValue* base_index = AddUncasted<HMul>(entry, Add<HConstant>(entry_size)); | 1686 HValue* base_index = AddUncasted<HMul>(entry, Add<HConstant>(entry_size)); |
| 1697 base_index->ClearFlag(HValue::kCanOverflow); | 1687 base_index->ClearFlag(HValue::kCanOverflow); |
| 1698 int start_offset = SeededNumberDictionary::kElementsStartIndex; | 1688 int start_offset = SeededNumberDictionary::kElementsStartIndex; |
| 1699 HValue* key_index = | 1689 HValue* key_index = |
| 1700 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset)); | 1690 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset)); |
| 1701 key_index->ClearFlag(HValue::kCanOverflow); | 1691 key_index->ClearFlag(HValue::kCanOverflow); |
| 1702 | 1692 |
| 1703 HValue* candidate_key = Add<HLoadKeyed>( | 1693 HValue* candidate_key = |
| 1704 elements, key_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 1694 Add<HLoadKeyed>(elements, key_index, nullptr, FAST_ELEMENTS); |
| 1705 IfBuilder if_undefined(this); | 1695 IfBuilder if_undefined(this); |
| 1706 if_undefined.If<HCompareObjectEqAndBranch>(candidate_key, | 1696 if_undefined.If<HCompareObjectEqAndBranch>(candidate_key, |
| 1707 graph()->GetConstantUndefined()); | 1697 graph()->GetConstantUndefined()); |
| 1708 if_undefined.Then(); | 1698 if_undefined.Then(); |
| 1709 { | 1699 { |
| 1710 // element == undefined means "not found". Call the runtime. | 1700 // element == undefined means "not found". Call the runtime. |
| 1711 // TODO(jkummerow): walk the prototype chain instead. | 1701 // TODO(jkummerow): walk the prototype chain instead. |
| 1712 Add<HPushArguments>(receiver, key); | 1702 Add<HPushArguments>(receiver, key); |
| 1713 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(), | 1703 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(), |
| 1714 Runtime::FunctionForId(Runtime::kKeyedGetProperty), | 1704 Runtime::FunctionForId(Runtime::kKeyedGetProperty), |
| 1715 2)); | 1705 2)); |
| 1716 } | 1706 } |
| 1717 if_undefined.Else(); | 1707 if_undefined.Else(); |
| 1718 { | 1708 { |
| 1719 IfBuilder if_match(this); | 1709 IfBuilder if_match(this); |
| 1720 if_match.If<HCompareObjectEqAndBranch>(candidate_key, key); | 1710 if_match.If<HCompareObjectEqAndBranch>(candidate_key, key); |
| 1721 if_match.Then(); | 1711 if_match.Then(); |
| 1722 if_match.Else(); | 1712 if_match.Else(); |
| 1723 | 1713 |
| 1724 // Update non-internalized string in the dictionary with internalized key? | 1714 // Update non-internalized string in the dictionary with internalized key? |
| 1725 IfBuilder if_update_with_internalized(this); | 1715 IfBuilder if_update_with_internalized(this); |
| 1726 HValue* smi_check = | 1716 HValue* smi_check = |
| 1727 if_update_with_internalized.IfNot<HIsSmiAndBranch>(candidate_key); | 1717 if_update_with_internalized.IfNot<HIsSmiAndBranch>(candidate_key); |
| 1728 if_update_with_internalized.And(); | 1718 if_update_with_internalized.And(); |
| 1729 HValue* map = AddLoadMap(candidate_key, smi_check); | 1719 HValue* map = AddLoadMap(candidate_key, smi_check); |
| 1730 HValue* instance_type = Add<HLoadNamedField>( | 1720 HValue* instance_type = |
| 1731 map, static_cast<HValue*>(NULL), HObjectAccess::ForMapInstanceType()); | 1721 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType()); |
| 1732 HValue* not_internalized_bit = AddUncasted<HBitwise>( | 1722 HValue* not_internalized_bit = AddUncasted<HBitwise>( |
| 1733 Token::BIT_AND, instance_type, | 1723 Token::BIT_AND, instance_type, |
| 1734 Add<HConstant>(static_cast<int>(kIsNotInternalizedMask))); | 1724 Add<HConstant>(static_cast<int>(kIsNotInternalizedMask))); |
| 1735 if_update_with_internalized.If<HCompareNumericAndBranch>( | 1725 if_update_with_internalized.If<HCompareNumericAndBranch>( |
| 1736 not_internalized_bit, graph()->GetConstant0(), Token::NE); | 1726 not_internalized_bit, graph()->GetConstant0(), Token::NE); |
| 1737 if_update_with_internalized.And(); | 1727 if_update_with_internalized.And(); |
| 1738 if_update_with_internalized.IfNot<HCompareObjectEqAndBranch>( | 1728 if_update_with_internalized.IfNot<HCompareObjectEqAndBranch>( |
| 1739 candidate_key, graph()->GetConstantHole()); | 1729 candidate_key, graph()->GetConstantHole()); |
| 1740 if_update_with_internalized.AndIf<HStringCompareAndBranch>(candidate_key, | 1730 if_update_with_internalized.AndIf<HStringCompareAndBranch>(candidate_key, |
| 1741 key, Token::EQ); | 1731 key, Token::EQ); |
| 1742 if_update_with_internalized.Then(); | 1732 if_update_with_internalized.Then(); |
| 1743 // Replace a key that is a non-internalized string by the equivalent | 1733 // Replace a key that is a non-internalized string by the equivalent |
| 1744 // internalized string for faster further lookups. | 1734 // internalized string for faster further lookups. |
| 1745 Add<HStoreKeyed>(elements, key_index, key, FAST_ELEMENTS); | 1735 Add<HStoreKeyed>(elements, key_index, key, FAST_ELEMENTS); |
| 1746 if_update_with_internalized.Else(); | 1736 if_update_with_internalized.Else(); |
| 1747 | 1737 |
| 1748 if_update_with_internalized.JoinContinuation(&found_key_match_continuation); | 1738 if_update_with_internalized.JoinContinuation(&found_key_match_continuation); |
| 1749 if_match.JoinContinuation(&found_key_match_continuation); | 1739 if_match.JoinContinuation(&found_key_match_continuation); |
| 1750 | 1740 |
| 1751 IfBuilder found_key_match(this, &found_key_match_continuation); | 1741 IfBuilder found_key_match(this, &found_key_match_continuation); |
| 1752 found_key_match.Then(); | 1742 found_key_match.Then(); |
| 1753 // Key at current probe matches. Relevant bits in the |details| field must | 1743 // Key at current probe matches. Relevant bits in the |details| field must |
| 1754 // be zero, otherwise the dictionary element requires special handling. | 1744 // be zero, otherwise the dictionary element requires special handling. |
| 1755 HValue* details_index = | 1745 HValue* details_index = |
| 1756 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 2)); | 1746 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 2)); |
| 1757 details_index->ClearFlag(HValue::kCanOverflow); | 1747 details_index->ClearFlag(HValue::kCanOverflow); |
| 1758 HValue* details = Add<HLoadKeyed>( | 1748 HValue* details = |
| 1759 elements, details_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 1749 Add<HLoadKeyed>(elements, details_index, nullptr, FAST_ELEMENTS); |
| 1760 int details_mask = PropertyDetails::TypeField::kMask | | 1750 int details_mask = PropertyDetails::TypeField::kMask | |
| 1761 PropertyDetails::DeletedField::kMask; | 1751 PropertyDetails::DeletedField::kMask; |
| 1762 details = AddUncasted<HBitwise>(Token::BIT_AND, details, | 1752 details = AddUncasted<HBitwise>(Token::BIT_AND, details, |
| 1763 Add<HConstant>(details_mask)); | 1753 Add<HConstant>(details_mask)); |
| 1764 IfBuilder details_compare(this); | 1754 IfBuilder details_compare(this); |
| 1765 details_compare.If<HCompareNumericAndBranch>( | 1755 details_compare.If<HCompareNumericAndBranch>( |
| 1766 details, graph()->GetConstant0(), Token::EQ); | 1756 details, graph()->GetConstant0(), Token::EQ); |
| 1767 details_compare.Then(); | 1757 details_compare.Then(); |
| 1768 HValue* result_index = | 1758 HValue* result_index = |
| 1769 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 1)); | 1759 AddUncasted<HAdd>(base_index, Add<HConstant>(start_offset + 1)); |
| 1770 result_index->ClearFlag(HValue::kCanOverflow); | 1760 result_index->ClearFlag(HValue::kCanOverflow); |
| 1771 Push(Add<HLoadKeyed>(elements, result_index, static_cast<HValue*>(NULL), | 1761 Push(Add<HLoadKeyed>(elements, result_index, nullptr, FAST_ELEMENTS)); |
| 1772 FAST_ELEMENTS)); | |
| 1773 details_compare.Else(); | 1762 details_compare.Else(); |
| 1774 Add<HPushArguments>(receiver, key); | 1763 Add<HPushArguments>(receiver, key); |
| 1775 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(), | 1764 Push(Add<HCallRuntime>(isolate()->factory()->empty_string(), |
| 1776 Runtime::FunctionForId(Runtime::kKeyedGetProperty), | 1765 Runtime::FunctionForId(Runtime::kKeyedGetProperty), |
| 1777 2)); | 1766 2)); |
| 1778 details_compare.End(); | 1767 details_compare.End(); |
| 1779 | 1768 |
| 1780 found_key_match.Else(); | 1769 found_key_match.Else(); |
| 1781 found_key_match.JoinContinuation(&return_or_loop_continuation); | 1770 found_key_match.JoinContinuation(&return_or_loop_continuation); |
| 1782 } | 1771 } |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1814 ElementsKind elements_kind = FAST_ELEMENTS; | 1803 ElementsKind elements_kind = FAST_ELEMENTS; |
| 1815 HValue* size = BuildCalculateElementsSize(elements_kind, length); | 1804 HValue* size = BuildCalculateElementsSize(elements_kind, length); |
| 1816 | 1805 |
| 1817 // Allocate the JSRegExpResult and the FixedArray in one step. | 1806 // Allocate the JSRegExpResult and the FixedArray in one step. |
| 1818 HValue* result = Add<HAllocate>( | 1807 HValue* result = Add<HAllocate>( |
| 1819 Add<HConstant>(JSRegExpResult::kSize), HType::JSArray(), | 1808 Add<HConstant>(JSRegExpResult::kSize), HType::JSArray(), |
| 1820 NOT_TENURED, JS_ARRAY_TYPE); | 1809 NOT_TENURED, JS_ARRAY_TYPE); |
| 1821 | 1810 |
| 1822 // Initialize the JSRegExpResult header. | 1811 // Initialize the JSRegExpResult header. |
| 1823 HValue* global_object = Add<HLoadNamedField>( | 1812 HValue* global_object = Add<HLoadNamedField>( |
| 1824 context(), static_cast<HValue*>(NULL), | 1813 context(), nullptr, |
| 1825 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 1814 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| 1826 HValue* native_context = Add<HLoadNamedField>( | 1815 HValue* native_context = Add<HLoadNamedField>( |
| 1827 global_object, static_cast<HValue*>(NULL), | 1816 global_object, nullptr, HObjectAccess::ForGlobalObjectNativeContext()); |
| 1828 HObjectAccess::ForGlobalObjectNativeContext()); | |
| 1829 Add<HStoreNamedField>( | 1817 Add<HStoreNamedField>( |
| 1830 result, HObjectAccess::ForMap(), | 1818 result, HObjectAccess::ForMap(), |
| 1831 Add<HLoadNamedField>( | 1819 Add<HLoadNamedField>( |
| 1832 native_context, static_cast<HValue*>(NULL), | 1820 native_context, nullptr, |
| 1833 HObjectAccess::ForContextSlot(Context::REGEXP_RESULT_MAP_INDEX))); | 1821 HObjectAccess::ForContextSlot(Context::REGEXP_RESULT_MAP_INDEX))); |
| 1834 HConstant* empty_fixed_array = | 1822 HConstant* empty_fixed_array = |
| 1835 Add<HConstant>(isolate()->factory()->empty_fixed_array()); | 1823 Add<HConstant>(isolate()->factory()->empty_fixed_array()); |
| 1836 Add<HStoreNamedField>( | 1824 Add<HStoreNamedField>( |
| 1837 result, HObjectAccess::ForJSArrayOffset(JSArray::kPropertiesOffset), | 1825 result, HObjectAccess::ForJSArrayOffset(JSArray::kPropertiesOffset), |
| 1838 empty_fixed_array); | 1826 empty_fixed_array); |
| 1839 Add<HStoreNamedField>( | 1827 Add<HStoreNamedField>( |
| 1840 result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset), | 1828 result, HObjectAccess::ForJSArrayOffset(JSArray::kElementsOffset), |
| 1841 empty_fixed_array); | 1829 empty_fixed_array); |
| 1842 Add<HStoreNamedField>( | 1830 Add<HStoreNamedField>( |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 // Check whether object is a smi. | 1889 // Check whether object is a smi. |
| 1902 IfBuilder if_objectissmi(this); | 1890 IfBuilder if_objectissmi(this); |
| 1903 if_objectissmi.If<HIsSmiAndBranch>(object); | 1891 if_objectissmi.If<HIsSmiAndBranch>(object); |
| 1904 if_objectissmi.Then(); | 1892 if_objectissmi.Then(); |
| 1905 { | 1893 { |
| 1906 // Compute hash for smi similar to smi_get_hash(). | 1894 // Compute hash for smi similar to smi_get_hash(). |
| 1907 HValue* hash = AddUncasted<HBitwise>(Token::BIT_AND, object, mask); | 1895 HValue* hash = AddUncasted<HBitwise>(Token::BIT_AND, object, mask); |
| 1908 | 1896 |
| 1909 // Load the key. | 1897 // Load the key. |
| 1910 HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); | 1898 HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); |
| 1911 HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, | 1899 HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, nullptr, |
| 1912 static_cast<HValue*>(NULL), | |
| 1913 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | 1900 FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| 1914 | 1901 |
| 1915 // Check if object == key. | 1902 // Check if object == key. |
| 1916 IfBuilder if_objectiskey(this); | 1903 IfBuilder if_objectiskey(this); |
| 1917 if_objectiskey.If<HCompareObjectEqAndBranch>(object, key); | 1904 if_objectiskey.If<HCompareObjectEqAndBranch>(object, key); |
| 1918 if_objectiskey.Then(); | 1905 if_objectiskey.Then(); |
| 1919 { | 1906 { |
| 1920 // Make the key_index available. | 1907 // Make the key_index available. |
| 1921 Push(key_index); | 1908 Push(key_index); |
| 1922 } | 1909 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1938 object, objectisnumber, | 1925 object, objectisnumber, |
| 1939 HObjectAccess::ForHeapNumberValueLowestBits()); | 1926 HObjectAccess::ForHeapNumberValueLowestBits()); |
| 1940 HValue* high = Add<HLoadNamedField>( | 1927 HValue* high = Add<HLoadNamedField>( |
| 1941 object, objectisnumber, | 1928 object, objectisnumber, |
| 1942 HObjectAccess::ForHeapNumberValueHighestBits()); | 1929 HObjectAccess::ForHeapNumberValueHighestBits()); |
| 1943 HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high); | 1930 HValue* hash = AddUncasted<HBitwise>(Token::BIT_XOR, low, high); |
| 1944 hash = AddUncasted<HBitwise>(Token::BIT_AND, hash, mask); | 1931 hash = AddUncasted<HBitwise>(Token::BIT_AND, hash, mask); |
| 1945 | 1932 |
| 1946 // Load the key. | 1933 // Load the key. |
| 1947 HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); | 1934 HValue* key_index = AddUncasted<HShl>(hash, graph()->GetConstant1()); |
| 1948 HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, | 1935 HValue* key = Add<HLoadKeyed>(number_string_cache, key_index, nullptr, |
| 1949 static_cast<HValue*>(NULL), | |
| 1950 FAST_ELEMENTS, ALLOW_RETURN_HOLE); | 1936 FAST_ELEMENTS, ALLOW_RETURN_HOLE); |
| 1951 | 1937 |
| 1952 // Check if the key is a heap number and compare it with the object. | 1938 // Check if the key is a heap number and compare it with the object. |
| 1953 IfBuilder if_keyisnotsmi(this); | 1939 IfBuilder if_keyisnotsmi(this); |
| 1954 HValue* keyisnotsmi = if_keyisnotsmi.IfNot<HIsSmiAndBranch>(key); | 1940 HValue* keyisnotsmi = if_keyisnotsmi.IfNot<HIsSmiAndBranch>(key); |
| 1955 if_keyisnotsmi.Then(); | 1941 if_keyisnotsmi.Then(); |
| 1956 { | 1942 { |
| 1957 IfBuilder if_keyisheapnumber(this); | 1943 IfBuilder if_keyisheapnumber(this); |
| 1958 if_keyisheapnumber.If<HCompareMap>( | 1944 if_keyisheapnumber.If<HCompareMap>( |
| 1959 key, isolate()->factory()->heap_number_map()); | 1945 key, isolate()->factory()->heap_number_map()); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1992 // Check for cache hit. | 1978 // Check for cache hit. |
| 1993 IfBuilder if_found(this, &found); | 1979 IfBuilder if_found(this, &found); |
| 1994 if_found.Then(); | 1980 if_found.Then(); |
| 1995 { | 1981 { |
| 1996 // Count number to string operation in native code. | 1982 // Count number to string operation in native code. |
| 1997 AddIncrementCounter(isolate()->counters()->number_to_string_native()); | 1983 AddIncrementCounter(isolate()->counters()->number_to_string_native()); |
| 1998 | 1984 |
| 1999 // Load the value in case of cache hit. | 1985 // Load the value in case of cache hit. |
| 2000 HValue* key_index = Pop(); | 1986 HValue* key_index = Pop(); |
| 2001 HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1()); | 1987 HValue* value_index = AddUncasted<HAdd>(key_index, graph()->GetConstant1()); |
| 2002 Push(Add<HLoadKeyed>(number_string_cache, value_index, | 1988 Push(Add<HLoadKeyed>(number_string_cache, value_index, nullptr, |
| 2003 static_cast<HValue*>(NULL), | |
| 2004 FAST_ELEMENTS, ALLOW_RETURN_HOLE)); | 1989 FAST_ELEMENTS, ALLOW_RETURN_HOLE)); |
| 2005 } | 1990 } |
| 2006 if_found.Else(); | 1991 if_found.Else(); |
| 2007 { | 1992 { |
| 2008 // Cache miss, fallback to runtime. | 1993 // Cache miss, fallback to runtime. |
| 2009 Add<HPushArguments>(object); | 1994 Add<HPushArguments>(object); |
| 2010 Push(Add<HCallRuntime>( | 1995 Push(Add<HCallRuntime>( |
| 2011 isolate()->factory()->empty_string(), | 1996 isolate()->factory()->empty_string(), |
| 2012 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), | 1997 Runtime::FunctionForId(Runtime::kNumberToStringSkipCache), |
| 2013 1)); | 1998 1)); |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2433 } else { | 2418 } else { |
| 2434 length = AddLoadFixedArrayLength(elements); | 2419 length = AddLoadFixedArrayLength(elements); |
| 2435 } | 2420 } |
| 2436 length->set_type(HType::Smi()); | 2421 length->set_type(HType::Smi()); |
| 2437 HValue* checked_key = NULL; | 2422 HValue* checked_key = NULL; |
| 2438 if (IsExternalArrayElementsKind(elements_kind) || | 2423 if (IsExternalArrayElementsKind(elements_kind) || |
| 2439 IsFixedTypedArrayElementsKind(elements_kind)) { | 2424 IsFixedTypedArrayElementsKind(elements_kind)) { |
| 2440 HValue* backing_store; | 2425 HValue* backing_store; |
| 2441 if (IsExternalArrayElementsKind(elements_kind)) { | 2426 if (IsExternalArrayElementsKind(elements_kind)) { |
| 2442 backing_store = Add<HLoadNamedField>( | 2427 backing_store = Add<HLoadNamedField>( |
| 2443 elements, static_cast<HValue*>(NULL), | 2428 elements, nullptr, HObjectAccess::ForExternalArrayExternalPointer()); |
| 2444 HObjectAccess::ForExternalArrayExternalPointer()); | |
| 2445 } else { | 2429 } else { |
| 2446 backing_store = elements; | 2430 backing_store = elements; |
| 2447 } | 2431 } |
| 2448 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { | 2432 if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { |
| 2449 NoObservableSideEffectsScope no_effects(this); | 2433 NoObservableSideEffectsScope no_effects(this); |
| 2450 IfBuilder length_checker(this); | 2434 IfBuilder length_checker(this); |
| 2451 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); | 2435 length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT); |
| 2452 length_checker.Then(); | 2436 length_checker.Then(); |
| 2453 IfBuilder negative_checker(this); | 2437 IfBuilder negative_checker(this); |
| 2454 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( | 2438 HValue* bounds_check = negative_checker.If<HCompareNumericAndBranch>( |
| (...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2840 BuildFillElementsWithValue(to_properties, kind, length, capacity, | 2824 BuildFillElementsWithValue(to_properties, kind, length, capacity, |
| 2841 graph()->GetConstantUndefined()); | 2825 graph()->GetConstantUndefined()); |
| 2842 | 2826 |
| 2843 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); | 2827 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); |
| 2844 | 2828 |
| 2845 HValue* key = builder.BeginBody(length, graph()->GetConstant0(), Token::GT); | 2829 HValue* key = builder.BeginBody(length, graph()->GetConstant0(), Token::GT); |
| 2846 | 2830 |
| 2847 key = AddUncasted<HSub>(key, graph()->GetConstant1()); | 2831 key = AddUncasted<HSub>(key, graph()->GetConstant1()); |
| 2848 key->ClearFlag(HValue::kCanOverflow); | 2832 key->ClearFlag(HValue::kCanOverflow); |
| 2849 | 2833 |
| 2850 HValue* element = | 2834 HValue* element = Add<HLoadKeyed>(from_properties, key, nullptr, kind); |
| 2851 Add<HLoadKeyed>(from_properties, key, static_cast<HValue*>(NULL), kind); | |
| 2852 | 2835 |
| 2853 Add<HStoreKeyed>(to_properties, key, element, kind); | 2836 Add<HStoreKeyed>(to_properties, key, element, kind); |
| 2854 | 2837 |
| 2855 builder.EndBody(); | 2838 builder.EndBody(); |
| 2856 } | 2839 } |
| 2857 | 2840 |
| 2858 | 2841 |
| 2859 void HGraphBuilder::BuildCopyElements(HValue* from_elements, | 2842 void HGraphBuilder::BuildCopyElements(HValue* from_elements, |
| 2860 ElementsKind from_elements_kind, | 2843 ElementsKind from_elements_kind, |
| 2861 HValue* to_elements, | 2844 HValue* to_elements, |
| (...skipping 19 matching lines...) Expand all Loading... |
| 2881 // consistent state. | 2864 // consistent state. |
| 2882 BuildFillElementsWithHole(to_elements, to_elements_kind, | 2865 BuildFillElementsWithHole(to_elements, to_elements_kind, |
| 2883 graph()->GetConstant0(), NULL); | 2866 graph()->GetConstant0(), NULL); |
| 2884 } | 2867 } |
| 2885 | 2868 |
| 2886 if (constant_capacity != -1) { | 2869 if (constant_capacity != -1) { |
| 2887 // Unroll the loop for small elements kinds. | 2870 // Unroll the loop for small elements kinds. |
| 2888 for (int i = 0; i < constant_capacity; i++) { | 2871 for (int i = 0; i < constant_capacity; i++) { |
| 2889 HValue* key_constant = Add<HConstant>(i); | 2872 HValue* key_constant = Add<HConstant>(i); |
| 2890 HInstruction* value = Add<HLoadKeyed>(from_elements, key_constant, | 2873 HInstruction* value = Add<HLoadKeyed>(from_elements, key_constant, |
| 2891 static_cast<HValue*>(NULL), | 2874 nullptr, from_elements_kind); |
| 2892 from_elements_kind); | |
| 2893 Add<HStoreKeyed>(to_elements, key_constant, value, to_elements_kind); | 2875 Add<HStoreKeyed>(to_elements, key_constant, value, to_elements_kind); |
| 2894 } | 2876 } |
| 2895 } else { | 2877 } else { |
| 2896 if (!pre_fill_with_holes && | 2878 if (!pre_fill_with_holes && |
| 2897 (capacity == NULL || !length->Equals(capacity))) { | 2879 (capacity == NULL || !length->Equals(capacity))) { |
| 2898 BuildFillElementsWithHole(to_elements, to_elements_kind, | 2880 BuildFillElementsWithHole(to_elements, to_elements_kind, |
| 2899 length, NULL); | 2881 length, NULL); |
| 2900 } | 2882 } |
| 2901 | 2883 |
| 2902 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); | 2884 LoopBuilder builder(this, context(), LoopBuilder::kPostDecrement); |
| 2903 | 2885 |
| 2904 HValue* key = builder.BeginBody(length, graph()->GetConstant0(), | 2886 HValue* key = builder.BeginBody(length, graph()->GetConstant0(), |
| 2905 Token::GT); | 2887 Token::GT); |
| 2906 | 2888 |
| 2907 key = AddUncasted<HSub>(key, graph()->GetConstant1()); | 2889 key = AddUncasted<HSub>(key, graph()->GetConstant1()); |
| 2908 key->ClearFlag(HValue::kCanOverflow); | 2890 key->ClearFlag(HValue::kCanOverflow); |
| 2909 | 2891 |
| 2910 HValue* element = Add<HLoadKeyed>(from_elements, key, | 2892 HValue* element = Add<HLoadKeyed>(from_elements, key, nullptr, |
| 2911 static_cast<HValue*>(NULL), | 2893 from_elements_kind, ALLOW_RETURN_HOLE); |
| 2912 from_elements_kind, | |
| 2913 ALLOW_RETURN_HOLE); | |
| 2914 | 2894 |
| 2915 ElementsKind kind = (IsHoleyElementsKind(from_elements_kind) && | 2895 ElementsKind kind = (IsHoleyElementsKind(from_elements_kind) && |
| 2916 IsFastSmiElementsKind(to_elements_kind)) | 2896 IsFastSmiElementsKind(to_elements_kind)) |
| 2917 ? FAST_HOLEY_ELEMENTS : to_elements_kind; | 2897 ? FAST_HOLEY_ELEMENTS : to_elements_kind; |
| 2918 | 2898 |
| 2919 if (IsHoleyElementsKind(from_elements_kind) && | 2899 if (IsHoleyElementsKind(from_elements_kind) && |
| 2920 from_elements_kind != to_elements_kind) { | 2900 from_elements_kind != to_elements_kind) { |
| 2921 IfBuilder if_hole(this); | 2901 IfBuilder if_hole(this); |
| 2922 if_hole.If<HCompareHoleAndBranch>(element); | 2902 if_hole.If<HCompareHoleAndBranch>(element); |
| 2923 if_hole.Then(); | 2903 if_hole.Then(); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3014 // The allocation for the cloned array above causes register pressure on | 2994 // The allocation for the cloned array above causes register pressure on |
| 3015 // machines with low register counts. Force a reload of the boilerplate | 2995 // machines with low register counts. Force a reload of the boilerplate |
| 3016 // elements here to free up a register for the allocation to avoid unnecessary | 2996 // elements here to free up a register for the allocation to avoid unnecessary |
| 3017 // spillage. | 2997 // spillage. |
| 3018 boilerplate_elements = AddLoadElements(boilerplate); | 2998 boilerplate_elements = AddLoadElements(boilerplate); |
| 3019 boilerplate_elements->SetFlag(HValue::kCantBeReplaced); | 2999 boilerplate_elements->SetFlag(HValue::kCantBeReplaced); |
| 3020 | 3000 |
| 3021 // Copy the elements array header. | 3001 // Copy the elements array header. |
| 3022 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { | 3002 for (int i = 0; i < FixedArrayBase::kHeaderSize; i += kPointerSize) { |
| 3023 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); | 3003 HObjectAccess access = HObjectAccess::ForFixedArrayHeader(i); |
| 3024 Add<HStoreNamedField>(elements, access, | 3004 Add<HStoreNamedField>( |
| 3025 Add<HLoadNamedField>(boilerplate_elements, | 3005 elements, access, |
| 3026 static_cast<HValue*>(NULL), access)); | 3006 Add<HLoadNamedField>(boilerplate_elements, nullptr, access)); |
| 3027 } | 3007 } |
| 3028 | 3008 |
| 3029 // And the result of the length | 3009 // And the result of the length |
| 3030 HValue* length = AddLoadArrayLength(boilerplate, kind); | 3010 HValue* length = AddLoadArrayLength(boilerplate, kind); |
| 3031 Add<HStoreNamedField>(result, HObjectAccess::ForArrayLength(kind), length); | 3011 Add<HStoreNamedField>(result, HObjectAccess::ForArrayLength(kind), length); |
| 3032 | 3012 |
| 3033 BuildCopyElements(boilerplate_elements, kind, elements, | 3013 BuildCopyElements(boilerplate_elements, kind, elements, |
| 3034 kind, length, NULL); | 3014 kind, length, NULL); |
| 3035 return result; | 3015 return result; |
| 3036 } | 3016 } |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3095 DCHECK(allocation_site != NULL); | 3075 DCHECK(allocation_site != NULL); |
| 3096 HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>( | 3076 HInnerAllocatedObject* allocation_memento = Add<HInnerAllocatedObject>( |
| 3097 previous_object, previous_object_size, HType::HeapObject()); | 3077 previous_object, previous_object_size, HType::HeapObject()); |
| 3098 AddStoreMapConstant( | 3078 AddStoreMapConstant( |
| 3099 allocation_memento, isolate()->factory()->allocation_memento_map()); | 3079 allocation_memento, isolate()->factory()->allocation_memento_map()); |
| 3100 Add<HStoreNamedField>( | 3080 Add<HStoreNamedField>( |
| 3101 allocation_memento, | 3081 allocation_memento, |
| 3102 HObjectAccess::ForAllocationMementoSite(), | 3082 HObjectAccess::ForAllocationMementoSite(), |
| 3103 allocation_site); | 3083 allocation_site); |
| 3104 if (FLAG_allocation_site_pretenuring) { | 3084 if (FLAG_allocation_site_pretenuring) { |
| 3105 HValue* memento_create_count = Add<HLoadNamedField>( | 3085 HValue* memento_create_count = |
| 3106 allocation_site, static_cast<HValue*>(NULL), | 3086 Add<HLoadNamedField>(allocation_site, nullptr, |
| 3107 HObjectAccess::ForAllocationSiteOffset( | 3087 HObjectAccess::ForAllocationSiteOffset( |
| 3108 AllocationSite::kPretenureCreateCountOffset)); | 3088 AllocationSite::kPretenureCreateCountOffset)); |
| 3109 memento_create_count = AddUncasted<HAdd>( | 3089 memento_create_count = AddUncasted<HAdd>( |
| 3110 memento_create_count, graph()->GetConstant1()); | 3090 memento_create_count, graph()->GetConstant1()); |
| 3111 // This smi value is reset to zero after every gc, overflow isn't a problem | 3091 // This smi value is reset to zero after every gc, overflow isn't a problem |
| 3112 // since the counter is bounded by the new space size. | 3092 // since the counter is bounded by the new space size. |
| 3113 memento_create_count->ClearFlag(HValue::kCanOverflow); | 3093 memento_create_count->ClearFlag(HValue::kCanOverflow); |
| 3114 Add<HStoreNamedField>( | 3094 Add<HStoreNamedField>( |
| 3115 allocation_site, HObjectAccess::ForAllocationSiteOffset( | 3095 allocation_site, HObjectAccess::ForAllocationSiteOffset( |
| 3116 AllocationSite::kPretenureCreateCountOffset), memento_create_count); | 3096 AllocationSite::kPretenureCreateCountOffset), memento_create_count); |
| 3117 } | 3097 } |
| 3118 } | 3098 } |
| 3119 | 3099 |
| 3120 | 3100 |
| 3121 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* closure) { | 3101 HInstruction* HGraphBuilder::BuildGetNativeContext(HValue* closure) { |
| 3122 // Get the global object, then the native context | 3102 // Get the global object, then the native context |
| 3123 HInstruction* context = | 3103 HInstruction* context = Add<HLoadNamedField>( |
| 3124 Add<HLoadNamedField>(closure, static_cast<HValue*>(NULL), | 3104 closure, nullptr, HObjectAccess::ForFunctionContextPointer()); |
| 3125 HObjectAccess::ForFunctionContextPointer()); | |
| 3126 HInstruction* global_object = Add<HLoadNamedField>( | 3105 HInstruction* global_object = Add<HLoadNamedField>( |
| 3127 context, static_cast<HValue*>(NULL), | 3106 context, nullptr, |
| 3128 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 3107 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| 3129 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( | 3108 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( |
| 3130 GlobalObject::kNativeContextOffset); | 3109 GlobalObject::kNativeContextOffset); |
| 3131 return Add<HLoadNamedField>( | 3110 return Add<HLoadNamedField>(global_object, nullptr, access); |
| 3132 global_object, static_cast<HValue*>(NULL), access); | |
| 3133 } | 3111 } |
| 3134 | 3112 |
| 3135 | 3113 |
| 3136 HInstruction* HGraphBuilder::BuildGetScriptContext(int context_index) { | 3114 HInstruction* HGraphBuilder::BuildGetScriptContext(int context_index) { |
| 3137 HValue* native_context = BuildGetNativeContext(); | 3115 HValue* native_context = BuildGetNativeContext(); |
| 3138 HValue* script_context_table = Add<HLoadNamedField>( | 3116 HValue* script_context_table = Add<HLoadNamedField>( |
| 3139 native_context, static_cast<HValue*>(NULL), | 3117 native_context, nullptr, |
| 3140 HObjectAccess::ForContextSlot(Context::SCRIPT_CONTEXT_TABLE_INDEX)); | 3118 HObjectAccess::ForContextSlot(Context::SCRIPT_CONTEXT_TABLE_INDEX)); |
| 3141 return Add<HLoadNamedField>(script_context_table, static_cast<HValue*>(NULL), | 3119 return Add<HLoadNamedField>(script_context_table, nullptr, |
| 3142 HObjectAccess::ForScriptContext(context_index)); | 3120 HObjectAccess::ForScriptContext(context_index)); |
| 3143 } | 3121 } |
| 3144 | 3122 |
| 3145 | 3123 |
| 3146 HInstruction* HGraphBuilder::BuildGetNativeContext() { | 3124 HInstruction* HGraphBuilder::BuildGetNativeContext() { |
| 3147 // Get the global object, then the native context | 3125 // Get the global object, then the native context |
| 3148 HValue* global_object = Add<HLoadNamedField>( | 3126 HValue* global_object = Add<HLoadNamedField>( |
| 3149 context(), static_cast<HValue*>(NULL), | 3127 context(), nullptr, |
| 3150 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 3128 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| 3151 return Add<HLoadNamedField>( | 3129 return Add<HLoadNamedField>(global_object, nullptr, |
| 3152 global_object, static_cast<HValue*>(NULL), | 3130 HObjectAccess::ForObservableJSObjectOffset( |
| 3153 HObjectAccess::ForObservableJSObjectOffset( | 3131 GlobalObject::kNativeContextOffset)); |
| 3154 GlobalObject::kNativeContextOffset)); | |
| 3155 } | 3132 } |
| 3156 | 3133 |
| 3157 | 3134 |
| 3158 HInstruction* HGraphBuilder::BuildGetArrayFunction() { | 3135 HInstruction* HGraphBuilder::BuildGetArrayFunction() { |
| 3159 HInstruction* native_context = BuildGetNativeContext(); | 3136 HInstruction* native_context = BuildGetNativeContext(); |
| 3160 HInstruction* index = | 3137 HInstruction* index = |
| 3161 Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); | 3138 Add<HConstant>(static_cast<int32_t>(Context::ARRAY_FUNCTION_INDEX)); |
| 3162 return Add<HLoadKeyed>( | 3139 return Add<HLoadKeyed>(native_context, index, nullptr, FAST_ELEMENTS); |
| 3163 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | |
| 3164 } | 3140 } |
| 3165 | 3141 |
| 3166 | 3142 |
| 3167 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, | 3143 HGraphBuilder::JSArrayBuilder::JSArrayBuilder(HGraphBuilder* builder, |
| 3168 ElementsKind kind, | 3144 ElementsKind kind, |
| 3169 HValue* allocation_site_payload, | 3145 HValue* allocation_site_payload, |
| 3170 HValue* constructor_function, | 3146 HValue* constructor_function, |
| 3171 AllocationSiteOverrideMode override_mode) : | 3147 AllocationSiteOverrideMode override_mode) : |
| 3172 builder_(builder), | 3148 builder_(builder), |
| 3173 kind_(kind), | 3149 kind_(kind), |
| (...skipping 24 matching lines...) Expand all Loading... |
| 3198 // A constant map is fine. | 3174 // A constant map is fine. |
| 3199 Handle<Map> map(builder()->isolate()->get_initial_js_array_map(kind_), | 3175 Handle<Map> map(builder()->isolate()->get_initial_js_array_map(kind_), |
| 3200 builder()->isolate()); | 3176 builder()->isolate()); |
| 3201 return builder()->Add<HConstant>(map); | 3177 return builder()->Add<HConstant>(map); |
| 3202 } | 3178 } |
| 3203 | 3179 |
| 3204 if (constructor_function_ != NULL && kind_ == GetInitialFastElementsKind()) { | 3180 if (constructor_function_ != NULL && kind_ == GetInitialFastElementsKind()) { |
| 3205 // No need for a context lookup if the kind_ matches the initial | 3181 // No need for a context lookup if the kind_ matches the initial |
| 3206 // map, because we can just load the map in that case. | 3182 // map, because we can just load the map in that case. |
| 3207 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 3183 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
| 3208 return builder()->Add<HLoadNamedField>( | 3184 return builder()->Add<HLoadNamedField>(constructor_function_, nullptr, |
| 3209 constructor_function_, static_cast<HValue*>(NULL), access); | 3185 access); |
| 3210 } | 3186 } |
| 3211 | 3187 |
| 3212 // TODO(mvstanton): we should always have a constructor function if we | 3188 // TODO(mvstanton): we should always have a constructor function if we |
| 3213 // are creating a stub. | 3189 // are creating a stub. |
| 3214 HInstruction* native_context = constructor_function_ != NULL | 3190 HInstruction* native_context = constructor_function_ != NULL |
| 3215 ? builder()->BuildGetNativeContext(constructor_function_) | 3191 ? builder()->BuildGetNativeContext(constructor_function_) |
| 3216 : builder()->BuildGetNativeContext(); | 3192 : builder()->BuildGetNativeContext(); |
| 3217 | 3193 |
| 3218 HInstruction* index = builder()->Add<HConstant>( | 3194 HInstruction* index = builder()->Add<HConstant>( |
| 3219 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); | 3195 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); |
| 3220 | 3196 |
| 3221 HInstruction* map_array = builder()->Add<HLoadKeyed>( | 3197 HInstruction* map_array = |
| 3222 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 3198 builder()->Add<HLoadKeyed>(native_context, index, nullptr, FAST_ELEMENTS); |
| 3223 | 3199 |
| 3224 HInstruction* kind_index = builder()->Add<HConstant>(kind_); | 3200 HInstruction* kind_index = builder()->Add<HConstant>(kind_); |
| 3225 | 3201 |
| 3226 return builder()->Add<HLoadKeyed>( | 3202 return builder()->Add<HLoadKeyed>(map_array, kind_index, nullptr, |
| 3227 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 3203 FAST_ELEMENTS); |
| 3228 } | 3204 } |
| 3229 | 3205 |
| 3230 | 3206 |
| 3231 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { | 3207 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { |
| 3232 // Find the map near the constructor function | 3208 // Find the map near the constructor function |
| 3233 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 3209 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
| 3234 return builder()->Add<HLoadNamedField>( | 3210 return builder()->Add<HLoadNamedField>(constructor_function_, nullptr, |
| 3235 constructor_function_, static_cast<HValue*>(NULL), access); | 3211 access); |
| 3236 } | 3212 } |
| 3237 | 3213 |
| 3238 | 3214 |
| 3239 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { | 3215 HAllocate* HGraphBuilder::JSArrayBuilder::AllocateEmptyArray() { |
| 3240 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); | 3216 HConstant* capacity = builder()->Add<HConstant>(initial_capacity()); |
| 3241 return AllocateArray(capacity, | 3217 return AllocateArray(capacity, |
| 3242 capacity, | 3218 capacity, |
| 3243 builder()->graph()->GetConstant0()); | 3219 builder()->graph()->GetConstant0()); |
| 3244 } | 3220 } |
| 3245 | 3221 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3324 builder()->BuildFillElementsWithHole(elements_location_, kind_, | 3300 builder()->BuildFillElementsWithHole(elements_location_, kind_, |
| 3325 graph()->GetConstant0(), capacity); | 3301 graph()->GetConstant0(), capacity); |
| 3326 } | 3302 } |
| 3327 | 3303 |
| 3328 return array_object; | 3304 return array_object; |
| 3329 } | 3305 } |
| 3330 | 3306 |
| 3331 | 3307 |
| 3332 HValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) { | 3308 HValue* HGraphBuilder::AddLoadJSBuiltin(Builtins::JavaScript builtin) { |
| 3333 HValue* global_object = Add<HLoadNamedField>( | 3309 HValue* global_object = Add<HLoadNamedField>( |
| 3334 context(), static_cast<HValue*>(NULL), | 3310 context(), nullptr, |
| 3335 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 3311 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| 3336 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( | 3312 HObjectAccess access = HObjectAccess::ForObservableJSObjectOffset( |
| 3337 GlobalObject::kBuiltinsOffset); | 3313 GlobalObject::kBuiltinsOffset); |
| 3338 HValue* builtins = Add<HLoadNamedField>( | 3314 HValue* builtins = Add<HLoadNamedField>(global_object, nullptr, access); |
| 3339 global_object, static_cast<HValue*>(NULL), access); | |
| 3340 HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset( | 3315 HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset( |
| 3341 JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); | 3316 JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); |
| 3342 return Add<HLoadNamedField>( | 3317 return Add<HLoadNamedField>(builtins, nullptr, function_access); |
| 3343 builtins, static_cast<HValue*>(NULL), function_access); | |
| 3344 } | 3318 } |
| 3345 | 3319 |
| 3346 | 3320 |
| 3347 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) | 3321 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) |
| 3348 : HGraphBuilder(info), | 3322 : HGraphBuilder(info), |
| 3349 function_state_(NULL), | 3323 function_state_(NULL), |
| 3350 initial_function_state_(this, info, NORMAL_RETURN, 0), | 3324 initial_function_state_(this, info, NORMAL_RETURN, 0), |
| 3351 ast_context_(NULL), | 3325 ast_context_(NULL), |
| 3352 break_scope_(NULL), | 3326 break_scope_(NULL), |
| 3353 inlined_count_(0), | 3327 inlined_count_(0), |
| (...skipping 1226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4580 } | 4554 } |
| 4581 VisitDeclarations(scope->declarations()); | 4555 VisitDeclarations(scope->declarations()); |
| 4582 AddSimulate(stmt->DeclsId(), REMOVABLE_SIMULATE); | 4556 AddSimulate(stmt->DeclsId(), REMOVABLE_SIMULATE); |
| 4583 } | 4557 } |
| 4584 CHECK_BAILOUT(VisitStatements(stmt->statements())); | 4558 CHECK_BAILOUT(VisitStatements(stmt->statements())); |
| 4585 } | 4559 } |
| 4586 set_scope(outer_scope); | 4560 set_scope(outer_scope); |
| 4587 if (scope != NULL && current_block() != NULL) { | 4561 if (scope != NULL && current_block() != NULL) { |
| 4588 HValue* inner_context = environment()->context(); | 4562 HValue* inner_context = environment()->context(); |
| 4589 HValue* outer_context = Add<HLoadNamedField>( | 4563 HValue* outer_context = Add<HLoadNamedField>( |
| 4590 inner_context, static_cast<HValue*>(NULL), | 4564 inner_context, nullptr, |
| 4591 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); | 4565 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); |
| 4592 | 4566 |
| 4593 HInstruction* instr = Add<HStoreFrameContext>(outer_context); | 4567 HInstruction* instr = Add<HStoreFrameContext>(outer_context); |
| 4594 environment()->BindContext(outer_context); | 4568 environment()->BindContext(outer_context); |
| 4595 if (instr->HasObservableSideEffects()) { | 4569 if (instr->HasObservableSideEffects()) { |
| 4596 AddSimulate(stmt->ExitId(), REMOVABLE_SIMULATE); | 4570 AddSimulate(stmt->ExitId(), REMOVABLE_SIMULATE); |
| 4597 } | 4571 } |
| 4598 } | 4572 } |
| 4599 HBasicBlock* break_block = break_info.break_block(); | 4573 HBasicBlock* break_block = break_info.break_block(); |
| 4600 if (break_block != NULL) { | 4574 if (break_block != NULL) { |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4711 int drop_extra = 0; | 4685 int drop_extra = 0; |
| 4712 HBasicBlock* continue_block = break_scope()->Get( | 4686 HBasicBlock* continue_block = break_scope()->Get( |
| 4713 stmt->target(), BreakAndContinueScope::CONTINUE, | 4687 stmt->target(), BreakAndContinueScope::CONTINUE, |
| 4714 &outer_scope, &drop_extra); | 4688 &outer_scope, &drop_extra); |
| 4715 HValue* context = environment()->context(); | 4689 HValue* context = environment()->context(); |
| 4716 Drop(drop_extra); | 4690 Drop(drop_extra); |
| 4717 int context_pop_count = inner_scope->ContextChainLength(outer_scope); | 4691 int context_pop_count = inner_scope->ContextChainLength(outer_scope); |
| 4718 if (context_pop_count > 0) { | 4692 if (context_pop_count > 0) { |
| 4719 while (context_pop_count-- > 0) { | 4693 while (context_pop_count-- > 0) { |
| 4720 HInstruction* context_instruction = Add<HLoadNamedField>( | 4694 HInstruction* context_instruction = Add<HLoadNamedField>( |
| 4721 context, static_cast<HValue*>(NULL), | 4695 context, nullptr, |
| 4722 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); | 4696 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); |
| 4723 context = context_instruction; | 4697 context = context_instruction; |
| 4724 } | 4698 } |
| 4725 HInstruction* instr = Add<HStoreFrameContext>(context); | 4699 HInstruction* instr = Add<HStoreFrameContext>(context); |
| 4726 if (instr->HasObservableSideEffects()) { | 4700 if (instr->HasObservableSideEffects()) { |
| 4727 AddSimulate(stmt->target()->EntryId(), REMOVABLE_SIMULATE); | 4701 AddSimulate(stmt->target()->EntryId(), REMOVABLE_SIMULATE); |
| 4728 } | 4702 } |
| 4729 environment()->BindContext(context); | 4703 environment()->BindContext(context); |
| 4730 } | 4704 } |
| 4731 | 4705 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4743 int drop_extra = 0; | 4717 int drop_extra = 0; |
| 4744 HBasicBlock* break_block = break_scope()->Get( | 4718 HBasicBlock* break_block = break_scope()->Get( |
| 4745 stmt->target(), BreakAndContinueScope::BREAK, | 4719 stmt->target(), BreakAndContinueScope::BREAK, |
| 4746 &outer_scope, &drop_extra); | 4720 &outer_scope, &drop_extra); |
| 4747 HValue* context = environment()->context(); | 4721 HValue* context = environment()->context(); |
| 4748 Drop(drop_extra); | 4722 Drop(drop_extra); |
| 4749 int context_pop_count = inner_scope->ContextChainLength(outer_scope); | 4723 int context_pop_count = inner_scope->ContextChainLength(outer_scope); |
| 4750 if (context_pop_count > 0) { | 4724 if (context_pop_count > 0) { |
| 4751 while (context_pop_count-- > 0) { | 4725 while (context_pop_count-- > 0) { |
| 4752 HInstruction* context_instruction = Add<HLoadNamedField>( | 4726 HInstruction* context_instruction = Add<HLoadNamedField>( |
| 4753 context, static_cast<HValue*>(NULL), | 4727 context, nullptr, |
| 4754 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); | 4728 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); |
| 4755 context = context_instruction; | 4729 context = context_instruction; |
| 4756 } | 4730 } |
| 4757 HInstruction* instr = Add<HStoreFrameContext>(context); | 4731 HInstruction* instr = Add<HStoreFrameContext>(context); |
| 4758 if (instr->HasObservableSideEffects()) { | 4732 if (instr->HasObservableSideEffects()) { |
| 4759 AddSimulate(stmt->target()->ExitId(), REMOVABLE_SIMULATE); | 4733 AddSimulate(stmt->target()->ExitId(), REMOVABLE_SIMULATE); |
| 4760 } | 4734 } |
| 4761 environment()->BindContext(context); | 4735 environment()->BindContext(context); |
| 4762 } | 4736 } |
| 4763 Goto(break_block); | 4737 Goto(break_block); |
| (...skipping 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5343 return kUseGeneric; | 5317 return kUseGeneric; |
| 5344 } | 5318 } |
| 5345 | 5319 |
| 5346 | 5320 |
| 5347 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { | 5321 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { |
| 5348 DCHECK(var->IsContextSlot()); | 5322 DCHECK(var->IsContextSlot()); |
| 5349 HValue* context = environment()->context(); | 5323 HValue* context = environment()->context(); |
| 5350 int length = scope()->ContextChainLength(var->scope()); | 5324 int length = scope()->ContextChainLength(var->scope()); |
| 5351 while (length-- > 0) { | 5325 while (length-- > 0) { |
| 5352 context = Add<HLoadNamedField>( | 5326 context = Add<HLoadNamedField>( |
| 5353 context, static_cast<HValue*>(NULL), | 5327 context, nullptr, |
| 5354 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); | 5328 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); |
| 5355 } | 5329 } |
| 5356 return context; | 5330 return context; |
| 5357 } | 5331 } |
| 5358 | 5332 |
| 5359 | 5333 |
| 5360 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 5334 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
| 5361 if (expr->is_this()) { | 5335 if (expr->is_this()) { |
| 5362 current_info()->set_this_has_uses(true); | 5336 current_info()->set_this_has_uses(true); |
| 5363 } | 5337 } |
| (...skipping 21 matching lines...) Expand all Loading... |
| 5385 | 5359 |
| 5386 if (FLAG_harmony_scoping) { | 5360 if (FLAG_harmony_scoping) { |
| 5387 Handle<ScriptContextTable> script_contexts( | 5361 Handle<ScriptContextTable> script_contexts( |
| 5388 global->native_context()->script_context_table()); | 5362 global->native_context()->script_context_table()); |
| 5389 ScriptContextTable::LookupResult lookup; | 5363 ScriptContextTable::LookupResult lookup; |
| 5390 if (ScriptContextTable::Lookup(script_contexts, variable->name(), | 5364 if (ScriptContextTable::Lookup(script_contexts, variable->name(), |
| 5391 &lookup)) { | 5365 &lookup)) { |
| 5392 Handle<Context> script_context = ScriptContextTable::GetContext( | 5366 Handle<Context> script_context = ScriptContextTable::GetContext( |
| 5393 script_contexts, lookup.context_index); | 5367 script_contexts, lookup.context_index); |
| 5394 HInstruction* result = New<HLoadNamedField>( | 5368 HInstruction* result = New<HLoadNamedField>( |
| 5395 Add<HConstant>(script_context), static_cast<HValue*>(NULL), | 5369 Add<HConstant>(script_context), nullptr, |
| 5396 HObjectAccess::ForContextSlot(lookup.slot_index)); | 5370 HObjectAccess::ForContextSlot(lookup.slot_index)); |
| 5397 return ast_context()->ReturnInstruction(result, expr->id()); | 5371 return ast_context()->ReturnInstruction(result, expr->id()); |
| 5398 } | 5372 } |
| 5399 } | 5373 } |
| 5400 | 5374 |
| 5401 LookupIterator it(global, variable->name(), | 5375 LookupIterator it(global, variable->name(), |
| 5402 LookupIterator::OWN_SKIP_INTERCEPTOR); | 5376 LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 5403 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); | 5377 GlobalPropertyAccess type = LookupGlobalProperty(variable, &it, LOAD); |
| 5404 | 5378 |
| 5405 if (type == kUseCell) { | 5379 if (type == kUseCell) { |
| 5406 Handle<PropertyCell> cell = it.GetPropertyCell(); | 5380 Handle<PropertyCell> cell = it.GetPropertyCell(); |
| 5407 if (cell->type()->IsConstant()) { | 5381 if (cell->type()->IsConstant()) { |
| 5408 PropertyCell::AddDependentCompilationInfo(cell, top_info()); | 5382 PropertyCell::AddDependentCompilationInfo(cell, top_info()); |
| 5409 Handle<Object> constant_object = cell->type()->AsConstant()->Value(); | 5383 Handle<Object> constant_object = cell->type()->AsConstant()->Value(); |
| 5410 if (constant_object->IsConsString()) { | 5384 if (constant_object->IsConsString()) { |
| 5411 constant_object = | 5385 constant_object = |
| 5412 String::Flatten(Handle<String>::cast(constant_object)); | 5386 String::Flatten(Handle<String>::cast(constant_object)); |
| 5413 } | 5387 } |
| 5414 HConstant* constant = New<HConstant>(constant_object); | 5388 HConstant* constant = New<HConstant>(constant_object); |
| 5415 return ast_context()->ReturnInstruction(constant, expr->id()); | 5389 return ast_context()->ReturnInstruction(constant, expr->id()); |
| 5416 } else { | 5390 } else { |
| 5417 HLoadGlobalCell* instr = | 5391 HLoadGlobalCell* instr = |
| 5418 New<HLoadGlobalCell>(cell, it.property_details()); | 5392 New<HLoadGlobalCell>(cell, it.property_details()); |
| 5419 return ast_context()->ReturnInstruction(instr, expr->id()); | 5393 return ast_context()->ReturnInstruction(instr, expr->id()); |
| 5420 } | 5394 } |
| 5421 } else { | 5395 } else { |
| 5422 HValue* global_object = Add<HLoadNamedField>( | 5396 HValue* global_object = Add<HLoadNamedField>( |
| 5423 context(), static_cast<HValue*>(NULL), | 5397 context(), nullptr, |
| 5424 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 5398 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| 5425 HLoadGlobalGeneric* instr = | 5399 HLoadGlobalGeneric* instr = |
| 5426 New<HLoadGlobalGeneric>(global_object, | 5400 New<HLoadGlobalGeneric>(global_object, |
| 5427 variable->name(), | 5401 variable->name(), |
| 5428 ast_context()->is_for_typeof()); | 5402 ast_context()->is_for_typeof()); |
| 5429 if (FLAG_vector_ics) { | 5403 if (FLAG_vector_ics) { |
| 5430 Handle<SharedFunctionInfo> current_shared = | 5404 Handle<SharedFunctionInfo> current_shared = |
| 5431 function_state()->compilation_info()->shared_info(); | 5405 function_state()->compilation_info()->shared_info(); |
| 5432 instr->SetVectorAndSlot( | 5406 instr->SetVectorAndSlot( |
| 5433 handle(current_shared->feedback_vector(), isolate()), | 5407 handle(current_shared->feedback_vector(), isolate()), |
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5865 return New<HConstant>(value); | 5839 return New<HConstant>(value); |
| 5866 } | 5840 } |
| 5867 } | 5841 } |
| 5868 } | 5842 } |
| 5869 | 5843 |
| 5870 HObjectAccess access = info->access(); | 5844 HObjectAccess access = info->access(); |
| 5871 if (access.representation().IsDouble() && | 5845 if (access.representation().IsDouble() && |
| 5872 (!FLAG_unbox_double_fields || !access.IsInobject())) { | 5846 (!FLAG_unbox_double_fields || !access.IsInobject())) { |
| 5873 // Load the heap number. | 5847 // Load the heap number. |
| 5874 checked_object = Add<HLoadNamedField>( | 5848 checked_object = Add<HLoadNamedField>( |
| 5875 checked_object, static_cast<HValue*>(NULL), | 5849 checked_object, nullptr, |
| 5876 access.WithRepresentation(Representation::Tagged())); | 5850 access.WithRepresentation(Representation::Tagged())); |
| 5877 // Load the double value from it. | 5851 // Load the double value from it. |
| 5878 access = HObjectAccess::ForHeapNumberValue(); | 5852 access = HObjectAccess::ForHeapNumberValue(); |
| 5879 } | 5853 } |
| 5880 | 5854 |
| 5881 SmallMapList* map_list = info->field_maps(); | 5855 SmallMapList* map_list = info->field_maps(); |
| 5882 if (map_list->length() == 0) { | 5856 if (map_list->length() == 0) { |
| 5883 return New<HLoadNamedField>(checked_object, checked_object, access); | 5857 return New<HLoadNamedField>(checked_object, checked_object, access); |
| 5884 } | 5858 } |
| 5885 | 5859 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5917 MUTABLE_HEAP_NUMBER_TYPE); | 5891 MUTABLE_HEAP_NUMBER_TYPE); |
| 5918 AddStoreMapConstant( | 5892 AddStoreMapConstant( |
| 5919 heap_number, isolate()->factory()->mutable_heap_number_map()); | 5893 heap_number, isolate()->factory()->mutable_heap_number_map()); |
| 5920 Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), | 5894 Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), |
| 5921 value); | 5895 value); |
| 5922 instr = New<HStoreNamedField>(checked_object->ActualValue(), | 5896 instr = New<HStoreNamedField>(checked_object->ActualValue(), |
| 5923 heap_number_access, | 5897 heap_number_access, |
| 5924 heap_number); | 5898 heap_number); |
| 5925 } else { | 5899 } else { |
| 5926 // Already holds a HeapNumber; load the box and write its value field. | 5900 // Already holds a HeapNumber; load the box and write its value field. |
| 5927 HInstruction* heap_number = Add<HLoadNamedField>( | 5901 HInstruction* heap_number = |
| 5928 checked_object, static_cast<HValue*>(NULL), heap_number_access); | 5902 Add<HLoadNamedField>(checked_object, nullptr, heap_number_access); |
| 5929 instr = New<HStoreNamedField>(heap_number, | 5903 instr = New<HStoreNamedField>(heap_number, |
| 5930 HObjectAccess::ForHeapNumberValue(), | 5904 HObjectAccess::ForHeapNumberValue(), |
| 5931 value, STORE_TO_INITIALIZED_ENTRY); | 5905 value, STORE_TO_INITIALIZED_ENTRY); |
| 5932 } | 5906 } |
| 5933 } else { | 5907 } else { |
| 5934 if (field_access.representation().IsHeapObject()) { | 5908 if (field_access.representation().IsHeapObject()) { |
| 5935 BuildCheckHeapObject(value); | 5909 BuildCheckHeapObject(value); |
| 5936 } | 5910 } |
| 5937 | 5911 |
| 5938 if (!info->field_maps()->is_empty()) { | 5912 if (!info->field_maps()->is_empty()) { |
| (...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6582 builder.End(); | 6556 builder.End(); |
| 6583 } | 6557 } |
| 6584 } | 6558 } |
| 6585 HInstruction* instr = | 6559 HInstruction* instr = |
| 6586 Add<HStoreGlobalCell>(value, cell, it.property_details()); | 6560 Add<HStoreGlobalCell>(value, cell, it.property_details()); |
| 6587 if (instr->HasObservableSideEffects()) { | 6561 if (instr->HasObservableSideEffects()) { |
| 6588 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6562 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
| 6589 } | 6563 } |
| 6590 } else { | 6564 } else { |
| 6591 HValue* global_object = Add<HLoadNamedField>( | 6565 HValue* global_object = Add<HLoadNamedField>( |
| 6592 context(), static_cast<HValue*>(NULL), | 6566 context(), nullptr, |
| 6593 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); | 6567 HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); |
| 6594 HStoreNamedGeneric* instr = | 6568 HStoreNamedGeneric* instr = |
| 6595 Add<HStoreNamedGeneric>(global_object, var->name(), | 6569 Add<HStoreNamedGeneric>(global_object, var->name(), |
| 6596 value, function_strict_mode()); | 6570 value, function_strict_mode()); |
| 6597 USE(instr); | 6571 USE(instr); |
| 6598 DCHECK(instr->HasObservableSideEffects()); | 6572 DCHECK(instr->HasObservableSideEffects()); |
| 6599 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); | 6573 Add<HSimulate>(ast_id, REMOVABLE_SIMULATE); |
| 6600 } | 6574 } |
| 6601 } | 6575 } |
| 6602 | 6576 |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6866 | 6840 |
| 6867 | 6841 |
| 6868 HInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) { | 6842 HInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) { |
| 6869 if (string->IsConstant()) { | 6843 if (string->IsConstant()) { |
| 6870 HConstant* c_string = HConstant::cast(string); | 6844 HConstant* c_string = HConstant::cast(string); |
| 6871 if (c_string->HasStringValue()) { | 6845 if (c_string->HasStringValue()) { |
| 6872 return Add<HConstant>(c_string->StringValue()->map()->instance_type()); | 6846 return Add<HConstant>(c_string->StringValue()->map()->instance_type()); |
| 6873 } | 6847 } |
| 6874 } | 6848 } |
| 6875 return Add<HLoadNamedField>( | 6849 return Add<HLoadNamedField>( |
| 6876 Add<HLoadNamedField>(string, static_cast<HValue*>(NULL), | 6850 Add<HLoadNamedField>(string, nullptr, HObjectAccess::ForMap()), nullptr, |
| 6877 HObjectAccess::ForMap()), | 6851 HObjectAccess::ForMapInstanceType()); |
| 6878 static_cast<HValue*>(NULL), HObjectAccess::ForMapInstanceType()); | |
| 6879 } | 6852 } |
| 6880 | 6853 |
| 6881 | 6854 |
| 6882 HInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) { | 6855 HInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) { |
| 6883 if (string->IsConstant()) { | 6856 if (string->IsConstant()) { |
| 6884 HConstant* c_string = HConstant::cast(string); | 6857 HConstant* c_string = HConstant::cast(string); |
| 6885 if (c_string->HasStringValue()) { | 6858 if (c_string->HasStringValue()) { |
| 6886 return Add<HConstant>(c_string->StringValue()->length()); | 6859 return Add<HConstant>(c_string->StringValue()->length()); |
| 6887 } | 6860 } |
| 6888 } | 6861 } |
| 6889 return Add<HLoadNamedField>(string, static_cast<HValue*>(NULL), | 6862 return Add<HLoadNamedField>(string, nullptr, |
| 6890 HObjectAccess::ForStringLength()); | 6863 HObjectAccess::ForStringLength()); |
| 6891 } | 6864 } |
| 6892 | 6865 |
| 6893 | 6866 |
| 6894 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( | 6867 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( |
| 6895 PropertyAccessType access_type, | 6868 PropertyAccessType access_type, |
| 6896 Expression* expr, | 6869 Expression* expr, |
| 6897 HValue* object, | 6870 HValue* object, |
| 6898 Handle<String> name, | 6871 Handle<String> name, |
| 6899 HValue* value, | 6872 HValue* value, |
| (...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7570 bool can_invoke_directly = | 7543 bool can_invoke_directly = |
| 7571 dont_adapt_arguments || formal_parameter_count == arity; | 7544 dont_adapt_arguments || formal_parameter_count == arity; |
| 7572 if (can_invoke_directly) { | 7545 if (can_invoke_directly) { |
| 7573 if (jsfun.is_identical_to(current_info()->closure())) { | 7546 if (jsfun.is_identical_to(current_info()->closure())) { |
| 7574 graph()->MarkRecursive(); | 7547 graph()->MarkRecursive(); |
| 7575 } | 7548 } |
| 7576 return NewPlainFunctionCall(target, argument_count, dont_adapt_arguments); | 7549 return NewPlainFunctionCall(target, argument_count, dont_adapt_arguments); |
| 7577 } else { | 7550 } else { |
| 7578 HValue* param_count_value = Add<HConstant>(formal_parameter_count); | 7551 HValue* param_count_value = Add<HConstant>(formal_parameter_count); |
| 7579 HValue* context = Add<HLoadNamedField>( | 7552 HValue* context = Add<HLoadNamedField>( |
| 7580 target, static_cast<HValue*>(NULL), | 7553 target, nullptr, HObjectAccess::ForFunctionContextPointer()); |
| 7581 HObjectAccess::ForFunctionContextPointer()); | |
| 7582 return NewArgumentAdaptorCall(target, context, | 7554 return NewArgumentAdaptorCall(target, context, |
| 7583 argument_count, param_count_value); | 7555 argument_count, param_count_value); |
| 7584 } | 7556 } |
| 7585 UNREACHABLE(); | 7557 UNREACHABLE(); |
| 7586 return NULL; | 7558 return NULL; |
| 7587 } | 7559 } |
| 7588 | 7560 |
| 7589 | 7561 |
| 7590 class FunctionSorter { | 7562 class FunctionSorter { |
| 7591 public: | 7563 public: |
| (...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8358 if (!IsFastElementsKind(elements_kind)) return false; | 8330 if (!IsFastElementsKind(elements_kind)) return false; |
| 8359 if (receiver_map->is_observed()) return false; | 8331 if (receiver_map->is_observed()) return false; |
| 8360 if (!receiver_map->is_extensible()) return false; | 8332 if (!receiver_map->is_extensible()) return false; |
| 8361 | 8333 |
| 8362 Drop(args_count_no_receiver); | 8334 Drop(args_count_no_receiver); |
| 8363 HValue* result; | 8335 HValue* result; |
| 8364 HValue* reduced_length; | 8336 HValue* reduced_length; |
| 8365 HValue* receiver = Pop(); | 8337 HValue* receiver = Pop(); |
| 8366 | 8338 |
| 8367 HValue* checked_object = AddCheckMap(receiver, receiver_map); | 8339 HValue* checked_object = AddCheckMap(receiver, receiver_map); |
| 8368 HValue* length = Add<HLoadNamedField>( | 8340 HValue* length = |
| 8369 checked_object, static_cast<HValue*>(NULL), | 8341 Add<HLoadNamedField>(checked_object, nullptr, |
| 8370 HObjectAccess::ForArrayLength(elements_kind)); | 8342 HObjectAccess::ForArrayLength(elements_kind)); |
| 8371 | 8343 |
| 8372 Drop(1); // Function. | 8344 Drop(1); // Function. |
| 8373 | 8345 |
| 8374 { NoObservableSideEffectsScope scope(this); | 8346 { NoObservableSideEffectsScope scope(this); |
| 8375 IfBuilder length_checker(this); | 8347 IfBuilder length_checker(this); |
| 8376 | 8348 |
| 8377 HValue* bounds_check = length_checker.If<HCompareNumericAndBranch>( | 8349 HValue* bounds_check = length_checker.If<HCompareNumericAndBranch>( |
| 8378 length, graph()->GetConstant0(), Token::EQ); | 8350 length, graph()->GetConstant0(), Token::EQ); |
| 8379 length_checker.Then(); | 8351 length_checker.Then(); |
| 8380 | 8352 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8441 HValue* value_to_push = Pop(); | 8413 HValue* value_to_push = Pop(); |
| 8442 HValue* array = Pop(); | 8414 HValue* array = Pop(); |
| 8443 Drop(1); // Drop function. | 8415 Drop(1); // Drop function. |
| 8444 | 8416 |
| 8445 HInstruction* new_size = NULL; | 8417 HInstruction* new_size = NULL; |
| 8446 HValue* length = NULL; | 8418 HValue* length = NULL; |
| 8447 | 8419 |
| 8448 { | 8420 { |
| 8449 NoObservableSideEffectsScope scope(this); | 8421 NoObservableSideEffectsScope scope(this); |
| 8450 | 8422 |
| 8451 length = Add<HLoadNamedField>(array, static_cast<HValue*>(NULL), | 8423 length = Add<HLoadNamedField>( |
| 8452 HObjectAccess::ForArrayLength(elements_kind)); | 8424 array, nullptr, HObjectAccess::ForArrayLength(elements_kind)); |
| 8453 | 8425 |
| 8454 new_size = AddUncasted<HAdd>(length, graph()->GetConstant1()); | 8426 new_size = AddUncasted<HAdd>(length, graph()->GetConstant1()); |
| 8455 | 8427 |
| 8456 bool is_array = receiver_map->instance_type() == JS_ARRAY_TYPE; | 8428 bool is_array = receiver_map->instance_type() == JS_ARRAY_TYPE; |
| 8457 BuildUncheckedMonomorphicElementAccess(array, length, | 8429 BuildUncheckedMonomorphicElementAccess(array, length, |
| 8458 value_to_push, is_array, | 8430 value_to_push, is_array, |
| 8459 elements_kind, STORE, | 8431 elements_kind, STORE, |
| 8460 NEVER_RETURN_HOLE, | 8432 NEVER_RETURN_HOLE, |
| 8461 STORE_AND_GROW_NO_TRANSITION); | 8433 STORE_AND_GROW_NO_TRANSITION); |
| 8462 | 8434 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8495 | 8467 |
| 8496 Drop(args_count_no_receiver); | 8468 Drop(args_count_no_receiver); |
| 8497 HValue* receiver = Pop(); | 8469 HValue* receiver = Pop(); |
| 8498 HValue* function = Pop(); | 8470 HValue* function = Pop(); |
| 8499 HValue* result; | 8471 HValue* result; |
| 8500 | 8472 |
| 8501 { | 8473 { |
| 8502 NoObservableSideEffectsScope scope(this); | 8474 NoObservableSideEffectsScope scope(this); |
| 8503 | 8475 |
| 8504 HValue* length = Add<HLoadNamedField>( | 8476 HValue* length = Add<HLoadNamedField>( |
| 8505 receiver, static_cast<HValue*>(NULL), | 8477 receiver, nullptr, HObjectAccess::ForArrayLength(kind)); |
| 8506 HObjectAccess::ForArrayLength(kind)); | |
| 8507 | 8478 |
| 8508 IfBuilder if_lengthiszero(this); | 8479 IfBuilder if_lengthiszero(this); |
| 8509 HValue* lengthiszero = if_lengthiszero.If<HCompareNumericAndBranch>( | 8480 HValue* lengthiszero = if_lengthiszero.If<HCompareNumericAndBranch>( |
| 8510 length, graph()->GetConstant0(), Token::EQ); | 8481 length, graph()->GetConstant0(), Token::EQ); |
| 8511 if_lengthiszero.Then(); | 8482 if_lengthiszero.Then(); |
| 8512 { | 8483 { |
| 8513 if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined()); | 8484 if (!ast_context()->IsEffect()) Push(graph()->GetConstantUndefined()); |
| 8514 } | 8485 } |
| 8515 if_lengthiszero.Else(); | 8486 if_lengthiszero.Else(); |
| 8516 { | 8487 { |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9003 if (IsFastDoubleElementsKind(kind) || IsFastSmiElementsKind(kind)) { | 8974 if (IsFastDoubleElementsKind(kind) || IsFastSmiElementsKind(kind)) { |
| 9004 // Make sure that we can actually compare numbers correctly below, see | 8975 // Make sure that we can actually compare numbers correctly below, see |
| 9005 // https://code.google.com/p/chromium/issues/detail?id=407946 for details. | 8976 // https://code.google.com/p/chromium/issues/detail?id=407946 for details. |
| 9006 search_element = AddUncasted<HForceRepresentation>( | 8977 search_element = AddUncasted<HForceRepresentation>( |
| 9007 search_element, IsFastSmiElementsKind(kind) ? Representation::Smi() | 8978 search_element, IsFastSmiElementsKind(kind) ? Representation::Smi() |
| 9008 : Representation::Double()); | 8979 : Representation::Double()); |
| 9009 | 8980 |
| 9010 LoopBuilder loop(this, context(), direction); | 8981 LoopBuilder loop(this, context(), direction); |
| 9011 { | 8982 { |
| 9012 HValue* index = loop.BeginBody(initial, terminating, token); | 8983 HValue* index = loop.BeginBody(initial, terminating, token); |
| 9013 HValue* element = AddUncasted<HLoadKeyed>( | 8984 HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr, kind, |
| 9014 elements, index, static_cast<HValue*>(NULL), | 8985 ALLOW_RETURN_HOLE); |
| 9015 kind, ALLOW_RETURN_HOLE); | |
| 9016 IfBuilder if_issame(this); | 8986 IfBuilder if_issame(this); |
| 9017 if_issame.If<HCompareNumericAndBranch>(element, search_element, | 8987 if_issame.If<HCompareNumericAndBranch>(element, search_element, |
| 9018 Token::EQ_STRICT); | 8988 Token::EQ_STRICT); |
| 9019 if_issame.Then(); | 8989 if_issame.Then(); |
| 9020 { | 8990 { |
| 9021 Drop(1); | 8991 Drop(1); |
| 9022 Push(index); | 8992 Push(index); |
| 9023 loop.Break(); | 8993 loop.Break(); |
| 9024 } | 8994 } |
| 9025 if_issame.End(); | 8995 if_issame.End(); |
| 9026 } | 8996 } |
| 9027 loop.EndBody(); | 8997 loop.EndBody(); |
| 9028 } else { | 8998 } else { |
| 9029 IfBuilder if_isstring(this); | 8999 IfBuilder if_isstring(this); |
| 9030 if_isstring.If<HIsStringAndBranch>(search_element); | 9000 if_isstring.If<HIsStringAndBranch>(search_element); |
| 9031 if_isstring.Then(); | 9001 if_isstring.Then(); |
| 9032 { | 9002 { |
| 9033 LoopBuilder loop(this, context(), direction); | 9003 LoopBuilder loop(this, context(), direction); |
| 9034 { | 9004 { |
| 9035 HValue* index = loop.BeginBody(initial, terminating, token); | 9005 HValue* index = loop.BeginBody(initial, terminating, token); |
| 9036 HValue* element = AddUncasted<HLoadKeyed>( | 9006 HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr, |
| 9037 elements, index, static_cast<HValue*>(NULL), | 9007 kind, ALLOW_RETURN_HOLE); |
| 9038 kind, ALLOW_RETURN_HOLE); | |
| 9039 IfBuilder if_issame(this); | 9008 IfBuilder if_issame(this); |
| 9040 if_issame.If<HIsStringAndBranch>(element); | 9009 if_issame.If<HIsStringAndBranch>(element); |
| 9041 if_issame.AndIf<HStringCompareAndBranch>( | 9010 if_issame.AndIf<HStringCompareAndBranch>( |
| 9042 element, search_element, Token::EQ_STRICT); | 9011 element, search_element, Token::EQ_STRICT); |
| 9043 if_issame.Then(); | 9012 if_issame.Then(); |
| 9044 { | 9013 { |
| 9045 Drop(1); | 9014 Drop(1); |
| 9046 Push(index); | 9015 Push(index); |
| 9047 loop.Break(); | 9016 loop.Break(); |
| 9048 } | 9017 } |
| 9049 if_issame.End(); | 9018 if_issame.End(); |
| 9050 } | 9019 } |
| 9051 loop.EndBody(); | 9020 loop.EndBody(); |
| 9052 } | 9021 } |
| 9053 if_isstring.Else(); | 9022 if_isstring.Else(); |
| 9054 { | 9023 { |
| 9055 IfBuilder if_isnumber(this); | 9024 IfBuilder if_isnumber(this); |
| 9056 if_isnumber.If<HIsSmiAndBranch>(search_element); | 9025 if_isnumber.If<HIsSmiAndBranch>(search_element); |
| 9057 if_isnumber.OrIf<HCompareMap>( | 9026 if_isnumber.OrIf<HCompareMap>( |
| 9058 search_element, isolate()->factory()->heap_number_map()); | 9027 search_element, isolate()->factory()->heap_number_map()); |
| 9059 if_isnumber.Then(); | 9028 if_isnumber.Then(); |
| 9060 { | 9029 { |
| 9061 HValue* search_number = | 9030 HValue* search_number = |
| 9062 AddUncasted<HForceRepresentation>(search_element, | 9031 AddUncasted<HForceRepresentation>(search_element, |
| 9063 Representation::Double()); | 9032 Representation::Double()); |
| 9064 LoopBuilder loop(this, context(), direction); | 9033 LoopBuilder loop(this, context(), direction); |
| 9065 { | 9034 { |
| 9066 HValue* index = loop.BeginBody(initial, terminating, token); | 9035 HValue* index = loop.BeginBody(initial, terminating, token); |
| 9067 HValue* element = AddUncasted<HLoadKeyed>( | 9036 HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr, |
| 9068 elements, index, static_cast<HValue*>(NULL), | 9037 kind, ALLOW_RETURN_HOLE); |
| 9069 kind, ALLOW_RETURN_HOLE); | |
| 9070 | 9038 |
| 9071 IfBuilder if_element_isnumber(this); | 9039 IfBuilder if_element_isnumber(this); |
| 9072 if_element_isnumber.If<HIsSmiAndBranch>(element); | 9040 if_element_isnumber.If<HIsSmiAndBranch>(element); |
| 9073 if_element_isnumber.OrIf<HCompareMap>( | 9041 if_element_isnumber.OrIf<HCompareMap>( |
| 9074 element, isolate()->factory()->heap_number_map()); | 9042 element, isolate()->factory()->heap_number_map()); |
| 9075 if_element_isnumber.Then(); | 9043 if_element_isnumber.Then(); |
| 9076 { | 9044 { |
| 9077 HValue* number = | 9045 HValue* number = |
| 9078 AddUncasted<HForceRepresentation>(element, | 9046 AddUncasted<HForceRepresentation>(element, |
| 9079 Representation::Double()); | 9047 Representation::Double()); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 9090 } | 9058 } |
| 9091 if_element_isnumber.End(); | 9059 if_element_isnumber.End(); |
| 9092 } | 9060 } |
| 9093 loop.EndBody(); | 9061 loop.EndBody(); |
| 9094 } | 9062 } |
| 9095 if_isnumber.Else(); | 9063 if_isnumber.Else(); |
| 9096 { | 9064 { |
| 9097 LoopBuilder loop(this, context(), direction); | 9065 LoopBuilder loop(this, context(), direction); |
| 9098 { | 9066 { |
| 9099 HValue* index = loop.BeginBody(initial, terminating, token); | 9067 HValue* index = loop.BeginBody(initial, terminating, token); |
| 9100 HValue* element = AddUncasted<HLoadKeyed>( | 9068 HValue* element = AddUncasted<HLoadKeyed>(elements, index, nullptr, |
| 9101 elements, index, static_cast<HValue*>(NULL), | 9069 kind, ALLOW_RETURN_HOLE); |
| 9102 kind, ALLOW_RETURN_HOLE); | |
| 9103 IfBuilder if_issame(this); | 9070 IfBuilder if_issame(this); |
| 9104 if_issame.If<HCompareObjectEqAndBranch>( | 9071 if_issame.If<HCompareObjectEqAndBranch>( |
| 9105 element, search_element); | 9072 element, search_element); |
| 9106 if_issame.Then(); | 9073 if_issame.Then(); |
| 9107 { | 9074 { |
| 9108 Drop(1); | 9075 Drop(1); |
| 9109 Push(index); | 9076 Push(index); |
| 9110 loop.Break(); | 9077 loop.Break(); |
| 9111 } | 9078 } |
| 9112 if_issame.End(); | 9079 if_issame.End(); |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9613 obj, | 9580 obj, |
| 9614 HObjectAccess::ForJSArrayBufferViewByteLength(), | 9581 HObjectAccess::ForJSArrayBufferViewByteLength(), |
| 9615 byte_length); | 9582 byte_length); |
| 9616 | 9583 |
| 9617 if (buffer != NULL) { | 9584 if (buffer != NULL) { |
| 9618 Add<HStoreNamedField>( | 9585 Add<HStoreNamedField>( |
| 9619 obj, | 9586 obj, |
| 9620 HObjectAccess::ForJSArrayBufferViewBuffer(), buffer); | 9587 HObjectAccess::ForJSArrayBufferViewBuffer(), buffer); |
| 9621 HObjectAccess weak_first_view_access = | 9588 HObjectAccess weak_first_view_access = |
| 9622 HObjectAccess::ForJSArrayBufferWeakFirstView(); | 9589 HObjectAccess::ForJSArrayBufferWeakFirstView(); |
| 9623 Add<HStoreNamedField>(obj, | 9590 Add<HStoreNamedField>( |
| 9624 HObjectAccess::ForJSArrayBufferViewWeakNext(), | 9591 obj, HObjectAccess::ForJSArrayBufferViewWeakNext(), |
| 9625 Add<HLoadNamedField>(buffer, | 9592 Add<HLoadNamedField>(buffer, nullptr, weak_first_view_access)); |
| 9626 static_cast<HValue*>(NULL), | |
| 9627 weak_first_view_access)); | |
| 9628 Add<HStoreNamedField>(buffer, weak_first_view_access, obj); | 9593 Add<HStoreNamedField>(buffer, weak_first_view_access, obj); |
| 9629 } else { | 9594 } else { |
| 9630 Add<HStoreNamedField>( | 9595 Add<HStoreNamedField>( |
| 9631 obj, | 9596 obj, |
| 9632 HObjectAccess::ForJSArrayBufferViewBuffer(), | 9597 HObjectAccess::ForJSArrayBufferViewBuffer(), |
| 9633 Add<HConstant>(static_cast<int32_t>(0))); | 9598 Add<HConstant>(static_cast<int32_t>(0))); |
| 9634 Add<HStoreNamedField>(obj, | 9599 Add<HStoreNamedField>(obj, |
| 9635 HObjectAccess::ForJSArrayBufferViewWeakNext(), | 9600 HObjectAccess::ForJSArrayBufferViewWeakNext(), |
| 9636 graph()->GetConstantUndefined()); | 9601 graph()->GetConstantUndefined()); |
| 9637 } | 9602 } |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9697 Add<HConstant>(ExternalArray::kAlignedSize), | 9662 Add<HConstant>(ExternalArray::kAlignedSize), |
| 9698 HType::HeapObject(), | 9663 HType::HeapObject(), |
| 9699 NOT_TENURED, | 9664 NOT_TENURED, |
| 9700 external_array_map->instance_type()); | 9665 external_array_map->instance_type()); |
| 9701 | 9666 |
| 9702 AddStoreMapConstant(elements, external_array_map); | 9667 AddStoreMapConstant(elements, external_array_map); |
| 9703 Add<HStoreNamedField>(elements, | 9668 Add<HStoreNamedField>(elements, |
| 9704 HObjectAccess::ForFixedArrayLength(), length); | 9669 HObjectAccess::ForFixedArrayLength(), length); |
| 9705 | 9670 |
| 9706 HValue* backing_store = Add<HLoadNamedField>( | 9671 HValue* backing_store = Add<HLoadNamedField>( |
| 9707 buffer, static_cast<HValue*>(NULL), | 9672 buffer, nullptr, HObjectAccess::ForJSArrayBufferBackingStore()); |
| 9708 HObjectAccess::ForJSArrayBufferBackingStore()); | |
| 9709 | 9673 |
| 9710 HValue* typed_array_start; | 9674 HValue* typed_array_start; |
| 9711 if (is_zero_byte_offset) { | 9675 if (is_zero_byte_offset) { |
| 9712 typed_array_start = backing_store; | 9676 typed_array_start = backing_store; |
| 9713 } else { | 9677 } else { |
| 9714 HInstruction* external_pointer = | 9678 HInstruction* external_pointer = |
| 9715 AddUncasted<HAdd>(backing_store, byte_offset); | 9679 AddUncasted<HAdd>(backing_store, byte_offset); |
| 9716 // Arguments are checked prior to call to TypedArrayInitialize, | 9680 // Arguments are checked prior to call to TypedArrayInitialize, |
| 9717 // including byte_offset. | 9681 // including byte_offset. |
| 9718 external_pointer->ClearFlag(HValue::kCanOverflow); | 9682 external_pointer->ClearFlag(HValue::kCanOverflow); |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9916 return ast_context()->ReturnInstruction(result, expr->id()); | 9880 return ast_context()->ReturnInstruction(result, expr->id()); |
| 9917 } | 9881 } |
| 9918 | 9882 |
| 9919 | 9883 |
| 9920 void HOptimizedGraphBuilder::GenerateArrayBufferGetByteLength( | 9884 void HOptimizedGraphBuilder::GenerateArrayBufferGetByteLength( |
| 9921 CallRuntime* expr) { | 9885 CallRuntime* expr) { |
| 9922 DCHECK(expr->arguments()->length() == 1); | 9886 DCHECK(expr->arguments()->length() == 1); |
| 9923 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); | 9887 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); |
| 9924 HValue* buffer = Pop(); | 9888 HValue* buffer = Pop(); |
| 9925 HInstruction* result = New<HLoadNamedField>( | 9889 HInstruction* result = New<HLoadNamedField>( |
| 9926 buffer, | 9890 buffer, nullptr, HObjectAccess::ForJSArrayBufferByteLength()); |
| 9927 static_cast<HValue*>(NULL), | |
| 9928 HObjectAccess::ForJSArrayBufferByteLength()); | |
| 9929 return ast_context()->ReturnInstruction(result, expr->id()); | 9891 return ast_context()->ReturnInstruction(result, expr->id()); |
| 9930 } | 9892 } |
| 9931 | 9893 |
| 9932 | 9894 |
| 9933 void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength( | 9895 void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength( |
| 9934 CallRuntime* expr) { | 9896 CallRuntime* expr) { |
| 9935 DCHECK(expr->arguments()->length() == 1); | 9897 DCHECK(expr->arguments()->length() == 1); |
| 9936 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); | 9898 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); |
| 9937 HValue* buffer = Pop(); | 9899 HValue* buffer = Pop(); |
| 9938 HInstruction* result = New<HLoadNamedField>( | 9900 HInstruction* result = New<HLoadNamedField>( |
| 9939 buffer, | 9901 buffer, nullptr, HObjectAccess::ForJSArrayBufferViewByteLength()); |
| 9940 static_cast<HValue*>(NULL), | |
| 9941 HObjectAccess::ForJSArrayBufferViewByteLength()); | |
| 9942 return ast_context()->ReturnInstruction(result, expr->id()); | 9902 return ast_context()->ReturnInstruction(result, expr->id()); |
| 9943 } | 9903 } |
| 9944 | 9904 |
| 9945 | 9905 |
| 9946 void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset( | 9906 void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset( |
| 9947 CallRuntime* expr) { | 9907 CallRuntime* expr) { |
| 9948 DCHECK(expr->arguments()->length() == 1); | 9908 DCHECK(expr->arguments()->length() == 1); |
| 9949 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); | 9909 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); |
| 9950 HValue* buffer = Pop(); | 9910 HValue* buffer = Pop(); |
| 9951 HInstruction* result = New<HLoadNamedField>( | 9911 HInstruction* result = New<HLoadNamedField>( |
| 9952 buffer, | 9912 buffer, nullptr, HObjectAccess::ForJSArrayBufferViewByteOffset()); |
| 9953 static_cast<HValue*>(NULL), | |
| 9954 HObjectAccess::ForJSArrayBufferViewByteOffset()); | |
| 9955 return ast_context()->ReturnInstruction(result, expr->id()); | 9913 return ast_context()->ReturnInstruction(result, expr->id()); |
| 9956 } | 9914 } |
| 9957 | 9915 |
| 9958 | 9916 |
| 9959 void HOptimizedGraphBuilder::GenerateTypedArrayGetLength( | 9917 void HOptimizedGraphBuilder::GenerateTypedArrayGetLength( |
| 9960 CallRuntime* expr) { | 9918 CallRuntime* expr) { |
| 9961 DCHECK(expr->arguments()->length() == 1); | 9919 DCHECK(expr->arguments()->length() == 1); |
| 9962 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); | 9920 CHECK_ALIVE(VisitForValue(expr->arguments()->at(0))); |
| 9963 HValue* buffer = Pop(); | 9921 HValue* buffer = Pop(); |
| 9964 HInstruction* result = New<HLoadNamedField>( | 9922 HInstruction* result = New<HLoadNamedField>( |
| 9965 buffer, | 9923 buffer, nullptr, HObjectAccess::ForJSTypedArrayLength()); |
| 9966 static_cast<HValue*>(NULL), | |
| 9967 HObjectAccess::ForJSTypedArrayLength()); | |
| 9968 return ast_context()->ReturnInstruction(result, expr->id()); | 9924 return ast_context()->ReturnInstruction(result, expr->id()); |
| 9969 } | 9925 } |
| 9970 | 9926 |
| 9971 | 9927 |
| 9972 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { | 9928 void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
| 9973 DCHECK(!HasStackOverflow()); | 9929 DCHECK(!HasStackOverflow()); |
| 9974 DCHECK(current_block() != NULL); | 9930 DCHECK(current_block() != NULL); |
| 9975 DCHECK(current_block()->HasPredecessor()); | 9931 DCHECK(current_block()->HasPredecessor()); |
| 9976 if (expr->is_jsruntime()) { | 9932 if (expr->is_jsruntime()) { |
| 9977 return Bailout(kCallToAJavaScriptRuntimeFunction); | 9933 return Bailout(kCallToAJavaScriptRuntimeFunction); |
| (...skipping 1386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11364 | 11320 |
| 11365 | 11321 |
| 11366 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( | 11322 void HOptimizedGraphBuilder::BuildEmitFixedDoubleArray( |
| 11367 Handle<FixedArrayBase> elements, | 11323 Handle<FixedArrayBase> elements, |
| 11368 ElementsKind kind, | 11324 ElementsKind kind, |
| 11369 HValue* object_elements) { | 11325 HValue* object_elements) { |
| 11370 HInstruction* boilerplate_elements = Add<HConstant>(elements); | 11326 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
| 11371 int elements_length = elements->length(); | 11327 int elements_length = elements->length(); |
| 11372 for (int i = 0; i < elements_length; i++) { | 11328 for (int i = 0; i < elements_length; i++) { |
| 11373 HValue* key_constant = Add<HConstant>(i); | 11329 HValue* key_constant = Add<HConstant>(i); |
| 11374 HInstruction* value_instruction = | 11330 HInstruction* value_instruction = Add<HLoadKeyed>( |
| 11375 Add<HLoadKeyed>(boilerplate_elements, key_constant, | 11331 boilerplate_elements, key_constant, nullptr, kind, ALLOW_RETURN_HOLE); |
| 11376 static_cast<HValue*>(NULL), kind, | |
| 11377 ALLOW_RETURN_HOLE); | |
| 11378 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, | 11332 HInstruction* store = Add<HStoreKeyed>(object_elements, key_constant, |
| 11379 value_instruction, kind); | 11333 value_instruction, kind); |
| 11380 store->SetFlag(HValue::kAllowUndefinedAsNaN); | 11334 store->SetFlag(HValue::kAllowUndefinedAsNaN); |
| 11381 } | 11335 } |
| 11382 } | 11336 } |
| 11383 | 11337 |
| 11384 | 11338 |
| 11385 void HOptimizedGraphBuilder::BuildEmitFixedArray( | 11339 void HOptimizedGraphBuilder::BuildEmitFixedArray( |
| 11386 Handle<FixedArrayBase> elements, | 11340 Handle<FixedArrayBase> elements, |
| 11387 ElementsKind kind, | 11341 ElementsKind kind, |
| 11388 HValue* object_elements, | 11342 HValue* object_elements, |
| 11389 AllocationSiteUsageContext* site_context) { | 11343 AllocationSiteUsageContext* site_context) { |
| 11390 HInstruction* boilerplate_elements = Add<HConstant>(elements); | 11344 HInstruction* boilerplate_elements = Add<HConstant>(elements); |
| 11391 int elements_length = elements->length(); | 11345 int elements_length = elements->length(); |
| 11392 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); | 11346 Handle<FixedArray> fast_elements = Handle<FixedArray>::cast(elements); |
| 11393 for (int i = 0; i < elements_length; i++) { | 11347 for (int i = 0; i < elements_length; i++) { |
| 11394 Handle<Object> value(fast_elements->get(i), isolate()); | 11348 Handle<Object> value(fast_elements->get(i), isolate()); |
| 11395 HValue* key_constant = Add<HConstant>(i); | 11349 HValue* key_constant = Add<HConstant>(i); |
| 11396 if (value->IsJSObject()) { | 11350 if (value->IsJSObject()) { |
| 11397 Handle<JSObject> value_object = Handle<JSObject>::cast(value); | 11351 Handle<JSObject> value_object = Handle<JSObject>::cast(value); |
| 11398 Handle<AllocationSite> current_site = site_context->EnterNewScope(); | 11352 Handle<AllocationSite> current_site = site_context->EnterNewScope(); |
| 11399 HInstruction* result = | 11353 HInstruction* result = |
| 11400 BuildFastLiteral(value_object, site_context); | 11354 BuildFastLiteral(value_object, site_context); |
| 11401 site_context->ExitScope(current_site, value_object); | 11355 site_context->ExitScope(current_site, value_object); |
| 11402 Add<HStoreKeyed>(object_elements, key_constant, result, kind); | 11356 Add<HStoreKeyed>(object_elements, key_constant, result, kind); |
| 11403 } else { | 11357 } else { |
| 11404 ElementsKind copy_kind = | 11358 ElementsKind copy_kind = |
| 11405 kind == FAST_HOLEY_SMI_ELEMENTS ? FAST_HOLEY_ELEMENTS : kind; | 11359 kind == FAST_HOLEY_SMI_ELEMENTS ? FAST_HOLEY_ELEMENTS : kind; |
| 11406 HInstruction* value_instruction = Add<HLoadKeyed>( | 11360 HInstruction* value_instruction = |
| 11407 boilerplate_elements, key_constant, static_cast<HValue*>(NULL), | 11361 Add<HLoadKeyed>(boilerplate_elements, key_constant, nullptr, |
| 11408 copy_kind, ALLOW_RETURN_HOLE); | 11362 copy_kind, ALLOW_RETURN_HOLE); |
| 11409 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, | 11363 Add<HStoreKeyed>(object_elements, key_constant, value_instruction, |
| 11410 copy_kind); | 11364 copy_kind); |
| 11411 } | 11365 } |
| 11412 } | 11366 } |
| 11413 } | 11367 } |
| 11414 | 11368 |
| 11415 | 11369 |
| 11416 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { | 11370 void HOptimizedGraphBuilder::VisitThisFunction(ThisFunction* expr) { |
| 11417 DCHECK(!HasStackOverflow()); | 11371 DCHECK(!HasStackOverflow()); |
| 11418 DCHECK(current_block() != NULL); | 11372 DCHECK(current_block() != NULL); |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11649 void HOptimizedGraphBuilder::GenerateIsJSProxy(CallRuntime* call) { | 11603 void HOptimizedGraphBuilder::GenerateIsJSProxy(CallRuntime* call) { |
| 11650 DCHECK(call->arguments()->length() == 1); | 11604 DCHECK(call->arguments()->length() == 1); |
| 11651 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 11605 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 11652 HValue* value = Pop(); | 11606 HValue* value = Pop(); |
| 11653 HIfContinuation continuation; | 11607 HIfContinuation continuation; |
| 11654 IfBuilder if_proxy(this); | 11608 IfBuilder if_proxy(this); |
| 11655 | 11609 |
| 11656 HValue* smicheck = if_proxy.IfNot<HIsSmiAndBranch>(value); | 11610 HValue* smicheck = if_proxy.IfNot<HIsSmiAndBranch>(value); |
| 11657 if_proxy.And(); | 11611 if_proxy.And(); |
| 11658 HValue* map = Add<HLoadNamedField>(value, smicheck, HObjectAccess::ForMap()); | 11612 HValue* map = Add<HLoadNamedField>(value, smicheck, HObjectAccess::ForMap()); |
| 11659 HValue* instance_type = Add<HLoadNamedField>( | 11613 HValue* instance_type = |
| 11660 map, static_cast<HValue*>(NULL), HObjectAccess::ForMapInstanceType()); | 11614 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapInstanceType()); |
| 11661 if_proxy.If<HCompareNumericAndBranch>( | 11615 if_proxy.If<HCompareNumericAndBranch>( |
| 11662 instance_type, Add<HConstant>(FIRST_JS_PROXY_TYPE), Token::GTE); | 11616 instance_type, Add<HConstant>(FIRST_JS_PROXY_TYPE), Token::GTE); |
| 11663 if_proxy.And(); | 11617 if_proxy.And(); |
| 11664 if_proxy.If<HCompareNumericAndBranch>( | 11618 if_proxy.If<HCompareNumericAndBranch>( |
| 11665 instance_type, Add<HConstant>(LAST_JS_PROXY_TYPE), Token::LTE); | 11619 instance_type, Add<HConstant>(LAST_JS_PROXY_TYPE), Token::LTE); |
| 11666 | 11620 |
| 11667 if_proxy.CaptureContinuation(&continuation); | 11621 if_proxy.CaptureContinuation(&continuation); |
| 11668 return ast_context()->ReturnContinuation(&continuation, call->id()); | 11622 return ast_context()->ReturnContinuation(&continuation, call->id()); |
| 11669 } | 11623 } |
| 11670 | 11624 |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12127 } | 12081 } |
| 12128 | 12082 |
| 12129 | 12083 |
| 12130 template <typename CollectionType> | 12084 template <typename CollectionType> |
| 12131 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableHashToEntry( | 12085 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableHashToEntry( |
| 12132 HValue* table, HValue* hash, HValue* num_buckets) { | 12086 HValue* table, HValue* hash, HValue* num_buckets) { |
| 12133 HValue* bucket = BuildOrderedHashTableHashToBucket(hash, num_buckets); | 12087 HValue* bucket = BuildOrderedHashTableHashToBucket(hash, num_buckets); |
| 12134 HValue* entry_index = AddUncasted<HAdd>( | 12088 HValue* entry_index = AddUncasted<HAdd>( |
| 12135 bucket, Add<HConstant>(CollectionType::kHashTableStartIndex)); | 12089 bucket, Add<HConstant>(CollectionType::kHashTableStartIndex)); |
| 12136 entry_index->ClearFlag(HValue::kCanOverflow); | 12090 entry_index->ClearFlag(HValue::kCanOverflow); |
| 12137 HValue* entry = Add<HLoadKeyed>(table, entry_index, | 12091 HValue* entry = Add<HLoadKeyed>(table, entry_index, nullptr, FAST_ELEMENTS); |
| 12138 static_cast<HValue*>(NULL), FAST_ELEMENTS); | |
| 12139 entry->set_type(HType::Smi()); | 12092 entry->set_type(HType::Smi()); |
| 12140 return entry; | 12093 return entry; |
| 12141 } | 12094 } |
| 12142 | 12095 |
| 12143 | 12096 |
| 12144 template <typename CollectionType> | 12097 template <typename CollectionType> |
| 12145 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableEntryToIndex( | 12098 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableEntryToIndex( |
| 12146 HValue* entry, HValue* num_buckets) { | 12099 HValue* entry, HValue* num_buckets) { |
| 12147 HValue* index = | 12100 HValue* index = |
| 12148 AddUncasted<HMul>(entry, Add<HConstant>(CollectionType::kEntrySize)); | 12101 AddUncasted<HMul>(entry, Add<HConstant>(CollectionType::kEntrySize)); |
| 12149 index->ClearFlag(HValue::kCanOverflow); | 12102 index->ClearFlag(HValue::kCanOverflow); |
| 12150 index = AddUncasted<HAdd>(index, num_buckets); | 12103 index = AddUncasted<HAdd>(index, num_buckets); |
| 12151 index->ClearFlag(HValue::kCanOverflow); | 12104 index->ClearFlag(HValue::kCanOverflow); |
| 12152 index = AddUncasted<HAdd>( | 12105 index = AddUncasted<HAdd>( |
| 12153 index, Add<HConstant>(CollectionType::kHashTableStartIndex)); | 12106 index, Add<HConstant>(CollectionType::kHashTableStartIndex)); |
| 12154 index->ClearFlag(HValue::kCanOverflow); | 12107 index->ClearFlag(HValue::kCanOverflow); |
| 12155 return index; | 12108 return index; |
| 12156 } | 12109 } |
| 12157 | 12110 |
| 12158 | 12111 |
| 12159 template <typename CollectionType> | 12112 template <typename CollectionType> |
| 12160 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableFindEntry(HValue* table, | 12113 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableFindEntry(HValue* table, |
| 12161 HValue* key, | 12114 HValue* key, |
| 12162 HValue* hash) { | 12115 HValue* hash) { |
| 12163 HValue* num_buckets = Add<HLoadNamedField>( | 12116 HValue* num_buckets = Add<HLoadNamedField>( |
| 12164 table, static_cast<HValue*>(NULL), | 12117 table, nullptr, |
| 12165 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>()); | 12118 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>()); |
| 12166 | 12119 |
| 12167 HValue* entry = BuildOrderedHashTableHashToEntry<CollectionType>(table, hash, | 12120 HValue* entry = BuildOrderedHashTableHashToEntry<CollectionType>(table, hash, |
| 12168 num_buckets); | 12121 num_buckets); |
| 12169 | 12122 |
| 12170 Push(entry); | 12123 Push(entry); |
| 12171 | 12124 |
| 12172 LoopBuilder loop(this); | 12125 LoopBuilder loop(this); |
| 12173 loop.BeginBody(1); | 12126 loop.BeginBody(1); |
| 12174 | 12127 |
| 12175 entry = Pop(); | 12128 entry = Pop(); |
| 12176 | 12129 |
| 12177 { | 12130 { |
| 12178 IfBuilder if_not_found(this); | 12131 IfBuilder if_not_found(this); |
| 12179 if_not_found.If<HCompareNumericAndBranch>( | 12132 if_not_found.If<HCompareNumericAndBranch>( |
| 12180 entry, Add<HConstant>(CollectionType::kNotFound), Token::EQ); | 12133 entry, Add<HConstant>(CollectionType::kNotFound), Token::EQ); |
| 12181 if_not_found.Then(); | 12134 if_not_found.Then(); |
| 12182 Push(entry); | 12135 Push(entry); |
| 12183 loop.Break(); | 12136 loop.Break(); |
| 12184 } | 12137 } |
| 12185 | 12138 |
| 12186 HValue* key_index = | 12139 HValue* key_index = |
| 12187 BuildOrderedHashTableEntryToIndex<CollectionType>(entry, num_buckets); | 12140 BuildOrderedHashTableEntryToIndex<CollectionType>(entry, num_buckets); |
| 12188 HValue* candidate_key = Add<HLoadKeyed>( | 12141 HValue* candidate_key = |
| 12189 table, key_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 12142 Add<HLoadKeyed>(table, key_index, nullptr, FAST_ELEMENTS); |
| 12190 | 12143 |
| 12191 { | 12144 { |
| 12192 IfBuilder if_keys_equal(this); | 12145 IfBuilder if_keys_equal(this); |
| 12193 if_keys_equal.If<HIsStringAndBranch>(candidate_key); | 12146 if_keys_equal.If<HIsStringAndBranch>(candidate_key); |
| 12194 if_keys_equal.AndIf<HStringCompareAndBranch>(candidate_key, key, | 12147 if_keys_equal.AndIf<HStringCompareAndBranch>(candidate_key, key, |
| 12195 Token::EQ_STRICT); | 12148 Token::EQ_STRICT); |
| 12196 if_keys_equal.Then(); | 12149 if_keys_equal.Then(); |
| 12197 Push(key_index); | 12150 Push(key_index); |
| 12198 loop.Break(); | 12151 loop.Break(); |
| 12199 } | 12152 } |
| 12200 | 12153 |
| 12201 // BuildChainAt | 12154 // BuildChainAt |
| 12202 HValue* chain_index = AddUncasted<HAdd>( | 12155 HValue* chain_index = AddUncasted<HAdd>( |
| 12203 key_index, Add<HConstant>(CollectionType::kChainOffset)); | 12156 key_index, Add<HConstant>(CollectionType::kChainOffset)); |
| 12204 chain_index->ClearFlag(HValue::kCanOverflow); | 12157 chain_index->ClearFlag(HValue::kCanOverflow); |
| 12205 entry = Add<HLoadKeyed>(table, chain_index, static_cast<HValue*>(NULL), | 12158 entry = Add<HLoadKeyed>(table, chain_index, nullptr, FAST_ELEMENTS); |
| 12206 FAST_ELEMENTS); | |
| 12207 entry->set_type(HType::Smi()); | 12159 entry->set_type(HType::Smi()); |
| 12208 Push(entry); | 12160 Push(entry); |
| 12209 | 12161 |
| 12210 loop.EndBody(); | 12162 loop.EndBody(); |
| 12211 | 12163 |
| 12212 return Pop(); | 12164 return Pop(); |
| 12213 } | 12165 } |
| 12214 | 12166 |
| 12215 | 12167 |
| 12216 void HOptimizedGraphBuilder::GenerateMapGet(CallRuntime* call) { | 12168 void HOptimizedGraphBuilder::GenerateMapGet(CallRuntime* call) { |
| 12217 DCHECK(call->arguments()->length() == 2); | 12169 DCHECK(call->arguments()->length() == 2); |
| 12218 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12170 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12219 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); | 12171 CHECK_ALIVE(VisitForValue(call->arguments()->at(1))); |
| 12220 HValue* key = Pop(); | 12172 HValue* key = Pop(); |
| 12221 HValue* receiver = Pop(); | 12173 HValue* receiver = Pop(); |
| 12222 | 12174 |
| 12223 NoObservableSideEffectsScope no_effects(this); | 12175 NoObservableSideEffectsScope no_effects(this); |
| 12224 | 12176 |
| 12225 HIfContinuation continuation; | 12177 HIfContinuation continuation; |
| 12226 HValue* hash = | 12178 HValue* hash = |
| 12227 BuildStringHashLoadIfIsStringAndHashComputed(key, &continuation); | 12179 BuildStringHashLoadIfIsStringAndHashComputed(key, &continuation); |
| 12228 { | 12180 { |
| 12229 IfBuilder string_checker(this, &continuation); | 12181 IfBuilder string_checker(this, &continuation); |
| 12230 string_checker.Then(); | 12182 string_checker.Then(); |
| 12231 { | 12183 { |
| 12232 HValue* table = | 12184 HValue* table = Add<HLoadNamedField>( |
| 12233 Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | 12185 receiver, nullptr, HObjectAccess::ForJSCollectionTable()); |
| 12234 HObjectAccess::ForJSCollectionTable()); | |
| 12235 HValue* key_index = | 12186 HValue* key_index = |
| 12236 BuildOrderedHashTableFindEntry<OrderedHashMap>(table, key, hash); | 12187 BuildOrderedHashTableFindEntry<OrderedHashMap>(table, key, hash); |
| 12237 IfBuilder if_found(this); | 12188 IfBuilder if_found(this); |
| 12238 if_found.If<HCompareNumericAndBranch>( | 12189 if_found.If<HCompareNumericAndBranch>( |
| 12239 key_index, Add<HConstant>(OrderedHashMap::kNotFound), Token::NE); | 12190 key_index, Add<HConstant>(OrderedHashMap::kNotFound), Token::NE); |
| 12240 if_found.Then(); | 12191 if_found.Then(); |
| 12241 { | 12192 { |
| 12242 HValue* value_index = AddUncasted<HAdd>( | 12193 HValue* value_index = AddUncasted<HAdd>( |
| 12243 key_index, Add<HConstant>(OrderedHashMap::kValueOffset)); | 12194 key_index, Add<HConstant>(OrderedHashMap::kValueOffset)); |
| 12244 value_index->ClearFlag(HValue::kCanOverflow); | 12195 value_index->ClearFlag(HValue::kCanOverflow); |
| 12245 Push(Add<HLoadKeyed>(table, value_index, static_cast<HValue*>(NULL), | 12196 Push(Add<HLoadKeyed>(table, value_index, nullptr, FAST_ELEMENTS)); |
| 12246 FAST_ELEMENTS)); | |
| 12247 } | 12197 } |
| 12248 if_found.Else(); | 12198 if_found.Else(); |
| 12249 Push(graph()->GetConstantUndefined()); | 12199 Push(graph()->GetConstantUndefined()); |
| 12250 if_found.End(); | 12200 if_found.End(); |
| 12251 } | 12201 } |
| 12252 string_checker.Else(); | 12202 string_checker.Else(); |
| 12253 { | 12203 { |
| 12254 Add<HPushArguments>(receiver, key); | 12204 Add<HPushArguments>(receiver, key); |
| 12255 Push(Add<HCallRuntime>(call->name(), | 12205 Push(Add<HCallRuntime>(call->name(), |
| 12256 Runtime::FunctionForId(Runtime::kMapGet), 2)); | 12206 Runtime::FunctionForId(Runtime::kMapGet), 2)); |
| 12257 } | 12207 } |
| 12258 } | 12208 } |
| 12259 | 12209 |
| 12260 return ast_context()->ReturnValue(Pop()); | 12210 return ast_context()->ReturnValue(Pop()); |
| 12261 } | 12211 } |
| 12262 | 12212 |
| 12263 | 12213 |
| 12264 HValue* HOptimizedGraphBuilder::BuildStringHashLoadIfIsStringAndHashComputed( | 12214 HValue* HOptimizedGraphBuilder::BuildStringHashLoadIfIsStringAndHashComputed( |
| 12265 HValue* object, HIfContinuation* continuation) { | 12215 HValue* object, HIfContinuation* continuation) { |
| 12266 IfBuilder string_checker(this); | 12216 IfBuilder string_checker(this); |
| 12267 string_checker.If<HIsStringAndBranch>(object); | 12217 string_checker.If<HIsStringAndBranch>(object); |
| 12268 string_checker.And(); | 12218 string_checker.And(); |
| 12269 HValue* hash = Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), | 12219 HValue* hash = Add<HLoadNamedField>(object, nullptr, |
| 12270 HObjectAccess::ForStringHashField()); | 12220 HObjectAccess::ForStringHashField()); |
| 12271 HValue* hash_not_computed_mask = Add<HConstant>(String::kHashNotComputedMask); | 12221 HValue* hash_not_computed_mask = Add<HConstant>(String::kHashNotComputedMask); |
| 12272 HValue* hash_computed_test = | 12222 HValue* hash_computed_test = |
| 12273 AddUncasted<HBitwise>(Token::BIT_AND, hash, hash_not_computed_mask); | 12223 AddUncasted<HBitwise>(Token::BIT_AND, hash, hash_not_computed_mask); |
| 12274 string_checker.If<HCompareNumericAndBranch>( | 12224 string_checker.If<HCompareNumericAndBranch>( |
| 12275 hash_computed_test, graph()->GetConstant0(), Token::EQ); | 12225 hash_computed_test, graph()->GetConstant0(), Token::EQ); |
| 12276 string_checker.Then(); | 12226 string_checker.Then(); |
| 12277 HValue* shifted_hash = | 12227 HValue* shifted_hash = |
| 12278 AddUncasted<HShr>(hash, Add<HConstant>(String::kHashShift)); | 12228 AddUncasted<HShr>(hash, Add<HConstant>(String::kHashShift)); |
| 12279 string_checker.CaptureContinuation(continuation); | 12229 string_checker.CaptureContinuation(continuation); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 12292 | 12242 |
| 12293 NoObservableSideEffectsScope no_effects(this); | 12243 NoObservableSideEffectsScope no_effects(this); |
| 12294 | 12244 |
| 12295 HIfContinuation continuation; | 12245 HIfContinuation continuation; |
| 12296 HValue* hash = | 12246 HValue* hash = |
| 12297 BuildStringHashLoadIfIsStringAndHashComputed(key, &continuation); | 12247 BuildStringHashLoadIfIsStringAndHashComputed(key, &continuation); |
| 12298 { | 12248 { |
| 12299 IfBuilder string_checker(this, &continuation); | 12249 IfBuilder string_checker(this, &continuation); |
| 12300 string_checker.Then(); | 12250 string_checker.Then(); |
| 12301 { | 12251 { |
| 12302 HValue* table = | 12252 HValue* table = Add<HLoadNamedField>( |
| 12303 Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | 12253 receiver, nullptr, HObjectAccess::ForJSCollectionTable()); |
| 12304 HObjectAccess::ForJSCollectionTable()); | |
| 12305 HValue* key_index = | 12254 HValue* key_index = |
| 12306 BuildOrderedHashTableFindEntry<CollectionType>(table, key, hash); | 12255 BuildOrderedHashTableFindEntry<CollectionType>(table, key, hash); |
| 12307 { | 12256 { |
| 12308 IfBuilder if_found(this); | 12257 IfBuilder if_found(this); |
| 12309 if_found.If<HCompareNumericAndBranch>( | 12258 if_found.If<HCompareNumericAndBranch>( |
| 12310 key_index, Add<HConstant>(CollectionType::kNotFound), Token::NE); | 12259 key_index, Add<HConstant>(CollectionType::kNotFound), Token::NE); |
| 12311 if_found.Then(); | 12260 if_found.Then(); |
| 12312 Push(graph()->GetConstantTrue()); | 12261 Push(graph()->GetConstantTrue()); |
| 12313 if_found.Else(); | 12262 if_found.Else(); |
| 12314 Push(graph()->GetConstantFalse()); | 12263 Push(graph()->GetConstantFalse()); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 12335 BuildJSCollectionHas<OrderedHashSet>( | 12284 BuildJSCollectionHas<OrderedHashSet>( |
| 12336 call, Runtime::FunctionForId(Runtime::kSetHas)); | 12285 call, Runtime::FunctionForId(Runtime::kSetHas)); |
| 12337 } | 12286 } |
| 12338 | 12287 |
| 12339 | 12288 |
| 12340 template <typename CollectionType> | 12289 template <typename CollectionType> |
| 12341 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableAddEntry( | 12290 HValue* HOptimizedGraphBuilder::BuildOrderedHashTableAddEntry( |
| 12342 HValue* table, HValue* key, HValue* hash, | 12291 HValue* table, HValue* key, HValue* hash, |
| 12343 HIfContinuation* join_continuation) { | 12292 HIfContinuation* join_continuation) { |
| 12344 HValue* num_buckets = Add<HLoadNamedField>( | 12293 HValue* num_buckets = Add<HLoadNamedField>( |
| 12345 table, static_cast<HValue*>(NULL), | 12294 table, nullptr, |
| 12346 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>()); | 12295 HObjectAccess::ForOrderedHashTableNumberOfBuckets<CollectionType>()); |
| 12347 HValue* capacity = AddUncasted<HMul>( | 12296 HValue* capacity = AddUncasted<HMul>( |
| 12348 num_buckets, Add<HConstant>(CollectionType::kLoadFactor)); | 12297 num_buckets, Add<HConstant>(CollectionType::kLoadFactor)); |
| 12349 capacity->ClearFlag(HValue::kCanOverflow); | 12298 capacity->ClearFlag(HValue::kCanOverflow); |
| 12350 HValue* num_elements = Add<HLoadNamedField>( | 12299 HValue* num_elements = Add<HLoadNamedField>( |
| 12351 table, static_cast<HValue*>(NULL), | 12300 table, nullptr, |
| 12352 HObjectAccess::ForOrderedHashTableNumberOfElements<CollectionType>()); | 12301 HObjectAccess::ForOrderedHashTableNumberOfElements<CollectionType>()); |
| 12353 HValue* num_deleted = Add<HLoadNamedField>( | 12302 HValue* num_deleted = Add<HLoadNamedField>( |
| 12354 table, static_cast<HValue*>(NULL), | 12303 table, nullptr, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements< |
| 12355 HObjectAccess::ForOrderedHashTableNumberOfDeletedElements< | 12304 CollectionType>()); |
| 12356 CollectionType>()); | |
| 12357 HValue* used = AddUncasted<HAdd>(num_elements, num_deleted); | 12305 HValue* used = AddUncasted<HAdd>(num_elements, num_deleted); |
| 12358 used->ClearFlag(HValue::kCanOverflow); | 12306 used->ClearFlag(HValue::kCanOverflow); |
| 12359 IfBuilder if_space_available(this); | 12307 IfBuilder if_space_available(this); |
| 12360 if_space_available.If<HCompareNumericAndBranch>(capacity, used, Token::GT); | 12308 if_space_available.If<HCompareNumericAndBranch>(capacity, used, Token::GT); |
| 12361 if_space_available.Then(); | 12309 if_space_available.Then(); |
| 12362 HValue* bucket = BuildOrderedHashTableHashToBucket(hash, num_buckets); | 12310 HValue* bucket = BuildOrderedHashTableHashToBucket(hash, num_buckets); |
| 12363 HValue* entry = used; | 12311 HValue* entry = used; |
| 12364 HValue* key_index = | 12312 HValue* key_index = |
| 12365 BuildOrderedHashTableEntryToIndex<CollectionType>(entry, num_buckets); | 12313 BuildOrderedHashTableEntryToIndex<CollectionType>(entry, num_buckets); |
| 12366 | 12314 |
| 12367 HValue* bucket_index = AddUncasted<HAdd>( | 12315 HValue* bucket_index = AddUncasted<HAdd>( |
| 12368 bucket, Add<HConstant>(CollectionType::kHashTableStartIndex)); | 12316 bucket, Add<HConstant>(CollectionType::kHashTableStartIndex)); |
| 12369 bucket_index->ClearFlag(HValue::kCanOverflow); | 12317 bucket_index->ClearFlag(HValue::kCanOverflow); |
| 12370 HValue* chain_entry = Add<HLoadKeyed>( | 12318 HValue* chain_entry = |
| 12371 table, bucket_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 12319 Add<HLoadKeyed>(table, bucket_index, nullptr, FAST_ELEMENTS); |
| 12372 chain_entry->set_type(HType::Smi()); | 12320 chain_entry->set_type(HType::Smi()); |
| 12373 | 12321 |
| 12374 HValue* chain_index = AddUncasted<HAdd>( | 12322 HValue* chain_index = AddUncasted<HAdd>( |
| 12375 key_index, Add<HConstant>(CollectionType::kChainOffset)); | 12323 key_index, Add<HConstant>(CollectionType::kChainOffset)); |
| 12376 chain_index->ClearFlag(HValue::kCanOverflow); | 12324 chain_index->ClearFlag(HValue::kCanOverflow); |
| 12377 | 12325 |
| 12378 Add<HStoreKeyed>(table, bucket_index, entry, FAST_ELEMENTS); | 12326 Add<HStoreKeyed>(table, bucket_index, entry, FAST_ELEMENTS); |
| 12379 Add<HStoreKeyed>(table, chain_index, chain_entry, FAST_ELEMENTS); | 12327 Add<HStoreKeyed>(table, chain_index, chain_entry, FAST_ELEMENTS); |
| 12380 Add<HStoreKeyed>(table, key_index, key, FAST_ELEMENTS); | 12328 Add<HStoreKeyed>(table, key_index, key, FAST_ELEMENTS); |
| 12381 | 12329 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 12403 NoObservableSideEffectsScope no_effects(this); | 12351 NoObservableSideEffectsScope no_effects(this); |
| 12404 | 12352 |
| 12405 HIfContinuation return_or_call_runtime_continuation( | 12353 HIfContinuation return_or_call_runtime_continuation( |
| 12406 graph()->CreateBasicBlock(), graph()->CreateBasicBlock()); | 12354 graph()->CreateBasicBlock(), graph()->CreateBasicBlock()); |
| 12407 HIfContinuation got_string_hash; | 12355 HIfContinuation got_string_hash; |
| 12408 HValue* hash = | 12356 HValue* hash = |
| 12409 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash); | 12357 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash); |
| 12410 IfBuilder string_checker(this, &got_string_hash); | 12358 IfBuilder string_checker(this, &got_string_hash); |
| 12411 string_checker.Then(); | 12359 string_checker.Then(); |
| 12412 { | 12360 { |
| 12413 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | 12361 HValue* table = Add<HLoadNamedField>(receiver, nullptr, |
| 12414 HObjectAccess::ForJSCollectionTable()); | 12362 HObjectAccess::ForJSCollectionTable()); |
| 12415 HValue* key_index = | 12363 HValue* key_index = |
| 12416 BuildOrderedHashTableFindEntry<OrderedHashMap>(table, key, hash); | 12364 BuildOrderedHashTableFindEntry<OrderedHashMap>(table, key, hash); |
| 12417 { | 12365 { |
| 12418 IfBuilder if_found(this); | 12366 IfBuilder if_found(this); |
| 12419 if_found.If<HCompareNumericAndBranch>( | 12367 if_found.If<HCompareNumericAndBranch>( |
| 12420 key_index, Add<HConstant>(OrderedHashMap::kNotFound), Token::NE); | 12368 key_index, Add<HConstant>(OrderedHashMap::kNotFound), Token::NE); |
| 12421 if_found.Then(); | 12369 if_found.Then(); |
| 12422 { | 12370 { |
| 12423 HValue* value_index = AddUncasted<HAdd>( | 12371 HValue* value_index = AddUncasted<HAdd>( |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12470 NoObservableSideEffectsScope no_effects(this); | 12418 NoObservableSideEffectsScope no_effects(this); |
| 12471 | 12419 |
| 12472 HIfContinuation return_or_call_runtime_continuation( | 12420 HIfContinuation return_or_call_runtime_continuation( |
| 12473 graph()->CreateBasicBlock(), graph()->CreateBasicBlock()); | 12421 graph()->CreateBasicBlock(), graph()->CreateBasicBlock()); |
| 12474 HIfContinuation got_string_hash; | 12422 HIfContinuation got_string_hash; |
| 12475 HValue* hash = | 12423 HValue* hash = |
| 12476 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash); | 12424 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash); |
| 12477 IfBuilder string_checker(this, &got_string_hash); | 12425 IfBuilder string_checker(this, &got_string_hash); |
| 12478 string_checker.Then(); | 12426 string_checker.Then(); |
| 12479 { | 12427 { |
| 12480 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | 12428 HValue* table = Add<HLoadNamedField>(receiver, nullptr, |
| 12481 HObjectAccess::ForJSCollectionTable()); | 12429 HObjectAccess::ForJSCollectionTable()); |
| 12482 HValue* key_index = | 12430 HValue* key_index = |
| 12483 BuildOrderedHashTableFindEntry<OrderedHashSet>(table, key, hash); | 12431 BuildOrderedHashTableFindEntry<OrderedHashSet>(table, key, hash); |
| 12484 { | 12432 { |
| 12485 IfBuilder if_not_found(this); | 12433 IfBuilder if_not_found(this); |
| 12486 if_not_found.If<HCompareNumericAndBranch>( | 12434 if_not_found.If<HCompareNumericAndBranch>( |
| 12487 key_index, Add<HConstant>(OrderedHashSet::kNotFound), Token::EQ); | 12435 key_index, Add<HConstant>(OrderedHashSet::kNotFound), Token::EQ); |
| 12488 if_not_found.Then(); | 12436 if_not_found.Then(); |
| 12489 BuildOrderedHashTableAddEntry<OrderedHashSet>( | 12437 BuildOrderedHashTableAddEntry<OrderedHashSet>( |
| 12490 table, key, hash, &return_or_call_runtime_continuation); | 12438 table, key, hash, &return_or_call_runtime_continuation); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 12519 NoObservableSideEffectsScope no_effects(this); | 12467 NoObservableSideEffectsScope no_effects(this); |
| 12520 | 12468 |
| 12521 HIfContinuation return_or_call_runtime_continuation( | 12469 HIfContinuation return_or_call_runtime_continuation( |
| 12522 graph()->CreateBasicBlock(), graph()->CreateBasicBlock()); | 12470 graph()->CreateBasicBlock(), graph()->CreateBasicBlock()); |
| 12523 HIfContinuation got_string_hash; | 12471 HIfContinuation got_string_hash; |
| 12524 HValue* hash = | 12472 HValue* hash = |
| 12525 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash); | 12473 BuildStringHashLoadIfIsStringAndHashComputed(key, &got_string_hash); |
| 12526 IfBuilder string_checker(this, &got_string_hash); | 12474 IfBuilder string_checker(this, &got_string_hash); |
| 12527 string_checker.Then(); | 12475 string_checker.Then(); |
| 12528 { | 12476 { |
| 12529 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | 12477 HValue* table = Add<HLoadNamedField>(receiver, nullptr, |
| 12530 HObjectAccess::ForJSCollectionTable()); | 12478 HObjectAccess::ForJSCollectionTable()); |
| 12531 HValue* key_index = | 12479 HValue* key_index = |
| 12532 BuildOrderedHashTableFindEntry<CollectionType>(table, key, hash); | 12480 BuildOrderedHashTableFindEntry<CollectionType>(table, key, hash); |
| 12533 { | 12481 { |
| 12534 IfBuilder if_found(this); | 12482 IfBuilder if_found(this); |
| 12535 if_found.If<HCompareNumericAndBranch>( | 12483 if_found.If<HCompareNumericAndBranch>( |
| 12536 key_index, Add<HConstant>(CollectionType::kNotFound), Token::NE); | 12484 key_index, Add<HConstant>(CollectionType::kNotFound), Token::NE); |
| 12537 if_found.Then(); | 12485 if_found.Then(); |
| 12538 { | 12486 { |
| 12539 // If we're removing an element, we might need to shrink. | 12487 // If we're removing an element, we might need to shrink. |
| 12540 // If we do need to shrink, we'll be bailing out to the runtime. | 12488 // If we do need to shrink, we'll be bailing out to the runtime. |
| 12541 HValue* num_elements = Add<HLoadNamedField>( | 12489 HValue* num_elements = Add<HLoadNamedField>( |
| 12542 table, static_cast<HValue*>(NULL), | 12490 table, nullptr, HObjectAccess::ForOrderedHashTableNumberOfElements< |
| 12543 HObjectAccess::ForOrderedHashTableNumberOfElements< | 12491 CollectionType>()); |
| 12544 CollectionType>()); | |
| 12545 num_elements = AddUncasted<HSub>(num_elements, graph()->GetConstant1()); | 12492 num_elements = AddUncasted<HSub>(num_elements, graph()->GetConstant1()); |
| 12546 num_elements->ClearFlag(HValue::kCanOverflow); | 12493 num_elements->ClearFlag(HValue::kCanOverflow); |
| 12547 | 12494 |
| 12548 HValue* num_buckets = Add<HLoadNamedField>( | 12495 HValue* num_buckets = Add<HLoadNamedField>( |
| 12549 table, static_cast<HValue*>(NULL), | 12496 table, nullptr, HObjectAccess::ForOrderedHashTableNumberOfBuckets< |
| 12550 HObjectAccess::ForOrderedHashTableNumberOfBuckets< | 12497 CollectionType>()); |
| 12551 CollectionType>()); | |
| 12552 // threshold is capacity >> 2; we simplify this to num_buckets >> 1 | 12498 // threshold is capacity >> 2; we simplify this to num_buckets >> 1 |
| 12553 // since kLoadFactor is 2. | 12499 // since kLoadFactor is 2. |
| 12554 STATIC_ASSERT(CollectionType::kLoadFactor == 2); | 12500 STATIC_ASSERT(CollectionType::kLoadFactor == 2); |
| 12555 HValue* threshold = | 12501 HValue* threshold = |
| 12556 AddUncasted<HShr>(num_buckets, graph()->GetConstant1()); | 12502 AddUncasted<HShr>(num_buckets, graph()->GetConstant1()); |
| 12557 | 12503 |
| 12558 IfBuilder if_need_not_shrink(this); | 12504 IfBuilder if_need_not_shrink(this); |
| 12559 if_need_not_shrink.If<HCompareNumericAndBranch>(num_elements, threshold, | 12505 if_need_not_shrink.If<HCompareNumericAndBranch>(num_elements, threshold, |
| 12560 Token::GTE); | 12506 Token::GTE); |
| 12561 if_need_not_shrink.Then(); | 12507 if_need_not_shrink.Then(); |
| 12562 { | 12508 { |
| 12563 Add<HStoreKeyed>(table, key_index, graph()->GetConstantHole(), | 12509 Add<HStoreKeyed>(table, key_index, graph()->GetConstantHole(), |
| 12564 FAST_ELEMENTS); | 12510 FAST_ELEMENTS); |
| 12565 | 12511 |
| 12566 // For maps, also need to clear the value. | 12512 // For maps, also need to clear the value. |
| 12567 if (CollectionType::kChainOffset > 1) { | 12513 if (CollectionType::kChainOffset > 1) { |
| 12568 HValue* value_index = | 12514 HValue* value_index = |
| 12569 AddUncasted<HAdd>(key_index, graph()->GetConstant1()); | 12515 AddUncasted<HAdd>(key_index, graph()->GetConstant1()); |
| 12570 value_index->ClearFlag(HValue::kCanOverflow); | 12516 value_index->ClearFlag(HValue::kCanOverflow); |
| 12571 Add<HStoreKeyed>(table, value_index, graph()->GetConstantHole(), | 12517 Add<HStoreKeyed>(table, value_index, graph()->GetConstantHole(), |
| 12572 FAST_ELEMENTS); | 12518 FAST_ELEMENTS); |
| 12573 } | 12519 } |
| 12574 STATIC_ASSERT(CollectionType::kChainOffset <= 2); | 12520 STATIC_ASSERT(CollectionType::kChainOffset <= 2); |
| 12575 | 12521 |
| 12576 HValue* num_deleted = Add<HLoadNamedField>( | 12522 HValue* num_deleted = Add<HLoadNamedField>( |
| 12577 table, static_cast<HValue*>(NULL), | 12523 table, nullptr, |
| 12578 HObjectAccess::ForOrderedHashTableNumberOfDeletedElements< | 12524 HObjectAccess::ForOrderedHashTableNumberOfDeletedElements< |
| 12579 CollectionType>()); | 12525 CollectionType>()); |
| 12580 num_deleted = AddUncasted<HAdd>(num_deleted, graph()->GetConstant1()); | 12526 num_deleted = AddUncasted<HAdd>(num_deleted, graph()->GetConstant1()); |
| 12581 num_deleted->ClearFlag(HValue::kCanOverflow); | 12527 num_deleted->ClearFlag(HValue::kCanOverflow); |
| 12582 Add<HStoreNamedField>( | 12528 Add<HStoreNamedField>( |
| 12583 table, HObjectAccess::ForOrderedHashTableNumberOfElements< | 12529 table, HObjectAccess::ForOrderedHashTableNumberOfElements< |
| 12584 CollectionType>(), | 12530 CollectionType>(), |
| 12585 num_elements); | 12531 num_elements); |
| 12586 Add<HStoreNamedField>( | 12532 Add<HStoreNamedField>( |
| 12587 table, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements< | 12533 table, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements< |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12623 void HOptimizedGraphBuilder::GenerateSetDelete(CallRuntime* call) { | 12569 void HOptimizedGraphBuilder::GenerateSetDelete(CallRuntime* call) { |
| 12624 BuildJSCollectionDelete<OrderedHashSet>( | 12570 BuildJSCollectionDelete<OrderedHashSet>( |
| 12625 call, Runtime::FunctionForId(Runtime::kSetDelete)); | 12571 call, Runtime::FunctionForId(Runtime::kSetDelete)); |
| 12626 } | 12572 } |
| 12627 | 12573 |
| 12628 | 12574 |
| 12629 void HOptimizedGraphBuilder::GenerateSetGetSize(CallRuntime* call) { | 12575 void HOptimizedGraphBuilder::GenerateSetGetSize(CallRuntime* call) { |
| 12630 DCHECK(call->arguments()->length() == 1); | 12576 DCHECK(call->arguments()->length() == 1); |
| 12631 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12577 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12632 HValue* receiver = Pop(); | 12578 HValue* receiver = Pop(); |
| 12633 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | 12579 HValue* table = Add<HLoadNamedField>(receiver, nullptr, |
| 12634 HObjectAccess::ForJSCollectionTable()); | 12580 HObjectAccess::ForJSCollectionTable()); |
| 12635 HInstruction* result = New<HLoadNamedField>( | 12581 HInstruction* result = New<HLoadNamedField>( |
| 12636 table, static_cast<HValue*>(NULL), | 12582 table, nullptr, |
| 12637 HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashSet>()); | 12583 HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashSet>()); |
| 12638 return ast_context()->ReturnInstruction(result, call->id()); | 12584 return ast_context()->ReturnInstruction(result, call->id()); |
| 12639 } | 12585 } |
| 12640 | 12586 |
| 12641 | 12587 |
| 12642 void HOptimizedGraphBuilder::GenerateMapGetSize(CallRuntime* call) { | 12588 void HOptimizedGraphBuilder::GenerateMapGetSize(CallRuntime* call) { |
| 12643 DCHECK(call->arguments()->length() == 1); | 12589 DCHECK(call->arguments()->length() == 1); |
| 12644 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12590 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12645 HValue* receiver = Pop(); | 12591 HValue* receiver = Pop(); |
| 12646 HValue* table = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | 12592 HValue* table = Add<HLoadNamedField>(receiver, nullptr, |
| 12647 HObjectAccess::ForJSCollectionTable()); | 12593 HObjectAccess::ForJSCollectionTable()); |
| 12648 HInstruction* result = New<HLoadNamedField>( | 12594 HInstruction* result = New<HLoadNamedField>( |
| 12649 table, static_cast<HValue*>(NULL), | 12595 table, nullptr, |
| 12650 HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashMap>()); | 12596 HObjectAccess::ForOrderedHashTableNumberOfElements<OrderedHashMap>()); |
| 12651 return ast_context()->ReturnInstruction(result, call->id()); | 12597 return ast_context()->ReturnInstruction(result, call->id()); |
| 12652 } | 12598 } |
| 12653 | 12599 |
| 12654 | 12600 |
| 12655 template <typename CollectionType> | 12601 template <typename CollectionType> |
| 12656 HValue* HOptimizedGraphBuilder::BuildAllocateOrderedHashTable() { | 12602 HValue* HOptimizedGraphBuilder::BuildAllocateOrderedHashTable() { |
| 12657 static const int kCapacity = CollectionType::kMinCapacity; | 12603 static const int kCapacity = CollectionType::kMinCapacity; |
| 12658 static const int kBucketCount = kCapacity / CollectionType::kLoadFactor; | 12604 static const int kBucketCount = kCapacity / CollectionType::kLoadFactor; |
| 12659 static const int kFixedArrayLength = CollectionType::kHashTableStartIndex + | 12605 static const int kFixedArrayLength = CollectionType::kHashTableStartIndex + |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12726 | 12672 |
| 12727 NoObservableSideEffectsScope no_effects(this); | 12673 NoObservableSideEffectsScope no_effects(this); |
| 12728 HValue* table = BuildAllocateOrderedHashTable<OrderedHashMap>(); | 12674 HValue* table = BuildAllocateOrderedHashTable<OrderedHashMap>(); |
| 12729 Add<HStoreNamedField>(receiver, HObjectAccess::ForJSCollectionTable(), table); | 12675 Add<HStoreNamedField>(receiver, HObjectAccess::ForJSCollectionTable(), table); |
| 12730 return ast_context()->ReturnValue(receiver); | 12676 return ast_context()->ReturnValue(receiver); |
| 12731 } | 12677 } |
| 12732 | 12678 |
| 12733 | 12679 |
| 12734 template <typename CollectionType> | 12680 template <typename CollectionType> |
| 12735 void HOptimizedGraphBuilder::BuildOrderedHashTableClear(HValue* receiver) { | 12681 void HOptimizedGraphBuilder::BuildOrderedHashTableClear(HValue* receiver) { |
| 12736 HValue* old_table = | 12682 HValue* old_table = Add<HLoadNamedField>( |
| 12737 Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | 12683 receiver, nullptr, HObjectAccess::ForJSCollectionTable()); |
| 12738 HObjectAccess::ForJSCollectionTable()); | |
| 12739 HValue* new_table = BuildAllocateOrderedHashTable<CollectionType>(); | 12684 HValue* new_table = BuildAllocateOrderedHashTable<CollectionType>(); |
| 12740 Add<HStoreNamedField>( | 12685 Add<HStoreNamedField>( |
| 12741 old_table, HObjectAccess::ForOrderedHashTableNextTable<CollectionType>(), | 12686 old_table, HObjectAccess::ForOrderedHashTableNextTable<CollectionType>(), |
| 12742 new_table); | 12687 new_table); |
| 12743 Add<HStoreNamedField>( | 12688 Add<HStoreNamedField>( |
| 12744 old_table, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements< | 12689 old_table, HObjectAccess::ForOrderedHashTableNumberOfDeletedElements< |
| 12745 CollectionType>(), | 12690 CollectionType>(), |
| 12746 Add<HConstant>(CollectionType::kClearedTableSentinel)); | 12691 Add<HConstant>(CollectionType::kClearedTableSentinel)); |
| 12747 Add<HStoreNamedField>(receiver, HObjectAccess::ForJSCollectionTable(), | 12692 Add<HStoreNamedField>(receiver, HObjectAccess::ForJSCollectionTable(), |
| 12748 new_table); | 12693 new_table); |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12800 CallRuntime* call) { | 12745 CallRuntime* call) { |
| 12801 Add<HDebugBreak>(); | 12746 Add<HDebugBreak>(); |
| 12802 return ast_context()->ReturnValue(graph()->GetConstant0()); | 12747 return ast_context()->ReturnValue(graph()->GetConstant0()); |
| 12803 } | 12748 } |
| 12804 | 12749 |
| 12805 | 12750 |
| 12806 void HOptimizedGraphBuilder::GenerateDebugIsActive(CallRuntime* call) { | 12751 void HOptimizedGraphBuilder::GenerateDebugIsActive(CallRuntime* call) { |
| 12807 DCHECK(call->arguments()->length() == 0); | 12752 DCHECK(call->arguments()->length() == 0); |
| 12808 HValue* ref = | 12753 HValue* ref = |
| 12809 Add<HConstant>(ExternalReference::debug_is_active_address(isolate())); | 12754 Add<HConstant>(ExternalReference::debug_is_active_address(isolate())); |
| 12810 HValue* value = Add<HLoadNamedField>( | 12755 HValue* value = |
| 12811 ref, static_cast<HValue*>(NULL), HObjectAccess::ForExternalUInteger8()); | 12756 Add<HLoadNamedField>(ref, nullptr, HObjectAccess::ForExternalUInteger8()); |
| 12812 return ast_context()->ReturnValue(value); | 12757 return ast_context()->ReturnValue(value); |
| 12813 } | 12758 } |
| 12814 | 12759 |
| 12815 | 12760 |
| 12816 void HOptimizedGraphBuilder::GenerateGetPrototype(CallRuntime* call) { | 12761 void HOptimizedGraphBuilder::GenerateGetPrototype(CallRuntime* call) { |
| 12817 DCHECK(call->arguments()->length() == 1); | 12762 DCHECK(call->arguments()->length() == 1); |
| 12818 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 12763 CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |
| 12819 HValue* object = Pop(); | 12764 HValue* object = Pop(); |
| 12820 | 12765 |
| 12821 NoObservableSideEffectsScope no_effects(this); | 12766 NoObservableSideEffectsScope no_effects(this); |
| 12822 | 12767 |
| 12823 HValue* map = Add<HLoadNamedField>(object, static_cast<HValue*>(NULL), | 12768 HValue* map = Add<HLoadNamedField>(object, nullptr, HObjectAccess::ForMap()); |
| 12824 HObjectAccess::ForMap()); | 12769 HValue* bit_field = |
| 12825 HValue* bit_field = Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), | 12770 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForMapBitField()); |
| 12826 HObjectAccess::ForMapBitField()); | |
| 12827 HValue* is_access_check_needed_mask = | 12771 HValue* is_access_check_needed_mask = |
| 12828 Add<HConstant>(1 << Map::kIsAccessCheckNeeded); | 12772 Add<HConstant>(1 << Map::kIsAccessCheckNeeded); |
| 12829 HValue* is_access_check_needed_test = AddUncasted<HBitwise>( | 12773 HValue* is_access_check_needed_test = AddUncasted<HBitwise>( |
| 12830 Token::BIT_AND, bit_field, is_access_check_needed_mask); | 12774 Token::BIT_AND, bit_field, is_access_check_needed_mask); |
| 12831 | 12775 |
| 12832 HValue* proto = Add<HLoadNamedField>(map, static_cast<HValue*>(NULL), | 12776 HValue* proto = |
| 12833 HObjectAccess::ForPrototype()); | 12777 Add<HLoadNamedField>(map, nullptr, HObjectAccess::ForPrototype()); |
| 12834 HValue* proto_map = Add<HLoadNamedField>(proto, static_cast<HValue*>(NULL), | 12778 HValue* proto_map = |
| 12835 HObjectAccess::ForMap()); | 12779 Add<HLoadNamedField>(proto, nullptr, HObjectAccess::ForMap()); |
| 12836 HValue* proto_bit_field = Add<HLoadNamedField>( | 12780 HValue* proto_bit_field = |
| 12837 proto_map, static_cast<HValue*>(NULL), HObjectAccess::ForMapBitField()); | 12781 Add<HLoadNamedField>(proto_map, nullptr, HObjectAccess::ForMapBitField()); |
| 12838 HValue* is_hidden_prototype_mask = | 12782 HValue* is_hidden_prototype_mask = |
| 12839 Add<HConstant>(1 << Map::kIsHiddenPrototype); | 12783 Add<HConstant>(1 << Map::kIsHiddenPrototype); |
| 12840 HValue* is_hidden_prototype_test = AddUncasted<HBitwise>( | 12784 HValue* is_hidden_prototype_test = AddUncasted<HBitwise>( |
| 12841 Token::BIT_AND, proto_bit_field, is_hidden_prototype_mask); | 12785 Token::BIT_AND, proto_bit_field, is_hidden_prototype_mask); |
| 12842 | 12786 |
| 12843 { | 12787 { |
| 12844 IfBuilder needs_runtime(this); | 12788 IfBuilder needs_runtime(this); |
| 12845 needs_runtime.If<HCompareNumericAndBranch>( | 12789 needs_runtime.If<HCompareNumericAndBranch>( |
| 12846 is_access_check_needed_test, graph()->GetConstant0(), Token::NE); | 12790 is_access_check_needed_test, graph()->GetConstant0(), Token::NE); |
| 12847 needs_runtime.OrIf<HCompareNumericAndBranch>( | 12791 needs_runtime.OrIf<HCompareNumericAndBranch>( |
| (...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13491 if (ShouldProduceTraceOutput()) { | 13435 if (ShouldProduceTraceOutput()) { |
| 13492 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 13436 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 13493 } | 13437 } |
| 13494 | 13438 |
| 13495 #ifdef DEBUG | 13439 #ifdef DEBUG |
| 13496 graph_->Verify(false); // No full verify. | 13440 graph_->Verify(false); // No full verify. |
| 13497 #endif | 13441 #endif |
| 13498 } | 13442 } |
| 13499 | 13443 |
| 13500 } } // namespace v8::internal | 13444 } } // namespace v8::internal |
| OLD | NEW |