Chromium Code Reviews| 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 |