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

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: Created 4 years, 6 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
1715 {
1716 Node* bit_field = LoadMapBitField(map);
1717 Node* mask = Int32Constant(1 << Map::kHasNamedInterceptor |
1718 1 << Map::kIsAccessCheckNeeded);
1719 GotoIf(Word32NotEqual(Word32And(bit_field, mask), Int32Constant(0)),
Toon Verwaest 2016/06/23 12:34:54 This shouldn't be possible if we check LAST_SPECIA
Igor Sheludko 2016/06/27 09:32:17 Done.
1720 if_bailout);
1721 }
1722
1695 Label if_objectisspecial(this); 1723 Label if_objectisspecial(this);
1696 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE); 1724 STATIC_ASSERT(JS_GLOBAL_OBJECT_TYPE <= LAST_SPECIAL_RECEIVER_TYPE);
1697 GotoIf(Int32LessThanOrEqual(instance_type, 1725 GotoIf(Int32LessThanOrEqual(instance_type,
1698 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), 1726 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
1699 &if_objectisspecial); 1727 &if_objectisspecial);
1700 1728
1701 Node* bit_field3 = LoadMapBitField3(map); 1729 Node* bit_field3 = LoadMapBitField3(map);
1702 Node* bit = BitFieldDecode<Map::DictionaryMap>(bit_field3); 1730 Node* bit = BitFieldDecode<Map::DictionaryMap>(bit_field3);
1703 Label if_isfastmap(this), if_isslowmap(this); 1731 Label if_isfastmap(this), if_isslowmap(this);
1704 Branch(Word32Equal(bit, Int32Constant(0)), &if_isfastmap, &if_isslowmap); 1732 Branch(Word32Equal(bit, Int32Constant(0)), &if_isfastmap, &if_isslowmap);
1705 Bind(&if_isfastmap); 1733 Bind(&if_isfastmap);
1706 { 1734 {
1735 Comment("DescriptorArrayLookup");
1707 Node* nof = BitFieldDecode<Map::NumberOfOwnDescriptorsBits>(bit_field3); 1736 Node* nof = BitFieldDecode<Map::NumberOfOwnDescriptorsBits>(bit_field3);
1708 // Bail out to the runtime for large numbers of own descriptors. The stub 1737 // 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. 1738 // only does linear search, which becomes too expensive in that case.
1710 { 1739 {
1711 static const int32_t kMaxLinear = 210; 1740 static const int32_t kMaxLinear = 210;
1712 GotoIf(Int32GreaterThan(nof, Int32Constant(kMaxLinear)), if_bailout); 1741 GotoIf(Int32GreaterThan(nof, Int32Constant(kMaxLinear)), if_bailout);
1713 } 1742 }
1714 Node* descriptors = LoadMapDescriptors(map); 1743 Node* descriptors = LoadMapDescriptors(map);
1744 var_meta_storage->Bind(descriptors);
1715 1745
1716 Variable var_descriptor(this, MachineRepresentation::kWord32); 1746 Variable var_descriptor(this, MachineRepresentation::kWord32);
1717 Label loop(this, &var_descriptor); 1747 Label loop(this, &var_descriptor);
1718 var_descriptor.Bind(Int32Constant(0)); 1748 var_descriptor.Bind(Int32Constant(0));
1719 Goto(&loop); 1749 Goto(&loop);
1720 Bind(&loop); 1750 Bind(&loop);
1721 { 1751 {
1722 Node* index = var_descriptor.value(); 1752 Node* index = var_descriptor.value();
1723 Node* offset = Int32Constant(DescriptorArray::ToKeyIndex(0)); 1753 Node* name_offset = Int32Constant(DescriptorArray::ToKeyIndex(0));
1724 Node* factor = Int32Constant(DescriptorArray::kDescriptorSize); 1754 Node* factor = Int32Constant(DescriptorArray::kDescriptorSize);
1725 GotoIf(Word32Equal(index, nof), if_not_found); 1755 GotoIf(Word32Equal(index, nof), if_not_found);
1726 1756
1727 Node* array_index = Int32Add(offset, Int32Mul(index, factor)); 1757 Node* name_index = Int32Add(name_offset, Int32Mul(index, factor));
1728 Node* current = LoadFixedArrayElement(descriptors, array_index); 1758 Node* name = LoadFixedArrayElement(descriptors, name_index);
1729 GotoIf(WordEqual(current, unique_name), if_found); 1759
1760 var_name_index->Bind(name_index);
1761 GotoIf(WordEqual(name, unique_name), if_found_fast);
1730 1762
1731 var_descriptor.Bind(Int32Add(index, Int32Constant(1))); 1763 var_descriptor.Bind(Int32Add(index, Int32Constant(1)));
1732 Goto(&loop); 1764 Goto(&loop);
1733 } 1765 }
1734 } 1766 }
1735 Bind(&if_isslowmap); 1767 Bind(&if_isslowmap);
1736 { 1768 {
1737 Variable var_entry(this, MachineRepresentation::kWord32);
1738 Node* dictionary = LoadProperties(object); 1769 Node* dictionary = LoadProperties(object);
1739 1770 var_meta_storage->Bind(dictionary);
1740 NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found, 1771
1741 &var_entry, if_not_found); 1772 NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found_dict,
1773 var_name_index, if_not_found);
1742 } 1774 }
1743 Bind(&if_objectisspecial); 1775 Bind(&if_objectisspecial);
1744 { 1776 {
1745 // Handle global object here and other special objects in runtime. 1777 // Handle global object here and other special objects in runtime.
1746 GotoUnless(Word32Equal(instance_type, Int32Constant(JS_GLOBAL_OBJECT_TYPE)), 1778 GotoUnless(Word32Equal(instance_type, Int32Constant(JS_GLOBAL_OBJECT_TYPE)),
1747 if_bailout); 1779 if_bailout);
1748 Variable var_entry(this, MachineRepresentation::kWord32); 1780
1749 Node* dictionary = LoadProperties(object); 1781 Node* dictionary = LoadProperties(object);
1750 1782 var_meta_storage->Bind(dictionary);
1751 NameDictionaryLookup<GlobalDictionary>(dictionary, unique_name, if_found, 1783
1752 &var_entry, if_not_found); 1784 NameDictionaryLookup<GlobalDictionary>(
1753 } 1785 dictionary, unique_name, if_found_global, var_name_index, if_not_found);
1754 } 1786 }
1755 1787 }
1788
1789 void CodeStubAssembler::TryHasOwnProperty(compiler::Node* object,
1790 compiler::Node* map,
1791 compiler::Node* instance_type,
1792 compiler::Node* unique_name,
1793 Label* if_found, Label* if_not_found,
1794 Label* if_bailout) {
1795 Comment("TryHasOwnProperty");
1796 Variable var_meta_storage(this, MachineRepresentation::kTagged);
1797 Variable var_name_index(this, MachineRepresentation::kWord32);
1798
1799 TryLookupProperty(object, map, instance_type, unique_name, if_found, if_found,
1800 if_found, &var_meta_storage, &var_name_index, if_not_found,
1801 if_bailout);
1802 }
1803
1804 void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
1805 Node* descriptors,
1806 Node* name_index,
1807 Variable* var_details,
1808 Variable* var_value) {
1809 DCHECK_EQ(MachineRepresentation::kWord32, var_details->rep());
1810 DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep());
1811 Comment("[ LoadPropertyFromFastObject");
1812
1813 const int name_to_details_offset =
1814 (DescriptorArray::kDescriptorDetails - DescriptorArray::kDescriptorKey) *
1815 kPointerSize;
1816 const int name_to_value_offset =
1817 (DescriptorArray::kDescriptorValue - DescriptorArray::kDescriptorKey) *
1818 kPointerSize;
1819
1820 Node* details = SmiToWord32(
1821 LoadFixedArrayElement(descriptors, name_index, name_to_details_offset));
1822 var_details->Bind(details);
1823
1824 Node* location = BitFieldDecode<PropertyDetails::LocationField>(details);
1825
1826 Label if_in_field(this), if_in_descriptor(this), done(this);
1827 Branch(Word32Equal(location, Int32Constant(kField)), &if_in_field,
1828 &if_in_descriptor);
1829 Bind(&if_in_field);
1830 {
1831 Node* field_index =
1832 BitFieldDecode<PropertyDetails::FieldIndexField>(details);
1833 Node* representation =
1834 BitFieldDecode<PropertyDetails::RepresentationField>(details);
1835
1836 Node* inobject_properties = LoadMapInobjectProperties(map);
1837
1838 Label if_inobject(this), if_backing_store(this);
1839 Variable var_double_value(this, MachineRepresentation::kFloat64);
1840 Label rebox_double(this, &var_double_value);
1841 BranchIfInt32LessThan(field_index, inobject_properties, &if_inobject,
1842 &if_backing_store);
1843 Bind(&if_inobject);
1844 {
1845 Comment("if_inobject");
1846 Node* field_offset = ChangeInt32ToIntPtr(
1847 Int32Mul(Int32Sub(LoadMapInstanceSize(map),
1848 Int32Sub(inobject_properties, field_index)),
1849 Int32Constant(kPointerSize)));
1850
1851 Label if_double(this), if_tagged(this);
1852 BranchIfWord32NotEqual(representation,
1853 Int32Constant(Representation::kDouble), &if_tagged,
1854 &if_double);
1855 Bind(&if_tagged);
1856 {
1857 var_value->Bind(LoadObjectField(object, field_offset));
1858 Goto(&done);
1859 }
1860 Bind(&if_double);
1861 {
1862 if (FLAG_unbox_double_fields) {
1863 var_double_value.Bind(
1864 LoadObjectField(object, field_offset, MachineType::Float64()));
1865 } else {
1866 Node* mutable_heap_number = LoadObjectField(object, field_offset);
1867 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number));
1868 }
1869 Goto(&rebox_double);
1870 }
1871 }
1872 Bind(&if_backing_store);
1873 {
1874 Comment("if_backing_store");
1875 Node* properties = LoadProperties(object);
1876 field_index = Int32Sub(field_index, inobject_properties);
1877 Node* value = LoadFixedArrayElement(properties, field_index);
1878
1879 Label if_double(this), if_tagged(this);
1880 BranchIfWord32NotEqual(representation,
1881 Int32Constant(Representation::kDouble), &if_tagged,
1882 &if_double);
1883 Bind(&if_tagged);
1884 {
1885 var_value->Bind(value);
1886 Goto(&done);
1887 }
1888 Bind(&if_double);
1889 {
1890 var_double_value.Bind(LoadHeapNumberValue(value));
1891 Goto(&rebox_double);
1892 }
1893 }
1894 Bind(&rebox_double);
1895 {
1896 Comment("rebox_double");
1897 Node* heap_number = AllocateHeapNumber();
1898 StoreHeapNumberValue(heap_number, var_double_value.value());
1899 var_value->Bind(heap_number);
1900 Goto(&done);
1901 }
1902 }
1903 Bind(&if_in_descriptor);
1904 {
1905 Node* value =
1906 LoadFixedArrayElement(descriptors, name_index, name_to_value_offset);
1907 var_value->Bind(value);
1908 Goto(&done);
1909 }
1910 Bind(&done);
1911
1912 Comment("] LoadPropertyFromFastObject");
1913 }
1914
1915 void CodeStubAssembler::LoadPropertyFromNameDictionary(Node* dictionary,
1916 Node* name_index,
1917 Variable* var_details,
1918 Variable* var_value) {
1919 Comment("LoadPropertyFromNameDictionary");
1920
1921 const int name_to_details_offset =
1922 (NameDictionary::kEntryDetailsIndex - NameDictionary::kEntryKeyIndex) *
1923 kPointerSize;
1924 const int name_to_value_offset =
1925 (NameDictionary::kEntryValueIndex - NameDictionary::kEntryKeyIndex) *
1926 kPointerSize;
1927
1928 Node* details = SmiToWord32(
1929 LoadFixedArrayElement(dictionary, name_index, name_to_details_offset));
1930
1931 var_details->Bind(details);
1932 var_value->Bind(
1933 LoadFixedArrayElement(dictionary, name_index, name_to_value_offset));
1934
1935 Comment("] LoadPropertyFromNameDictionary");
1936 }
1937
1938 void CodeStubAssembler::LoadPropertyFromGlobalDictionary(Node* dictionary,
1939 Node* name_index,
1940 Variable* var_details,
1941 Variable* var_value,
1942 Label* if_deleted) {
1943 Comment("[ LoadPropertyFromGlobalDictionary");
1944
1945 const int name_to_value_offset =
1946 (GlobalDictionary::kEntryValueIndex - GlobalDictionary::kEntryKeyIndex) *
1947 kPointerSize;
1948
1949 Node* property_cell =
1950 LoadFixedArrayElement(dictionary, name_index, name_to_value_offset);
1951
1952 Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset);
1953 GotoIf(WordEqual(value, TheHoleConstant()), if_deleted);
Toon Verwaest 2016/06/23 12:34:54 This should already have been handled in TryLookup
Igor Sheludko 2016/06/27 09:32:17 Currently it's the caller responsibility to do a h
1954
1955 var_value->Bind(value);
1956
1957 Node* details =
1958 SmiToWord32(LoadObjectField(property_cell, PropertyCell::kDetailsOffset));
1959 var_details->Bind(details);
1960
1961 Comment("] LoadPropertyFromGlobalDictionary");
1962 }
1963
1964 void CodeStubAssembler::TryGetOwnProperty(
1965 Node* context, Node* receiver, Node* object, Node* map, Node* instance_type,
1966 Node* unique_name, Label* if_found_value, Variable* var_value,
1967 Label* if_not_found, Label* if_bailout) {
1968 DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep());
1969 Comment("TryGetOwnProperty");
1970
1971 Variable var_meta_storage(this, MachineRepresentation::kTagged);
1972 Variable var_entry(this, MachineRepresentation::kWord32);
1973
1974 Label if_found_fast(this), if_found_dict(this), if_found_global(this);
1975
1976 Variable var_details(this, MachineRepresentation::kWord32);
1977 Variable* vars[] = {var_value, &var_details};
1978 Label if_found(this, 2, vars);
1979
1980 TryLookupProperty(object, map, instance_type, unique_name, &if_found_fast,
1981 &if_found_dict, &if_found_global, &var_meta_storage,
1982 &var_entry, if_not_found, if_bailout);
1983 Bind(&if_found_fast);
1984 {
1985 Node* descriptors = var_meta_storage.value();
1986 Node* name_index = var_entry.value();
1987
1988 LoadPropertyFromFastObject(object, map, descriptors, name_index,
1989 &var_details, var_value);
1990 Goto(&if_found);
1991 }
1992 Bind(&if_found_dict);
1993 {
1994 Node* dictionary = var_meta_storage.value();
1995 Node* entry = var_entry.value();
1996 LoadPropertyFromNameDictionary(dictionary, entry, &var_details, var_value);
1997 Goto(&if_found);
1998 }
1999 Bind(&if_found_global);
2000 {
2001 Node* dictionary = var_meta_storage.value();
2002 Node* entry = var_entry.value();
2003
2004 LoadPropertyFromGlobalDictionary(dictionary, entry, &var_details, var_value,
2005 if_not_found);
2006 Goto(&if_found);
2007 }
2008 // Here we have details and value which could be an accessor.
2009 Bind(&if_found);
2010 {
2011 Node* details = var_details.value();
2012 Node* kind = BitFieldDecode<PropertyDetails::KindField>(details);
2013
2014 Label if_accessor(this);
2015 Branch(Word32Equal(kind, Int32Constant(kData)), if_found_value,
2016 &if_accessor);
2017 Bind(&if_accessor);
2018 {
2019 Node* accessor_pair = var_value->value();
2020 GotoIf(Word32Equal(LoadInstanceType(accessor_pair),
2021 Int32Constant(ACCESSOR_INFO_TYPE)),
2022 if_bailout);
2023 AssertInstanceType(accessor_pair, ACCESSOR_PAIR_TYPE);
2024 Node* getter =
2025 LoadObjectField(accessor_pair, AccessorPair::kGetterOffset);
2026 Node* getter_map = LoadMap(getter);
2027 Node* instance_type = LoadMapInstanceType(getter_map);
2028 // FunctionTemplateInfo getters are not supported yet.
2029 GotoIf(Word32Equal(instance_type,
2030 Int32Constant(FUNCTION_TEMPLATE_INFO_TYPE)),
2031 if_bailout);
2032
2033 // Return undefined if the {getter} is not callable.
2034 var_value->Bind(UndefinedConstant());
2035 GotoIf(Word32Equal(Word32And(LoadMapBitField(getter_map),
2036 Int32Constant(1 << Map::kIsCallable)),
2037 Int32Constant(0)),
2038 if_found_value);
2039
2040 // Call the accessor.
2041 Callable callable = CodeFactory::Call(isolate());
2042 Node* result = CallJS(callable, context, getter, receiver);
2043 var_value->Bind(result);
2044 Goto(if_found_value);
2045 }
2046 }
2047 }
2048
1756 void CodeStubAssembler::TryLookupElement(Node* object, Node* map, 2049 void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
1757 Node* instance_type, Node* index, 2050 Node* instance_type, Node* index,
1758 Label* if_found, Label* if_not_found, 2051 Label* if_found, Label* if_not_found,
1759 Label* if_bailout) { 2052 Label* if_bailout) {
1760 // Handle special objects in runtime. 2053 // Handle special objects in runtime.
1761 GotoIf(Int32LessThanOrEqual(instance_type, 2054 GotoIf(Int32LessThanOrEqual(instance_type,
1762 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)), 2055 Int32Constant(LAST_SPECIAL_RECEIVER_TYPE)),
1763 if_bailout); 2056 if_bailout);
1764 2057
1765 Node* bit_field2 = LoadMapBitField2(map); 2058 Node* bit_field2 = LoadMapBitField2(map);
(...skipping 589 matching lines...) Expand 10 before | Expand all | Expand 10 after
2355 } 2648 }
2356 Bind(&miss); 2649 Bind(&miss);
2357 { 2650 {
2358 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->name, p->slot, 2651 TailCallRuntime(Runtime::kLoadGlobalIC_Miss, p->context, p->name, p->slot,
2359 p->vector); 2652 p->vector);
2360 } 2653 }
2361 } 2654 }
2362 2655
2363 } // namespace internal 2656 } // namespace internal
2364 } // namespace v8 2657 } // 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