OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/code-stubs.h" | 7 #include "src/code-stubs.h" |
8 #include "src/field-index.h" | 8 #include "src/field-index.h" |
9 #include "src/hydrogen.h" | 9 #include "src/hydrogen.h" |
10 #include "src/lithium.h" | 10 #include "src/lithium.h" |
(...skipping 1636 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1647 | 1647 |
1648 ExternalReference cache_keys_ref = | 1648 ExternalReference cache_keys_ref = |
1649 ExternalReference::keyed_lookup_cache_keys(isolate()); | 1649 ExternalReference::keyed_lookup_cache_keys(isolate()); |
1650 HValue* cache_keys = Add<HConstant>(cache_keys_ref); | 1650 HValue* cache_keys = Add<HConstant>(cache_keys_ref); |
1651 | 1651 |
1652 HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), | 1652 HValue* map = Add<HLoadNamedField>(receiver, static_cast<HValue*>(NULL), |
1653 HObjectAccess::ForMap()); | 1653 HObjectAccess::ForMap()); |
1654 HValue* base_index = AddUncasted<HMul>(hash, Add<HConstant>(2)); | 1654 HValue* base_index = AddUncasted<HMul>(hash, Add<HConstant>(2)); |
1655 base_index->ClearFlag(HValue::kCanOverflow); | 1655 base_index->ClearFlag(HValue::kCanOverflow); |
1656 | 1656 |
1657 IfBuilder lookup_if(this); | 1657 HIfContinuation inline_or_runtime_continuation( |
1658 for (int probe = 0; probe < KeyedLookupCache::kEntriesPerBucket; | 1658 graph()->CreateBasicBlock(), graph()->CreateBasicBlock()); |
1659 ++probe) { | 1659 { |
1660 int probe_base = probe * KeyedLookupCache::kEntryLength; | 1660 IfBuilder lookup_ifs[KeyedLookupCache::kEntriesPerBucket]; |
1661 HValue* map_index = AddUncasted<HAdd>(base_index, | 1661 for (int probe = 0; probe < KeyedLookupCache::kEntriesPerBucket; |
1662 Add<HConstant>(probe_base + KeyedLookupCache::kMapIndex)); | 1662 ++probe) { |
1663 map_index->ClearFlag(HValue::kCanOverflow); | 1663 IfBuilder* lookup_if = &lookup_ifs[probe]; |
1664 HValue* key_index = AddUncasted<HAdd>(base_index, | 1664 lookup_if->Initialize(this); |
1665 Add<HConstant>(probe_base + KeyedLookupCache::kKeyIndex)); | 1665 int probe_base = probe * KeyedLookupCache::kEntryLength; |
1666 key_index->ClearFlag(HValue::kCanOverflow); | 1666 HValue* map_index = AddUncasted<HAdd>( |
1667 HValue* map_to_check = Add<HLoadKeyed>(cache_keys, | 1667 base_index, |
1668 map_index, | 1668 Add<HConstant>(probe_base + KeyedLookupCache::kMapIndex)); |
1669 static_cast<HValue*>(NULL), | 1669 map_index->ClearFlag(HValue::kCanOverflow); |
1670 FAST_ELEMENTS, | 1670 HValue* key_index = AddUncasted<HAdd>( |
1671 NEVER_RETURN_HOLE, 0); | 1671 base_index, |
1672 lookup_if.If<HCompareObjectEqAndBranch>(map_to_check, map); | 1672 Add<HConstant>(probe_base + KeyedLookupCache::kKeyIndex)); |
1673 lookup_if.And(); | 1673 key_index->ClearFlag(HValue::kCanOverflow); |
1674 HValue* key_to_check = Add<HLoadKeyed>(cache_keys, | 1674 HValue* map_to_check = |
1675 key_index, | 1675 Add<HLoadKeyed>(cache_keys, map_index, static_cast<HValue*>(NULL), |
1676 static_cast<HValue*>(NULL), | 1676 FAST_ELEMENTS, NEVER_RETURN_HOLE, 0); |
1677 FAST_ELEMENTS, | 1677 lookup_if->If<HCompareObjectEqAndBranch>(map_to_check, map); |
1678 NEVER_RETURN_HOLE, 0); | 1678 lookup_if->And(); |
1679 lookup_if.If<HCompareObjectEqAndBranch>(key_to_check, key); | 1679 HValue* key_to_check = |
1680 lookup_if.Then(); | 1680 Add<HLoadKeyed>(cache_keys, key_index, static_cast<HValue*>(NULL), |
1681 { | 1681 FAST_ELEMENTS, NEVER_RETURN_HOLE, 0); |
1682 ExternalReference cache_field_offsets_ref = | 1682 lookup_if->If<HCompareObjectEqAndBranch>(key_to_check, key); |
1683 ExternalReference::keyed_lookup_cache_field_offsets(isolate()); | 1683 lookup_if->Then(); |
1684 HValue* cache_field_offsets = Add<HConstant>(cache_field_offsets_ref); | 1684 { |
1685 HValue* index = AddUncasted<HAdd>(hash, | 1685 ExternalReference cache_field_offsets_ref = |
1686 Add<HConstant>(probe)); | 1686 ExternalReference::keyed_lookup_cache_field_offsets(isolate()); |
1687 index->ClearFlag(HValue::kCanOverflow); | 1687 HValue* cache_field_offsets = |
1688 HValue* property_index = Add<HLoadKeyed>(cache_field_offsets, | 1688 Add<HConstant>(cache_field_offsets_ref); |
1689 index, | 1689 HValue* index = AddUncasted<HAdd>(hash, Add<HConstant>(probe)); |
1690 static_cast<HValue*>(NULL), | 1690 index->ClearFlag(HValue::kCanOverflow); |
1691 EXTERNAL_INT32_ELEMENTS, | 1691 HValue* property_index = Add<HLoadKeyed>( |
1692 NEVER_RETURN_HOLE, 0); | 1692 cache_field_offsets, index, static_cast<HValue*>(NULL), |
1693 Push(property_index); | 1693 EXTERNAL_INT32_ELEMENTS, NEVER_RETURN_HOLE, 0); |
| 1694 Push(property_index); |
| 1695 } |
| 1696 lookup_if->Else(); |
1694 } | 1697 } |
1695 lookup_if.Else(); | 1698 for (int i = 0; i < KeyedLookupCache::kEntriesPerBucket; ++i) { |
| 1699 lookup_ifs[i].JoinContinuation(&inline_or_runtime_continuation); |
| 1700 } |
1696 } | 1701 } |
1697 Add<HDeoptimize>("KeyedLoad fall-back", Deoptimizer::EAGER); | 1702 |
1698 Push(graph()->GetConstant0()); | 1703 IfBuilder inline_or_runtime(this, &inline_or_runtime_continuation); |
1699 lookup_if.End(); | 1704 inline_or_runtime.Then(); |
1700 Push(Add<HLoadFieldByIndex>(receiver, Pop())); | 1705 { |
| 1706 // Found a cached index, load property inline. |
| 1707 Push(Add<HLoadFieldByIndex>(receiver, Pop())); |
| 1708 } |
| 1709 inline_or_runtime.Else(); |
| 1710 { |
| 1711 // KeyedLookupCache miss; call runtime. |
| 1712 Add<HPushArguments>(receiver, key); |
| 1713 Push(Add<HCallRuntime>( |
| 1714 isolate()->factory()->empty_string(), |
| 1715 Runtime::FunctionForId(Runtime::kKeyedGetProperty), 2)); |
| 1716 } |
| 1717 inline_or_runtime.End(); |
1701 } | 1718 } |
1702 if_dict_properties.End(); | 1719 if_dict_properties.End(); |
1703 } | 1720 } |
1704 index_name_split.End(); | 1721 index_name_split.End(); |
1705 | 1722 |
1706 return Pop(); | 1723 return Pop(); |
1707 } | 1724 } |
1708 | 1725 |
1709 | 1726 |
1710 Handle<Code> KeyedLoadGenericElementStub::GenerateCode() { | 1727 Handle<Code> KeyedLoadGenericElementStub::GenerateCode() { |
1711 return DoGenerateCode(this); | 1728 return DoGenerateCode(this); |
1712 } | 1729 } |
1713 | 1730 |
1714 | 1731 |
1715 } } // namespace v8::internal | 1732 } } // namespace v8::internal |
OLD | NEW |