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 graph()->CreateBasicBlock(), graph()->CreateBasicBlock()); | |
1659 IfBuilder* lookup_ifs[KeyedLookupCache::kEntriesPerBucket]; | |
1658 for (int probe = 0; probe < KeyedLookupCache::kEntriesPerBucket; | 1660 for (int probe = 0; probe < KeyedLookupCache::kEntriesPerBucket; |
1659 ++probe) { | 1661 ++probe) { |
1662 IfBuilder* lookup_if = new IfBuilder(this); | |
danno
2014/07/07 07:59:06
Shouldn't you just Zone allocate this?
void* buff
Jakob Kummerow
2014/07/07 11:52:10
I'm not sure. In what way would that be better? We
danno
2014/07/07 12:08:45
Well, since we generally avoid allocating from the
| |
1663 lookup_ifs[probe] = lookup_if; | |
1660 int probe_base = probe * KeyedLookupCache::kEntryLength; | 1664 int probe_base = probe * KeyedLookupCache::kEntryLength; |
1661 HValue* map_index = AddUncasted<HAdd>(base_index, | 1665 HValue* map_index = AddUncasted<HAdd>(base_index, |
1662 Add<HConstant>(probe_base + KeyedLookupCache::kMapIndex)); | 1666 Add<HConstant>(probe_base + KeyedLookupCache::kMapIndex)); |
1663 map_index->ClearFlag(HValue::kCanOverflow); | 1667 map_index->ClearFlag(HValue::kCanOverflow); |
1664 HValue* key_index = AddUncasted<HAdd>(base_index, | 1668 HValue* key_index = AddUncasted<HAdd>(base_index, |
1665 Add<HConstant>(probe_base + KeyedLookupCache::kKeyIndex)); | 1669 Add<HConstant>(probe_base + KeyedLookupCache::kKeyIndex)); |
1666 key_index->ClearFlag(HValue::kCanOverflow); | 1670 key_index->ClearFlag(HValue::kCanOverflow); |
1667 HValue* map_to_check = Add<HLoadKeyed>(cache_keys, | 1671 HValue* map_to_check = Add<HLoadKeyed>(cache_keys, |
1668 map_index, | 1672 map_index, |
1669 static_cast<HValue*>(NULL), | 1673 static_cast<HValue*>(NULL), |
1670 FAST_ELEMENTS, | 1674 FAST_ELEMENTS, |
1671 NEVER_RETURN_HOLE, 0); | 1675 NEVER_RETURN_HOLE, 0); |
1672 lookup_if.If<HCompareObjectEqAndBranch>(map_to_check, map); | 1676 lookup_if->If<HCompareObjectEqAndBranch>(map_to_check, map); |
1673 lookup_if.And(); | 1677 lookup_if->And(); |
1674 HValue* key_to_check = Add<HLoadKeyed>(cache_keys, | 1678 HValue* key_to_check = Add<HLoadKeyed>(cache_keys, |
1675 key_index, | 1679 key_index, |
1676 static_cast<HValue*>(NULL), | 1680 static_cast<HValue*>(NULL), |
1677 FAST_ELEMENTS, | 1681 FAST_ELEMENTS, |
1678 NEVER_RETURN_HOLE, 0); | 1682 NEVER_RETURN_HOLE, 0); |
1679 lookup_if.If<HCompareObjectEqAndBranch>(key_to_check, key); | 1683 lookup_if->If<HCompareObjectEqAndBranch>(key_to_check, key); |
1680 lookup_if.Then(); | 1684 lookup_if->Then(); |
1681 { | 1685 { |
1682 ExternalReference cache_field_offsets_ref = | 1686 ExternalReference cache_field_offsets_ref = |
1683 ExternalReference::keyed_lookup_cache_field_offsets(isolate()); | 1687 ExternalReference::keyed_lookup_cache_field_offsets(isolate()); |
1684 HValue* cache_field_offsets = Add<HConstant>(cache_field_offsets_ref); | 1688 HValue* cache_field_offsets = Add<HConstant>(cache_field_offsets_ref); |
1685 HValue* index = AddUncasted<HAdd>(hash, | 1689 HValue* index = AddUncasted<HAdd>(hash, |
1686 Add<HConstant>(probe)); | 1690 Add<HConstant>(probe)); |
1687 index->ClearFlag(HValue::kCanOverflow); | 1691 index->ClearFlag(HValue::kCanOverflow); |
1688 HValue* property_index = Add<HLoadKeyed>(cache_field_offsets, | 1692 HValue* property_index = Add<HLoadKeyed>(cache_field_offsets, |
1689 index, | 1693 index, |
1690 static_cast<HValue*>(NULL), | 1694 static_cast<HValue*>(NULL), |
1691 EXTERNAL_INT32_ELEMENTS, | 1695 EXTERNAL_INT32_ELEMENTS, |
1692 NEVER_RETURN_HOLE, 0); | 1696 NEVER_RETURN_HOLE, 0); |
1693 Push(property_index); | 1697 Push(property_index); |
1694 } | 1698 } |
1695 lookup_if.Else(); | 1699 lookup_if->Else(); |
1696 } | 1700 } |
1697 Add<HDeoptimize>("KeyedLoad fall-back", Deoptimizer::EAGER); | 1701 for (int i = 0; i < KeyedLookupCache::kEntriesPerBucket; ++i) { |
1698 Push(graph()->GetConstant0()); | 1702 lookup_ifs[i]->JoinContinuation(&inline_or_runtime_continuation); |
1699 lookup_if.End(); | 1703 delete lookup_ifs[i]; |
1700 Push(Add<HLoadFieldByIndex>(receiver, Pop())); | 1704 } |
1705 | |
1706 IfBuilder inline_or_runtime(this, &inline_or_runtime_continuation); | |
1707 inline_or_runtime.Then(); | |
1708 { | |
1709 // Found a cached index, load property inline. | |
1710 Push(Add<HLoadFieldByIndex>(receiver, Pop())); | |
1711 } | |
1712 inline_or_runtime.Else(); | |
1713 { | |
1714 // KeyedLookupCache miss; call runtime. | |
1715 Add<HPushArguments>(receiver, key); | |
1716 Push(Add<HCallRuntime>( | |
1717 isolate()->factory()->empty_string(), | |
1718 Runtime::FunctionForId(Runtime::kKeyedGetProperty), 2)); | |
1719 } | |
1720 inline_or_runtime.End(); | |
1701 } | 1721 } |
1702 if_dict_properties.End(); | 1722 if_dict_properties.End(); |
1703 } | 1723 } |
1704 index_name_split.End(); | 1724 index_name_split.End(); |
1705 | 1725 |
1706 return Pop(); | 1726 return Pop(); |
1707 } | 1727 } |
1708 | 1728 |
1709 | 1729 |
1710 Handle<Code> KeyedLoadGenericElementStub::GenerateCode() { | 1730 Handle<Code> KeyedLoadGenericElementStub::GenerateCode() { |
1711 return DoGenerateCode(this); | 1731 return DoGenerateCode(this); |
1712 } | 1732 } |
1713 | 1733 |
1714 | 1734 |
1715 } } // namespace v8::internal | 1735 } } // namespace v8::internal |
OLD | NEW |