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

Side by Side Diff: src/code-stub-assembler.cc

Issue 2079823002: [stubs] Implementing CodeStubAssembler::GetOwnProperty(). (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fixing TryHasOwnProperty and addressing comments Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/code-stubs.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2016 the V8 project authors. All rights reserved. 1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/code-stub-assembler.h" 5 #include "src/code-stub-assembler.h"
6 #include "src/code-factory.h" 6 #include "src/code-factory.h"
7 #include "src/frames-inl.h" 7 #include "src/frames-inl.h"
8 #include "src/frames.h" 8 #include "src/frames.h"
9 #include "src/ic/stub-cache.h" 9 #include "src/ic/stub-cache.h"
10 10
(...skipping 10 matching lines...) Expand all
21 result_size) {} 21 result_size) {}
22 22
23 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone, 23 CodeStubAssembler::CodeStubAssembler(Isolate* isolate, Zone* zone,
24 int parameter_count, Code::Flags flags, 24 int parameter_count, Code::Flags flags,
25 const char* name) 25 const char* name)
26 : compiler::CodeAssembler(isolate, zone, parameter_count, flags, name) {} 26 : compiler::CodeAssembler(isolate, zone, parameter_count, flags, name) {}
27 27
28 void CodeStubAssembler::Assert(Node* condition) { 28 void CodeStubAssembler::Assert(Node* condition) {
29 #if defined(DEBUG) 29 #if defined(DEBUG)
30 Label ok(this); 30 Label ok(this);
31 Label not_ok(this); 31 Comment("[ Assert");
32 Branch(condition, &ok, &not_ok); 32 GotoIf(condition, &ok);
33 Bind(&not_ok);
34 DebugBreak(); 33 DebugBreak();
35 Goto(&ok); 34 Goto(&ok);
36 Bind(&ok); 35 Bind(&ok);
36 Comment("] Assert");
37 #endif 37 #endif
38 } 38 }
39 39
40 Node* CodeStubAssembler::BooleanMapConstant() { 40 Node* CodeStubAssembler::BooleanMapConstant() {
41 return HeapConstant(isolate()->factory()->boolean_map()); 41 return HeapConstant(isolate()->factory()->boolean_map());
42 } 42 }
43 43
44 Node* CodeStubAssembler::EmptyStringConstant() { 44 Node* CodeStubAssembler::EmptyStringConstant() {
45 return LoadRoot(Heap::kempty_stringRootIndex); 45 return LoadRoot(Heap::kempty_stringRootIndex);
46 } 46 }
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 Node* CodeStubAssembler::LoadBufferObject(Node* buffer, int offset, 487 Node* CodeStubAssembler::LoadBufferObject(Node* buffer, int offset,
488 MachineType rep) { 488 MachineType rep) {
489 return Load(rep, buffer, IntPtrConstant(offset)); 489 return Load(rep, buffer, IntPtrConstant(offset));
490 } 490 }
491 491
492 Node* CodeStubAssembler::LoadObjectField(Node* object, int offset, 492 Node* CodeStubAssembler::LoadObjectField(Node* object, int offset,
493 MachineType rep) { 493 MachineType rep) {
494 return Load(rep, object, IntPtrConstant(offset - kHeapObjectTag)); 494 return Load(rep, object, IntPtrConstant(offset - kHeapObjectTag));
495 } 495 }
496 496
497 Node* CodeStubAssembler::LoadObjectField(Node* object, Node* offset,
498 MachineType rep) {
499 return Load(rep, object, IntPtrSub(offset, IntPtrConstant(kHeapObjectTag)));
500 }
501
497 Node* CodeStubAssembler::LoadHeapNumberValue(Node* object) { 502 Node* CodeStubAssembler::LoadHeapNumberValue(Node* object) {
498 return LoadObjectField(object, HeapNumber::kValueOffset, 503 return LoadObjectField(object, HeapNumber::kValueOffset,
499 MachineType::Float64()); 504 MachineType::Float64());
500 } 505 }
501 506
502 Node* CodeStubAssembler::LoadMap(Node* object) { 507 Node* CodeStubAssembler::LoadMap(Node* object) {
503 return LoadObjectField(object, HeapObject::kMapOffset); 508 return LoadObjectField(object, HeapObject::kMapOffset);
504 } 509 }
505 510
506 Node* CodeStubAssembler::LoadInstanceType(Node* object) { 511 Node* CodeStubAssembler::LoadInstanceType(Node* object) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 } 550 }
546 551
547 Node* CodeStubAssembler::LoadMapPrototype(Node* map) { 552 Node* CodeStubAssembler::LoadMapPrototype(Node* map) {
548 return LoadObjectField(map, Map::kPrototypeOffset); 553 return LoadObjectField(map, Map::kPrototypeOffset);
549 } 554 }
550 555
551 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) { 556 Node* CodeStubAssembler::LoadMapInstanceSize(Node* map) {
552 return LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8()); 557 return LoadObjectField(map, Map::kInstanceSizeOffset, MachineType::Uint8());
553 } 558 }
554 559
560 Node* CodeStubAssembler::LoadMapInobjectProperties(Node* map) {
561 // See Map::GetInObjectProperties() for details.
562 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
563 Assert(Int32GreaterThanOrEqual(LoadMapInstanceType(map),
564 Int32Constant(FIRST_JS_OBJECT_TYPE)));
565 return LoadObjectField(
566 map, Map::kInObjectPropertiesOrConstructorFunctionIndexOffset,
567 MachineType::Uint8());
568 }
569
555 Node* CodeStubAssembler::LoadNameHashField(Node* name) { 570 Node* CodeStubAssembler::LoadNameHashField(Node* name) {
556 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32()); 571 return LoadObjectField(name, Name::kHashFieldOffset, MachineType::Uint32());
557 } 572 }
558 573
559 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) { 574 Node* CodeStubAssembler::LoadNameHash(Node* name, Label* if_hash_not_computed) {
560 Node* hash_field = LoadNameHashField(name); 575 Node* hash_field = LoadNameHashField(name);
561 if (if_hash_not_computed != nullptr) { 576 if (if_hash_not_computed != nullptr) {
562 GotoIf(WordEqual( 577 GotoIf(WordEqual(
563 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)), 578 Word32And(hash_field, Int32Constant(Name::kHashNotComputedMask)),
564 Int32Constant(0)), 579 Int32Constant(0)),
(...skipping 915 matching lines...) Expand 10 before | Expand all | Expand 10 after
1480 Node* value = Load(MachineType::Int32(), counter_address); 1495 Node* value = Load(MachineType::Int32(), counter_address);
1481 value = Int32Sub(value, Int32Constant(delta)); 1496 value = Int32Sub(value, Int32Constant(delta));
1482 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, value); 1497 StoreNoWriteBarrier(MachineRepresentation::kWord32, counter_address, value);
1483 } 1498 }
1484 } 1499 }
1485 1500
1486 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex, 1501 void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex,
1487 Variable* var_index, Label* if_keyisunique, 1502 Variable* var_index, Label* if_keyisunique,
1488 Label* if_bailout) { 1503 Label* if_bailout) {
1489 DCHECK_EQ(MachineRepresentation::kWord32, var_index->rep()); 1504 DCHECK_EQ(MachineRepresentation::kWord32, var_index->rep());
1505 Comment("TryToName");
1490 1506
1491 Label if_keyissmi(this), if_keyisnotsmi(this); 1507 Label if_keyissmi(this), if_keyisnotsmi(this);
1492 Branch(WordIsSmi(key), &if_keyissmi, &if_keyisnotsmi); 1508 Branch(WordIsSmi(key), &if_keyissmi, &if_keyisnotsmi);
1493 Bind(&if_keyissmi); 1509 Bind(&if_keyissmi);
1494 { 1510 {
1495 // Negative smi keys are named properties. Handle in the runtime. 1511 // Negative smi keys are named properties. Handle in the runtime.
1496 GotoUnless(WordIsPositiveSmi(key), if_bailout); 1512 GotoUnless(WordIsPositiveSmi(key), if_bailout);
1497 1513
1498 var_index->Bind(SmiToWord32(key)); 1514 var_index->Bind(SmiToWord32(key));
1499 Goto(if_keyisindex); 1515 Goto(if_keyisindex);
(...skipping 22 matching lines...) Expand all
1522 GotoIf(Word32NotEqual(bit, Int32Constant(0)), if_keyisunique); 1538 GotoIf(Word32NotEqual(bit, Int32Constant(0)), if_keyisunique);
1523 // Key is an index. Check if it is small enough to be encoded in the 1539 // Key is an index. Check if it is small enough to be encoded in the
1524 // hash_field. Handle too big array index in runtime. 1540 // hash_field. Handle too big array index in runtime.
1525 bit = Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask)); 1541 bit = Word32And(hash, Int32Constant(Name::kContainsCachedArrayIndexMask));
1526 GotoIf(Word32NotEqual(bit, Int32Constant(0)), if_bailout); 1542 GotoIf(Word32NotEqual(bit, Int32Constant(0)), if_bailout);
1527 var_index->Bind(BitFieldDecode<Name::ArrayIndexValueBits>(hash)); 1543 var_index->Bind(BitFieldDecode<Name::ArrayIndexValueBits>(hash));
1528 Goto(if_keyisindex); 1544 Goto(if_keyisindex);
1529 } 1545 }
1530 1546
1531 template <typename Dictionary> 1547 template <typename Dictionary>
1548 Node* CodeStubAssembler::EntryToIndex(Node* entry, int field_index) {
1549 Node* entry_index = Int32Mul(entry, Int32Constant(Dictionary::kEntrySize));
1550 return Int32Add(entry_index,
1551 Int32Constant(Dictionary::kElementsStartIndex + field_index));
1552 }
1553
1554 template <typename Dictionary>
1532 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary, 1555 void CodeStubAssembler::NameDictionaryLookup(Node* dictionary,
1533 Node* unique_name, Label* if_found, 1556 Node* unique_name, Label* if_found,
1534 Variable* var_entry, 1557 Variable* var_name_index,
1535 Label* if_not_found, 1558 Label* if_not_found,
1536 int inlined_probes) { 1559 int inlined_probes) {
1537 DCHECK_EQ(MachineRepresentation::kWord32, var_entry->rep()); 1560 DCHECK_EQ(MachineRepresentation::kWord32, var_name_index->rep());
1538 1561 Comment("NameDictionaryLookup");
1539 const int kElementsStartOffset =
1540 Dictionary::kElementsStartIndex * kPointerSize;
1541 1562
1542 Node* capacity = SmiToWord32(LoadFixedArrayElement( 1563 Node* capacity = SmiToWord32(LoadFixedArrayElement(
1543 dictionary, Int32Constant(Dictionary::kCapacityIndex))); 1564 dictionary, Int32Constant(Dictionary::kCapacityIndex)));
1544 Node* mask = Int32Sub(capacity, Int32Constant(1)); 1565 Node* mask = Int32Sub(capacity, Int32Constant(1));
1545 Node* hash = LoadNameHash(unique_name); 1566 Node* hash = LoadNameHash(unique_name);
1546 1567
1547 // See Dictionary::FirstProbe(). 1568 // See Dictionary::FirstProbe().
1548 Node* count = Int32Constant(0); 1569 Node* count = Int32Constant(0);
1549 Node* entry = Word32And(hash, mask); 1570 Node* entry = Word32And(hash, mask);
1550 1571
1551 for (int i = 0; i < inlined_probes; i++) { 1572 for (int i = 0; i < inlined_probes; i++) {
1552 // See Dictionary::EntryToIndex() 1573 Node* index = EntryToIndex<Dictionary>(entry);
1553 Node* index = Int32Mul(entry, Int32Constant(Dictionary::kEntrySize)); 1574 var_name_index->Bind(index);
1554 Node* current = 1575
1555 LoadFixedArrayElement(dictionary, index, kElementsStartOffset); 1576 Node* current = LoadFixedArrayElement(dictionary, index);
1556 var_entry->Bind(entry);
1557 GotoIf(WordEqual(current, unique_name), if_found); 1577 GotoIf(WordEqual(current, unique_name), if_found);
1558 1578
1559 // See Dictionary::NextProbe(). 1579 // See Dictionary::NextProbe().
1560 count = Int32Constant(i + 1); 1580 count = Int32Constant(i + 1);
1561 entry = Word32And(Int32Add(entry, count), mask); 1581 entry = Word32And(Int32Add(entry, count), mask);
1562 } 1582 }
1563 1583
1564 Node* undefined = UndefinedConstant(); 1584 Node* undefined = UndefinedConstant();
1565 1585
1566 Variable var_count(this, MachineRepresentation::kWord32); 1586 Variable var_count(this, MachineRepresentation::kWord32);
1567 Variable* loop_vars[] = {&var_count, var_entry}; 1587 Variable var_entry(this, MachineRepresentation::kWord32);
1568 Label loop(this, 2, loop_vars); 1588 Variable* loop_vars[] = {&var_count, &var_entry, var_name_index};
1589 Label loop(this, 3, loop_vars);
1569 var_count.Bind(count); 1590 var_count.Bind(count);
1570 var_entry->Bind(entry); 1591 var_entry.Bind(entry);
1571 Goto(&loop); 1592 Goto(&loop);
1572 Bind(&loop); 1593 Bind(&loop);
1573 { 1594 {
1574 Node* count = var_count.value(); 1595 Node* count = var_count.value();
1575 Node* entry = var_entry->value(); 1596 Node* entry = var_entry.value();
1576 1597
1577 // See Dictionary::EntryToIndex() 1598 Node* index = EntryToIndex<Dictionary>(entry);
1578 Node* index = Int32Mul(entry, Int32Constant(Dictionary::kEntrySize)); 1599 var_name_index->Bind(index);
1579 Node* current = 1600
1580 LoadFixedArrayElement(dictionary, index, kElementsStartOffset); 1601 Node* current = LoadFixedArrayElement(dictionary, index);
1581 GotoIf(WordEqual(current, undefined), if_not_found); 1602 GotoIf(WordEqual(current, undefined), if_not_found);
1582 GotoIf(WordEqual(current, unique_name), if_found); 1603 GotoIf(WordEqual(current, unique_name), if_found);
1583 1604
1584 // See Dictionary::NextProbe(). 1605 // See Dictionary::NextProbe().
1585 count = Int32Add(count, Int32Constant(1)); 1606 count = Int32Add(count, Int32Constant(1));
1586 entry = Word32And(Int32Add(entry, count), mask); 1607 entry = Word32And(Int32Add(entry, count), mask);
1587 1608
1588 var_count.Bind(count); 1609 var_count.Bind(count);
1589 var_entry->Bind(entry); 1610 var_entry.Bind(entry);
1590 Goto(&loop); 1611 Goto(&loop);
1591 } 1612 }
1592 } 1613 }
1593 1614
1594 // Instantiate template methods to workaround GCC compilation issue. 1615 // Instantiate template methods to workaround GCC compilation issue.
1595 template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>( 1616 template void CodeStubAssembler::NameDictionaryLookup<NameDictionary>(
1596 Node*, Node*, Label*, Variable*, Label*, int); 1617 Node*, Node*, Label*, Variable*, Label*, int);
1597 template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>( 1618 template void CodeStubAssembler::NameDictionaryLookup<GlobalDictionary>(
1598 Node*, Node*, Label*, Variable*, Label*, int); 1619 Node*, Node*, Label*, Variable*, Label*, int);
1599 1620
(...skipping 10 matching lines...) Expand all
1610 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16))); 1631 hash = Word32Xor(hash, Word32Shr(hash, Int32Constant(16)));
1611 return Word32And(hash, Int32Constant(0x3fffffff)); 1632 return Word32And(hash, Int32Constant(0x3fffffff));
1612 } 1633 }
1613 1634
1614 template <typename Dictionary> 1635 template <typename Dictionary>
1615 void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, Node* key, 1636 void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary, Node* key,
1616 Label* if_found, 1637 Label* if_found,
1617 Variable* var_entry, 1638 Variable* var_entry,
1618 Label* if_not_found) { 1639 Label* if_not_found) {
1619 DCHECK_EQ(MachineRepresentation::kWord32, var_entry->rep()); 1640 DCHECK_EQ(MachineRepresentation::kWord32, var_entry->rep());
1620 1641 Comment("NumberDictionaryLookup");
1621 const int kElementsStartOffset =
1622 Dictionary::kElementsStartIndex * kPointerSize;
1623 1642
1624 Node* capacity = SmiToWord32(LoadFixedArrayElement( 1643 Node* capacity = SmiToWord32(LoadFixedArrayElement(
1625 dictionary, Int32Constant(Dictionary::kCapacityIndex))); 1644 dictionary, Int32Constant(Dictionary::kCapacityIndex)));
1626 Node* mask = Int32Sub(capacity, Int32Constant(1)); 1645 Node* mask = Int32Sub(capacity, Int32Constant(1));
1627 1646
1628 Node* seed; 1647 Node* seed;
1629 if (Dictionary::ShapeT::UsesSeed) { 1648 if (Dictionary::ShapeT::UsesSeed) {
1630 seed = HashSeed(); 1649 seed = HashSeed();
1631 } else { 1650 } else {
1632 seed = Int32Constant(kZeroHashSeed); 1651 seed = Int32Constant(kZeroHashSeed);
(...skipping 12 matching lines...) Expand all
1645 Variable* loop_vars[] = {&var_count, var_entry}; 1664 Variable* loop_vars[] = {&var_count, var_entry};
1646 Label loop(this, 2, loop_vars); 1665 Label loop(this, 2, loop_vars);
1647 var_count.Bind(count); 1666 var_count.Bind(count);
1648 var_entry->Bind(entry); 1667 var_entry->Bind(entry);
1649 Goto(&loop); 1668 Goto(&loop);
1650 Bind(&loop); 1669 Bind(&loop);
1651 { 1670 {
1652 Node* count = var_count.value(); 1671 Node* count = var_count.value();
1653 Node* entry = var_entry->value(); 1672 Node* entry = var_entry->value();
1654 1673
1655 // See Dictionary::EntryToIndex() 1674 Node* index = EntryToIndex<Dictionary>(entry);
1656 Node* index = Int32Mul(entry, Int32Constant(Dictionary::kEntrySize)); 1675 Node* current = LoadFixedArrayElement(dictionary, index);
1657 Node* current =
1658 LoadFixedArrayElement(dictionary, index, kElementsStartOffset);
1659 GotoIf(WordEqual(current, undefined), if_not_found); 1676 GotoIf(WordEqual(current, undefined), if_not_found);
1660 Label next_probe(this); 1677 Label next_probe(this);
1661 { 1678 {
1662 Label if_currentissmi(this), if_currentisnotsmi(this); 1679 Label if_currentissmi(this), if_currentisnotsmi(this);
1663 Branch(WordIsSmi(current), &if_currentissmi, &if_currentisnotsmi); 1680 Branch(WordIsSmi(current), &if_currentissmi, &if_currentisnotsmi);
1664 Bind(&if_currentissmi); 1681 Bind(&if_currentissmi);
1665 { 1682 {
1666 Node* current_value = SmiToWord32(current); 1683 Node* current_value = SmiToWord32(current);
1667 Branch(Word32Equal(current_value, key), if_found, &next_probe); 1684 Branch(Word32Equal(current_value, key), if_found, &next_probe);
1668 } 1685 }
(...skipping 11 matching lines...) Expand all
1680 // See Dictionary::NextProbe(). 1697 // See Dictionary::NextProbe().
1681 count = Int32Add(count, Int32Constant(1)); 1698 count = Int32Add(count, Int32Constant(1));
1682 entry = Word32And(Int32Add(entry, count), mask); 1699 entry = Word32And(Int32Add(entry, count), mask);
1683 1700
1684 var_count.Bind(count); 1701 var_count.Bind(count);
1685 var_entry->Bind(entry); 1702 var_entry->Bind(entry);
1686 Goto(&loop); 1703 Goto(&loop);
1687 } 1704 }
1688 } 1705 }
1689 1706
1690 void CodeStubAssembler::TryLookupProperty(Node* object, Node* map, 1707 void CodeStubAssembler::TryLookupProperty(
1691 Node* instance_type, 1708 Node* object, Node* map, Node* instance_type, Node* unique_name,
1692 Node* unique_name, Label* if_found, 1709 Label* if_found_fast, Label* if_found_dict, Label* if_found_global,
1693 Label* if_not_found, 1710 Variable* var_meta_storage, Variable* var_name_index, Label* if_not_found,
1694 Label* if_bailout) { 1711 Label* if_bailout) {
1712 DCHECK_EQ(MachineRepresentation::kTagged, var_meta_storage->rep());
1713 DCHECK_EQ(MachineRepresentation::kWord32, var_name_index->rep());
1714
1695 Label if_objectisspecial(this); 1715 Label if_objectisspecial(this);
1696 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); 1716 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE);
1697 GotoIf(Int32LessThanOrEqual(instance_type, 1717 GotoIf(Int32LessThanOrEqual(instance_type,
1698 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), 1718 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
1699 &if_objectisspecial); 1719 &if_objectisspecial);
1700 1720
1721 Node* bit_field = LoadMapBitField(map);
1722 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor |
1723 1 << Map::kIsAccessCheckNeeded);
1724 Assert(Word32Equal(Word32And(bit_field, mask), Int32Constant(0)));
1725
1701 Node* bit_field3 = LoadMapBitField3(map); 1726 Node* bit_field3 = LoadMapBitField3(map);
1702 Node* bit = BitFieldDecode<Map::DictionaryMap>(bit_field3); 1727 Node* bit = BitFieldDecode<Map::DictionaryMap>(bit_field3);
1703 Label if_isfastmap(this), if_isslowmap(this); 1728 Label if_isfastmap(this), if_isslowmap(this);
1704 Branch(Word32Equal(bit, Int32Constant(0)), &if_isfastmap, &if_isslowmap); 1729 Branch(Word32Equal(bit, Int32Constant(0)), &if_isfastmap, &if_isslowmap);
1705 Bind(&if_isfastmap); 1730 Bind(&if_isfastmap);
1706 { 1731 {
1732 Comment("DescriptorArrayLookup");
1707 Node* nof = BitFieldDecode<Map::NumberOfOwnDescriptorsBits>(bit_field3); 1733 Node* nof = BitFieldDecode<Map::NumberOfOwnDescriptorsBits>(bit_field3);
1708 // Bail out to the runtime for large numbers of own descriptors. The stub 1734 // Bail out to the runtime for large numbers of own descriptors. The stub
1709 // only does linear search, which becomes too expensive in that case. 1735 // only does linear search, which becomes too expensive in that case.
1710 { 1736 {
1711 static const int32_t kMaxLinear = 210; 1737 static const int32_t kMaxLinear = 210;
1712 GotoIf(Int32GreaterThan(nof, Int32Constant(kMaxLinear)), if_bailout); 1738 GotoIf(Int32GreaterThan(nof, Int32Constant(kMaxLinear)), if_bailout);
1713 } 1739 }
1714 Node* descriptors = LoadMapDescriptors(map); 1740 Node* descriptors = LoadMapDescriptors(map);
1741 var_meta_storage->Bind(descriptors);
1715 1742
1716 Variable var_descriptor(this, MachineRepresentation::kWord32); 1743 Variable var_descriptor(this, MachineRepresentation::kWord32);
1717 Label loop(this, &var_descriptor); 1744 Label loop(this, &var_descriptor);
1718 var_descriptor.Bind(Int32Constant(0)); 1745 var_descriptor.Bind(Int32Constant(0));
1719 Goto(&loop); 1746 Goto(&loop);
1720 Bind(&loop); 1747 Bind(&loop);
1721 { 1748 {
1722 Node* index = var_descriptor.value(); 1749 Node* index = var_descriptor.value();
1723 Node* offset = Int32Constant(DescriptorArray::ToKeyIndex(0)); 1750 Node* name_offset = Int32Constant(DescriptorArray::ToKeyIndex(0));
1724 Node* factor = Int32Constant(DescriptorArray::kDescriptorSize); 1751 Node* factor = Int32Constant(DescriptorArray::kDescriptorSize);
1725 GotoIf(Word32Equal(index, nof), if_not_found); 1752 GotoIf(Word32Equal(index, nof), if_not_found);
1726 1753
1727 Node* array_index = Int32Add(offset, Int32Mul(index, factor)); 1754 Node* name_index = Int32Add(name_offset, Int32Mul(index, factor));
1728 Node* current = LoadFixedArrayElement(descriptors, array_index); 1755 Node* name = LoadFixedArrayElement(descriptors, name_index);
1729 GotoIf(WordEqual(current, unique_name), if_found); 1756
1757 var_name_index->Bind(name_index);
1758 GotoIf(WordEqual(name, unique_name), if_found_fast);
1730 1759
1731 var_descriptor.Bind(Int32Add(index, Int32Constant(1))); 1760 var_descriptor.Bind(Int32Add(index, Int32Constant(1)));
1732 Goto(&loop); 1761 Goto(&loop);
1733 } 1762 }
1734 } 1763 }
1735 Bind(&if_isslowmap); 1764 Bind(&if_isslowmap);
1736 { 1765 {
1737 Variable var_entry(this, MachineRepresentation::kWord32);
1738 Node* dictionary = LoadProperties(object); 1766 Node* dictionary = LoadProperties(object);
1739 1767 var_meta_storage->Bind(dictionary);
1740 NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found, 1768
1741 &var_entry, if_not_found); 1769 NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found_dict,
1770 var_name_index, if_not_found);
1742 } 1771 }
1743 Bind(&if_objectisspecial); 1772 Bind(&if_objectisspecial);
1744 { 1773 {
1745 // Handle global object here and other special objects in runtime. 1774 // Handle global object here and other special objects in runtime.
1746 GotoUnless(Word32Equal(instance_type, Int32Constant(JS_GLOBAL_OBJECT_TYPE)), 1775 GotoUnless(Word32Equal(instance_type, Int32Constant(JS_GLOBAL_OBJECT_TYPE)),
1747 if_bailout); 1776 if_bailout);
1748 Variable var_entry(this, MachineRepresentation::kWord32); 1777
1778 // Handle interceptors and access checks in runtime.
1779 Node* bit_field = LoadMapBitField(map);
1780 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor |
1781 1 << Map::kIsAccessCheckNeeded);
1782 GotoIf(Word32NotEqual(Word32And(bit_field, mask), Int32Constant(0)),
1783 if_bailout);
1784
1749 Node* dictionary = LoadProperties(object); 1785 Node* dictionary = LoadProperties(object);
1750 1786 var_meta_storage->Bind(dictionary);
1751 NameDictionaryLookup<GlobalDictionary>(dictionary, unique_name, if_found, 1787
1752 &var_entry, if_not_found); 1788 NameDictionaryLookup<GlobalDictionary>(
1753 } 1789 dictionary, unique_name, if_found_global, var_name_index, if_not_found);
1754 } 1790 }
1755 1791 }
1792
1793 void CodeStubAssembler::TryHasOwnProperty(compiler::Node* object,
1794 compiler::Node* map,
1795 compiler::Node* instance_type,
1796 compiler::Node* unique_name,
1797 Label* if_found, Label* if_not_found,
1798 Label* if_bailout) {
1799 Comment("TryHasOwnProperty");
1800 Variable var_meta_storage(this, MachineRepresentation::kTagged);
1801 Variable var_name_index(this, MachineRepresentation::kWord32);
1802
1803 Label if_found_global(this);
1804 TryLookupProperty(object, map, instance_type, unique_name, if_found, if_found,
1805 &if_found_global, &var_meta_storage, &var_name_index,
1806 if_not_found, if_bailout);
1807 Bind(&if_found_global);
1808 {
1809 Variable var_value(this, MachineRepresentation::kTagged);
1810 Variable var_details(this, MachineRepresentation::kWord32);
1811 // Check if the property cell is not deleted.
1812 LoadPropertyFromGlobalDictionary(var_meta_storage.value(),
1813 var_name_index.value(), &var_value,
1814 &var_details, if_not_found);
1815 Goto(if_found);
1816 }
1817 }
1818
1819 void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
1820 Node* descriptors,
1821 Node* name_index,
1822 Variable* var_details,
1823 Variable* var_value) {
1824 DCHECK_EQ(MachineRepresentation::kWord32, var_details->rep());
1825 DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep());
1826 Comment("[ LoadPropertyFromFastObject");
1827
1828 const int name_to_details_offset =
1829 (DescriptorArray::kDescriptorDetails - DescriptorArray::kDescriptorKey) *
1830 kPointerSize;
1831 const int name_to_value_offset =
1832 (DescriptorArray::kDescriptorValue - DescriptorArray::kDescriptorKey) *
1833 kPointerSize;
1834
1835 Node* details = SmiToWord32(
1836 LoadFixedArrayElement(descriptors, name_index, name_to_details_offset));
1837 var_details->Bind(details);
1838
1839 Node* location = BitFieldDecode<PropertyDetails::LocationField>(details);
1840
1841 Label if_in_field(this), if_in_descriptor(this), done(this);
1842 Branch(Word32Equal(location, Int32Constant(kField)), &if_in_field,
1843 &if_in_descriptor);
1844 Bind(&if_in_field);
1845 {
1846 Node* field_index =
1847 BitFieldDecode<PropertyDetails::FieldIndexField>(details);
1848 Node* representation =
1849 BitFieldDecode<PropertyDetails::RepresentationField>(details);
1850
1851 Node* inobject_properties = LoadMapInobjectProperties(map);
1852
1853 Label if_inobject(this), if_backing_store(this);
1854 Variable var_double_value(this, MachineRepresentation::kFloat64);
1855 Label rebox_double(this, &var_double_value);
1856 BranchIfInt32LessThan(field_index, inobject_properties, &if_inobject,
1857 &if_backing_store);
1858 Bind(&if_inobject);
1859 {
1860 Comment("if_inobject");
1861 Node* field_offset = ChangeInt32ToIntPtr(
1862 Int32Mul(Int32Sub(LoadMapInstanceSize(map),
1863 Int32Sub(inobject_properties, field_index)),
1864 Int32Constant(kPointerSize)));
1865
1866 Label if_double(this), if_tagged(this);
1867 BranchIfWord32NotEqual(representation,
1868 Int32Constant(Representation::kDouble), &if_tagged,
1869 &if_double);
1870 Bind(&if_tagged);
1871 {
1872 var_value->Bind(LoadObjectField(object, field_offset));
1873 Goto(&done);
1874 }
1875 Bind(&if_double);
1876 {
1877 if (FLAG_unbox_double_fields) {
1878 var_double_value.Bind(
1879 LoadObjectField(object, field_offset, MachineType::Float64()));
1880 } else {
1881 Node* mutable_heap_number = LoadObjectField(object, field_offset);
1882 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number));
1883 }
1884 Goto(&rebox_double);
1885 }
1886 }
1887 Bind(&if_backing_store);
1888 {
1889 Comment("if_backing_store");
1890 Node* properties = LoadProperties(object);
1891 field_index = Int32Sub(field_index, inobject_properties);
1892 Node* value = LoadFixedArrayElement(properties, field_index);
1893
1894 Label if_double(this), if_tagged(this);
1895 BranchIfWord32NotEqual(representation,
1896 Int32Constant(Representation::kDouble), &if_tagged,
1897 &if_double);
1898 Bind(&if_tagged);
1899 {
1900 var_value->Bind(value);
1901 Goto(&done);
1902 }
1903 Bind(&if_double);
1904 {
1905 var_double_value.Bind(LoadHeapNumberValue(value));
1906 Goto(&rebox_double);
1907 }
1908 }
1909 Bind(&rebox_double);
1910 {
1911 Comment("rebox_double");
1912 Node* heap_number = AllocateHeapNumber();
1913 StoreHeapNumberValue(heap_number, var_double_value.value());
1914 var_value->Bind(heap_number);
1915 Goto(&done);
1916 }
1917 }
1918 Bind(&if_in_descriptor);
1919 {
1920 Node* value =
1921 LoadFixedArrayElement(descriptors, name_index, name_to_value_offset);
1922 var_value->Bind(value);
1923 Goto(&done);
1924 }
1925 Bind(&done);
1926
1927 Comment("] LoadPropertyFromFastObject");
1928 }
1929
1930 void CodeStubAssembler::LoadPropertyFromNameDictionary(Node* dictionary,
1931 Node* name_index,
1932 Variable* var_details,
1933 Variable* var_value) {
1934 Comment("LoadPropertyFromNameDictionary");
1935
1936 const int name_to_details_offset =
1937 (NameDictionary::kEntryDetailsIndex - NameDictionary::kEntryKeyIndex) *
1938 kPointerSize;
1939 const int name_to_value_offset =
1940 (NameDictionary::kEntryValueIndex - NameDictionary::kEntryKeyIndex) *
1941 kPointerSize;
1942
1943 Node* details = SmiToWord32(
1944 LoadFixedArrayElement(dictionary, name_index, name_to_details_offset));
1945
1946 var_details->Bind(details);
1947 var_value->Bind(
1948 LoadFixedArrayElement(dictionary, name_index, name_to_value_offset));
1949
1950 Comment("] LoadPropertyFromNameDictionary");
1951 }
1952
1953 void CodeStubAssembler::LoadPropertyFromGlobalDictionary(Node* dictionary,
1954 Node* name_index,
1955 Variable* var_details,
1956 Variable* var_value,
1957 Label* if_deleted) {
1958 Comment("[ LoadPropertyFromGlobalDictionary");
1959
1960 const int name_to_value_offset =
1961 (GlobalDictionary::kEntryValueIndex - GlobalDictionary::kEntryKeyIndex) *
1962 kPointerSize;
1963
1964 Node* property_cell =
1965 LoadFixedArrayElement(dictionary, name_index, name_to_value_offset);
1966
1967 Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset);
1968 GotoIf(WordEqual(value, TheHoleConstant()), if_deleted);
1969
1970 var_value->Bind(value);
1971
1972 Node* details =
1973 SmiToWord32(LoadObjectField(property_cell, PropertyCell::kDetailsOffset));
1974 var_details->Bind(details);
1975
1976 Comment("] LoadPropertyFromGlobalDictionary");
1977 }
1978
1979 void CodeStubAssembler::TryGetOwnProperty(
1980 Node* context, Node* receiver, Node* object, Node* map, Node* instance_type,
1981 Node* unique_name, Label* if_found_value, Variable* var_value,
1982 Label* if_not_found, Label* if_bailout) {
1983 DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep());
1984 Comment("TryGetOwnProperty");
1985
1986 Variable var_meta_storage(this, MachineRepresentation::kTagged);
1987 Variable var_entry(this, MachineRepresentation::kWord32);
1988
1989 Label if_found_fast(this), if_found_dict(this), if_found_global(this);
1990
1991 Variable var_details(this, MachineRepresentation::kWord32);
1992 Variable* vars[] = {var_value, &var_details};
1993 Label if_found(this, 2, vars);
1994
1995 TryLookupProperty(object, map, instance_type, unique_name, &if_found_fast,
1996 &if_found_dict, &if_found_global, &var_meta_storage,
1997 &var_entry, if_not_found, if_bailout);
1998 Bind(&if_found_fast);
1999 {
2000 Node* descriptors = var_meta_storage.value();
2001 Node* name_index = var_entry.value();
2002
2003 LoadPropertyFromFastObject(object, map, descriptors, name_index,
2004 &var_details, var_value);
2005 Goto(&if_found);
2006 }
2007 Bind(&if_found_dict);
2008 {
2009 Node* dictionary = var_meta_storage.value();
2010 Node* entry = var_entry.value();
2011 LoadPropertyFromNameDictionary(dictionary, entry, &var_details, var_value);
2012 Goto(&if_found);
2013 }
2014 Bind(&if_found_global);
2015 {
2016 Node* dictionary = var_meta_storage.value();
2017 Node* entry = var_entry.value();
2018
2019 LoadPropertyFromGlobalDictionary(dictionary, entry, &var_details, var_value,
2020 if_not_found);
2021 Goto(&if_found);
2022 }
2023 // Here we have details and value which could be an accessor.
2024 Bind(&if_found);
2025 {
2026 Node* details = var_details.value();
2027 Node* kind = BitFieldDecode<PropertyDetails::KindField>(details);
2028
2029 Label if_accessor(this);
2030 Branch(Word32Equal(kind, Int32Constant(kData)), if_found_value,
2031 &if_accessor);
2032 Bind(&if_accessor);
2033 {
2034 Node* accessor_pair = var_value->value();
2035 GotoIf(Word32Equal(LoadInstanceType(accessor_pair),
2036 Int32Constant(ACCESSOR_INFO_TYPE)),
2037 if_bailout);
2038 AssertInstanceType(accessor_pair, ACCESSOR_PAIR_TYPE);
2039 Node* getter =
2040 LoadObjectField(accessor_pair, AccessorPair::kGetterOffset);
2041 Node* getter_map = LoadMap(getter);
2042 Node* instance_type = LoadMapInstanceType(getter_map);
2043 // FunctionTemplateInfo getters are not supported yet.
2044 GotoIf(Word32Equal(instance_type,
2045 Int32Constant(FUNCTION_TEMPLATE_INFO_TYPE)),
2046 if_bailout);
2047
2048 // Return undefined if the {getter} is not callable.
2049 var_value->Bind(UndefinedConstant());
2050 GotoIf(Word32Equal(Word32And(LoadMapBitField(getter_map),
2051 Int32Constant(1 << Map::kIsCallable)),
2052 Int32Constant(0)),
2053 if_found_value);
2054
2055 // Call the accessor.
2056 Callable callable = CodeFactory::Call(isolate());
2057 Node* result = CallJS(callable, context, getter, receiver);
2058 var_value->Bind(result);
2059 Goto(if_found_value);
2060 }
2061 }
2062 }
2063
1756 void CodeStubAssembler::TryLookupElement(Node* object, Node* map, 2064 void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
1757 Node* instance_type, Node* index, 2065 Node* instance_type, Node* index,
1758 Label* if_found, Label* if_not_found, 2066 Label* if_found, Label* if_not_found,
1759 Label* if_bailout) { 2067 Label* if_bailout) {
1760 // Handle special objects in runtime. 2068 // Handle special objects in runtime.
1761 GotoIf(Int32LessThanOrEqual(instance_type, 2069 GotoIf(Int32LessThanOrEqual(instance_type,
1762 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), 2070 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
1763 if_bailout); 2071 if_bailout);
1764 2072
1765 Node* bit_field2 = LoadMapBitField2(map); 2073 Node* bit_field2 = LoadMapBitField2(map);
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after
2355 } 2663 }
2356 Bind(&miss); 2664 Bind(&miss);
2357 { 2665 {
2358 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->name, p->slot, 2666 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->name, p->slot,
2359 p->vector); 2667 p->vector);
2360 } 2668 }
2361 } 2669 }
2362 2670
2363 } // namespace internal 2671 } // namespace internal
2364 } // namespace v8 2672 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/code-stubs.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698