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 |