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/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 1658 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1669 if (!use_ic) { | 1669 if (!use_ic) { |
1670 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); | 1670 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); |
1671 } | 1671 } |
1672 Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); | 1672 Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); |
1673 | 1673 |
1674 PatchCache(lookup->name(), code); | 1674 PatchCache(lookup->name(), code); |
1675 TRACE_IC("StoreIC", lookup->name()); | 1675 TRACE_IC("StoreIC", lookup->name()); |
1676 } | 1676 } |
1677 | 1677 |
1678 | 1678 |
| 1679 static Handle<Code> PropertyCellStoreHandler( |
| 1680 Isolate* isolate, Handle<JSObject> receiver, Handle<GlobalObject> holder, |
| 1681 Handle<Name> name, Handle<PropertyCell> cell, Handle<Object> value) { |
| 1682 auto union_type = PropertyCell::UpdatedType(cell, value); |
| 1683 StoreGlobalStub stub(isolate, union_type->IsConstant(), |
| 1684 receiver->IsJSGlobalProxy()); |
| 1685 auto code = stub.GetCodeCopyFromTemplate(holder, cell); |
| 1686 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. |
| 1687 HeapObject::UpdateMapCodeCache(receiver, name, code); |
| 1688 return code; |
| 1689 } |
| 1690 |
| 1691 |
1679 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, | 1692 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, |
1680 Handle<Object> value, | 1693 Handle<Object> value, |
1681 CacheHolderFlag cache_holder) { | 1694 CacheHolderFlag cache_holder) { |
1682 DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); | 1695 DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); |
1683 | 1696 |
1684 // This is currently guaranteed by checks in StoreIC::Store. | 1697 // This is currently guaranteed by checks in StoreIC::Store. |
1685 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); | 1698 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); |
1686 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); | 1699 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); |
1687 DCHECK(!receiver->IsAccessCheckNeeded()); | 1700 DCHECK(!receiver->IsAccessCheckNeeded()); |
1688 | 1701 |
1689 switch (lookup->state()) { | 1702 switch (lookup->state()) { |
1690 case LookupIterator::TRANSITION: { | 1703 case LookupIterator::TRANSITION: { |
| 1704 auto store_target = lookup->GetStoreTarget(); |
| 1705 if (store_target->IsGlobalObject()) { |
| 1706 auto cell = lookup->GetTransitionPropertyCell(); |
| 1707 return PropertyCellStoreHandler( |
| 1708 isolate(), store_target, Handle<GlobalObject>::cast(store_target), |
| 1709 lookup->name(), cell, value); |
| 1710 } |
1691 Handle<Map> transition = lookup->transition_map(); | 1711 Handle<Map> transition = lookup->transition_map(); |
1692 // Currently not handled by CompileStoreTransition. | 1712 // Currently not handled by CompileStoreTransition. |
1693 if (!holder->HasFastProperties()) { | 1713 if (!holder->HasFastProperties()) { |
1694 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); | 1714 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); |
1695 break; | 1715 break; |
1696 } | 1716 } |
1697 | 1717 |
1698 DCHECK(lookup->IsCacheableTransition()); | 1718 DCHECK(lookup->IsCacheableTransition()); |
1699 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); | 1719 NamedStoreHandlerCompiler compiler(isolate(), receiver_type(), holder); |
1700 return compiler.CompileStoreTransition(transition, lookup->name()); | 1720 return compiler.CompileStoreTransition(transition, lookup->name()); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1747 return compiler.CompileStoreViaSetter(receiver, lookup->name(), | 1767 return compiler.CompileStoreViaSetter(receiver, lookup->name(), |
1748 lookup->GetAccessorIndex(), | 1768 lookup->GetAccessorIndex(), |
1749 expected_arguments); | 1769 expected_arguments); |
1750 } | 1770 } |
1751 break; | 1771 break; |
1752 } | 1772 } |
1753 | 1773 |
1754 case LookupIterator::DATA: { | 1774 case LookupIterator::DATA: { |
1755 if (lookup->is_dictionary_holder()) { | 1775 if (lookup->is_dictionary_holder()) { |
1756 if (holder->IsGlobalObject()) { | 1776 if (holder->IsGlobalObject()) { |
1757 Handle<PropertyCell> cell = lookup->GetPropertyCell(); | |
1758 Handle<HeapType> union_type = PropertyCell::UpdatedType(cell, value); | |
1759 DCHECK(holder.is_identical_to(receiver) || | 1777 DCHECK(holder.is_identical_to(receiver) || |
1760 receiver->map()->prototype() == *holder); | 1778 receiver->map()->prototype() == *holder); |
1761 StoreGlobalStub stub(isolate(), union_type->IsConstant(), | 1779 auto cell = lookup->GetPropertyCell(); |
1762 receiver->IsJSGlobalProxy()); | 1780 return PropertyCellStoreHandler(isolate(), receiver, |
1763 Handle<Code> code = stub.GetCodeCopyFromTemplate( | 1781 Handle<GlobalObject>::cast(holder), |
1764 Handle<GlobalObject>::cast(holder), cell); | 1782 lookup->name(), cell, value); |
1765 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. | |
1766 HeapObject::UpdateMapCodeCache(receiver, lookup->name(), code); | |
1767 return code; | |
1768 } | 1783 } |
1769 DCHECK(holder.is_identical_to(receiver)); | 1784 DCHECK(holder.is_identical_to(receiver)); |
1770 return isolate()->builtins()->StoreIC_Normal(); | 1785 return isolate()->builtins()->StoreIC_Normal(); |
1771 } | 1786 } |
1772 | 1787 |
1773 // -------------- Fields -------------- | 1788 // -------------- Fields -------------- |
1774 if (lookup->property_details().type() == DATA) { | 1789 if (lookup->property_details().type() == DATA) { |
1775 bool use_stub = true; | 1790 bool use_stub = true; |
1776 if (lookup->representation().IsHeapObject()) { | 1791 if (lookup->representation().IsHeapObject()) { |
1777 // Only use a generic stub if no types need to be tracked. | 1792 // Only use a generic stub if no types need to be tracked. |
(...skipping 1219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2997 static const Address IC_utilities[] = { | 3012 static const Address IC_utilities[] = { |
2998 #define ADDR(name) FUNCTION_ADDR(name), | 3013 #define ADDR(name) FUNCTION_ADDR(name), |
2999 IC_UTIL_LIST(ADDR) NULL | 3014 IC_UTIL_LIST(ADDR) NULL |
3000 #undef ADDR | 3015 #undef ADDR |
3001 }; | 3016 }; |
3002 | 3017 |
3003 | 3018 |
3004 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } | 3019 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } |
3005 } | 3020 } |
3006 } // namespace v8::internal | 3021 } // namespace v8::internal |
OLD | NEW |