| 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 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 if (index >= 0) { | 309 if (index >= 0) { |
| 310 ic_holder_map->RemoveFromCodeCache(*name, *target(), index); | 310 ic_holder_map->RemoveFromCodeCache(*name, *target(), index); |
| 311 } | 311 } |
| 312 } | 312 } |
| 313 | 313 |
| 314 if (receiver->IsGlobalObject()) { | 314 if (receiver->IsGlobalObject()) { |
| 315 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); | 315 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); |
| 316 LookupIterator it(global, name, LookupIterator::OWN_SKIP_INTERCEPTOR); | 316 LookupIterator it(global, name, LookupIterator::OWN_SKIP_INTERCEPTOR); |
| 317 if (it.state() == LookupIterator::ACCESS_CHECK) return false; | 317 if (it.state() == LookupIterator::ACCESS_CHECK) return false; |
| 318 if (!it.IsFound()) return false; | 318 if (!it.IsFound()) return false; |
| 319 Handle<PropertyCell> cell = it.GetPropertyCell(); | 319 return it.property_details().cell_type() == PropertyCellType::kConstant; |
| 320 return cell->type()->IsConstant(); | |
| 321 } | 320 } |
| 322 | 321 |
| 323 return true; | 322 return true; |
| 324 } | 323 } |
| 325 | 324 |
| 326 | 325 |
| 327 bool IC::IsNameCompatibleWithPrototypeFailure(Handle<Object> name) { | 326 bool IC::IsNameCompatibleWithPrototypeFailure(Handle<Object> name) { |
| 328 if (target()->is_keyed_stub()) { | 327 if (target()->is_keyed_stub()) { |
| 329 // Determine whether the failure is due to a name failure. | 328 // Determine whether the failure is due to a name failure. |
| 330 if (!name->IsName()) return false; | 329 if (!name->IsName()) return false; |
| (...skipping 1379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1710 } | 1709 } |
| 1711 Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); | 1710 Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); |
| 1712 | 1711 |
| 1713 PatchCache(lookup->name(), code); | 1712 PatchCache(lookup->name(), code); |
| 1714 TRACE_IC("StoreIC", lookup->name()); | 1713 TRACE_IC("StoreIC", lookup->name()); |
| 1715 } | 1714 } |
| 1716 | 1715 |
| 1717 | 1716 |
| 1718 static Handle<Code> PropertyCellStoreHandler( | 1717 static Handle<Code> PropertyCellStoreHandler( |
| 1719 Isolate* isolate, Handle<JSObject> receiver, Handle<GlobalObject> holder, | 1718 Isolate* isolate, Handle<JSObject> receiver, Handle<GlobalObject> holder, |
| 1720 Handle<Name> name, Handle<PropertyCell> cell, Handle<Object> value) { | 1719 Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) { |
| 1721 auto union_type = PropertyCell::UpdatedType(cell, value); | 1720 StoreGlobalStub stub(isolate, type == PropertyCellType::kConstant, |
| 1722 StoreGlobalStub stub(isolate, union_type->IsConstant(), | |
| 1723 receiver->IsJSGlobalProxy()); | 1721 receiver->IsJSGlobalProxy()); |
| 1724 auto code = stub.GetCodeCopyFromTemplate(holder, cell); | 1722 auto code = stub.GetCodeCopyFromTemplate(holder, cell); |
| 1725 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. | 1723 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. |
| 1726 HeapObject::UpdateMapCodeCache(receiver, name, code); | 1724 HeapObject::UpdateMapCodeCache(receiver, name, code); |
| 1727 return code; | 1725 return code; |
| 1728 } | 1726 } |
| 1729 | 1727 |
| 1730 | 1728 |
| 1731 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, | 1729 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, |
| 1732 Handle<Object> value, | 1730 Handle<Object> value, |
| 1733 CacheHolderFlag cache_holder) { | 1731 CacheHolderFlag cache_holder) { |
| 1734 DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); | 1732 DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); |
| 1735 | 1733 |
| 1736 // This is currently guaranteed by checks in StoreIC::Store. | 1734 // This is currently guaranteed by checks in StoreIC::Store. |
| 1737 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); | 1735 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); |
| 1738 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); | 1736 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); |
| 1739 DCHECK(!receiver->IsAccessCheckNeeded()); | 1737 DCHECK(!receiver->IsAccessCheckNeeded()); |
| 1740 | 1738 |
| 1741 switch (lookup->state()) { | 1739 switch (lookup->state()) { |
| 1742 case LookupIterator::TRANSITION: { | 1740 case LookupIterator::TRANSITION: { |
| 1743 auto store_target = lookup->GetStoreTarget(); | 1741 auto store_target = lookup->GetStoreTarget(); |
| 1744 if (store_target->IsGlobalObject()) { | 1742 if (store_target->IsGlobalObject()) { |
| 1745 auto cell = lookup->GetTransitionPropertyCell(); | 1743 // TODO(dcarney): this currently just deopts. Use the transition cell. |
| 1746 return PropertyCellStoreHandler( | 1744 auto cell = isolate()->factory()->NewPropertyCell(); |
| 1745 cell->set_value(*value); |
| 1746 auto code = PropertyCellStoreHandler( |
| 1747 isolate(), store_target, Handle<GlobalObject>::cast(store_target), | 1747 isolate(), store_target, Handle<GlobalObject>::cast(store_target), |
| 1748 lookup->name(), cell, value); | 1748 lookup->name(), cell, PropertyCellType::kConstant); |
| 1749 cell->set_value(isolate()->heap()->the_hole_value()); |
| 1750 return code; |
| 1749 } | 1751 } |
| 1750 Handle<Map> transition = lookup->transition_map(); | 1752 Handle<Map> transition = lookup->transition_map(); |
| 1751 // Currently not handled by CompileStoreTransition. | 1753 // Currently not handled by CompileStoreTransition. |
| 1752 if (!holder->HasFastProperties()) { | 1754 if (!holder->HasFastProperties()) { |
| 1753 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); | 1755 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); |
| 1754 break; | 1756 break; |
| 1755 } | 1757 } |
| 1756 | 1758 |
| 1757 DCHECK(lookup->IsCacheableTransition()); | 1759 DCHECK(lookup->IsCacheableTransition()); |
| 1758 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); | 1760 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1809 } | 1811 } |
| 1810 break; | 1812 break; |
| 1811 } | 1813 } |
| 1812 | 1814 |
| 1813 case LookupIterator::DATA: { | 1815 case LookupIterator::DATA: { |
| 1814 if (lookup->is_dictionary_holder()) { | 1816 if (lookup->is_dictionary_holder()) { |
| 1815 if (holder->IsGlobalObject()) { | 1817 if (holder->IsGlobalObject()) { |
| 1816 DCHECK(holder.is_identical_to(receiver) || | 1818 DCHECK(holder.is_identical_to(receiver) || |
| 1817 receiver->map()->prototype() == *holder); | 1819 receiver->map()->prototype() == *holder); |
| 1818 auto cell = lookup->GetPropertyCell(); | 1820 auto cell = lookup->GetPropertyCell(); |
| 1821 auto union_type = PropertyCell::UpdatedType( |
| 1822 cell, value, lookup->property_details()); |
| 1819 return PropertyCellStoreHandler(isolate(), receiver, | 1823 return PropertyCellStoreHandler(isolate(), receiver, |
| 1820 Handle<GlobalObject>::cast(holder), | 1824 Handle<GlobalObject>::cast(holder), |
| 1821 lookup->name(), cell, value); | 1825 lookup->name(), cell, union_type); |
| 1822 } | 1826 } |
| 1823 DCHECK(holder.is_identical_to(receiver)); | 1827 DCHECK(holder.is_identical_to(receiver)); |
| 1824 return isolate()->builtins()->StoreIC_Normal(); | 1828 return isolate()->builtins()->StoreIC_Normal(); |
| 1825 } | 1829 } |
| 1826 | 1830 |
| 1827 // -------------- Fields -------------- | 1831 // -------------- Fields -------------- |
| 1828 if (lookup->property_details().type() == DATA) { | 1832 if (lookup->property_details().type() == DATA) { |
| 1829 bool use_stub = true; | 1833 bool use_stub = true; |
| 1830 if (lookup->representation().IsHeapObject()) { | 1834 if (lookup->representation().IsHeapObject()) { |
| 1831 // Only use a generic stub if no types need to be tracked. | 1835 // Only use a generic stub if no types need to be tracked. |
| (...skipping 1232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3064 static const Address IC_utilities[] = { | 3068 static const Address IC_utilities[] = { |
| 3065 #define ADDR(name) FUNCTION_ADDR(name), | 3069 #define ADDR(name) FUNCTION_ADDR(name), |
| 3066 IC_UTIL_LIST(ADDR) NULL | 3070 IC_UTIL_LIST(ADDR) NULL |
| 3067 #undef ADDR | 3071 #undef ADDR |
| 3068 }; | 3072 }; |
| 3069 | 3073 |
| 3070 | 3074 |
| 3071 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } | 3075 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } |
| 3072 } | 3076 } |
| 3073 } // namespace v8::internal | 3077 } // namespace v8::internal |
| OLD | NEW |