| 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 1225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1236 break; | 1236 break; |
| 1237 } | 1237 } |
| 1238 | 1238 |
| 1239 case LookupIterator::DATA: { | 1239 case LookupIterator::DATA: { |
| 1240 if (lookup->is_dictionary_holder()) { | 1240 if (lookup->is_dictionary_holder()) { |
| 1241 if (kind() != Code::LOAD_IC) break; | 1241 if (kind() != Code::LOAD_IC) break; |
| 1242 if (holder->IsGlobalObject()) { | 1242 if (holder->IsGlobalObject()) { |
| 1243 NamedLoadHandlerCompiler compiler(isolate(), map, holder, | 1243 NamedLoadHandlerCompiler compiler(isolate(), map, holder, |
| 1244 cache_holder); | 1244 cache_holder); |
| 1245 Handle<PropertyCell> cell = lookup->GetPropertyCell(); | 1245 Handle<PropertyCell> cell = lookup->GetPropertyCell(); |
| 1246 Handle<Code> code = compiler.CompileLoadGlobal( | 1246 Handle<Code> code = compiler.CompileLoadGlobal(cell, lookup->name()); |
| 1247 cell, lookup->name(), lookup->IsConfigurable()); | |
| 1248 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. | 1247 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. |
| 1249 CacheHolderFlag flag; | 1248 CacheHolderFlag flag; |
| 1250 Handle<Map> stub_holder_map = | 1249 Handle<Map> stub_holder_map = |
| 1251 GetHandlerCacheHolder(map, receiver_is_holder, isolate(), &flag); | 1250 GetHandlerCacheHolder(map, receiver_is_holder, isolate(), &flag); |
| 1252 Map::UpdateCodeCache(stub_holder_map, lookup->name(), code); | 1251 Map::UpdateCodeCache(stub_holder_map, lookup->name(), code); |
| 1253 return code; | 1252 return code; |
| 1254 } | 1253 } |
| 1255 // There is only one shared stub for loading normalized | 1254 // There is only one shared stub for loading normalized |
| 1256 // properties. It does not traverse the prototype chain, so the | 1255 // properties. It does not traverse the prototype chain, so the |
| 1257 // property must be found in the object for the stub to be | 1256 // property must be found in the object for the stub to be |
| (...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1660 if (!use_ic) { | 1659 if (!use_ic) { |
| 1661 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); | 1660 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); |
| 1662 } | 1661 } |
| 1663 Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); | 1662 Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); |
| 1664 | 1663 |
| 1665 PatchCache(lookup->name(), code); | 1664 PatchCache(lookup->name(), code); |
| 1666 TRACE_IC("StoreIC", lookup->name()); | 1665 TRACE_IC("StoreIC", lookup->name()); |
| 1667 } | 1666 } |
| 1668 | 1667 |
| 1669 | 1668 |
| 1670 static Handle<Code> PropertyCellStoreHandler( | 1669 static Handle<Code> PropertyCellStoreHandler(Isolate* isolate, |
| 1671 Isolate* isolate, Handle<JSObject> receiver, Handle<GlobalObject> holder, | 1670 Handle<JSObject> receiver, |
| 1672 Handle<Name> name, Handle<PropertyCell> cell, Handle<Object> value) { | 1671 Handle<Name> name, |
| 1672 Handle<PropertyCell> cell, |
| 1673 Handle<Object> value) { |
| 1673 auto union_type = PropertyCell::UpdatedType(cell, value); | 1674 auto union_type = PropertyCell::UpdatedType(cell, value); |
| 1674 StoreGlobalStub stub(isolate, union_type->IsConstant(), | 1675 StoreGlobalStub stub(isolate, union_type->IsConstant(), |
| 1675 receiver->IsJSGlobalProxy()); | 1676 receiver->IsJSGlobalProxy()); |
| 1676 auto code = stub.GetCodeCopyFromTemplate(holder, cell); | 1677 auto code = stub.GetCodeCopyFromTemplate(cell); |
| 1677 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. | 1678 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. |
| 1678 HeapObject::UpdateMapCodeCache(receiver, name, code); | 1679 HeapObject::UpdateMapCodeCache(receiver, name, code); |
| 1679 return code; | 1680 return code; |
| 1680 } | 1681 } |
| 1681 | 1682 |
| 1682 | 1683 |
| 1683 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, | 1684 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, |
| 1684 Handle<Object> value, | 1685 Handle<Object> value, |
| 1685 CacheHolderFlag cache_holder) { | 1686 CacheHolderFlag cache_holder) { |
| 1686 DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); | 1687 DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); |
| 1687 | 1688 |
| 1688 // This is currently guaranteed by checks in StoreIC::Store. | 1689 // This is currently guaranteed by checks in StoreIC::Store. |
| 1689 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); | 1690 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); |
| 1690 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); | 1691 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); |
| 1691 DCHECK(!receiver->IsAccessCheckNeeded()); | 1692 DCHECK(!receiver->IsAccessCheckNeeded()); |
| 1692 | 1693 |
| 1693 switch (lookup->state()) { | 1694 switch (lookup->state()) { |
| 1694 case LookupIterator::TRANSITION: { | 1695 case LookupIterator::TRANSITION: { |
| 1695 auto store_target = lookup->GetStoreTarget(); | 1696 auto store_target = lookup->GetStoreTarget(); |
| 1696 if (store_target->IsGlobalObject()) { | 1697 if (store_target->IsGlobalObject()) { |
| 1697 auto cell = lookup->GetTransitionPropertyCell(); | 1698 auto cell = lookup->GetTransitionPropertyCell(); |
| 1698 return PropertyCellStoreHandler( | 1699 return PropertyCellStoreHandler(isolate(), receiver, lookup->name(), |
| 1699 isolate(), store_target, Handle<GlobalObject>::cast(store_target), | 1700 cell, value); |
| 1700 lookup->name(), cell, value); | |
| 1701 } | 1701 } |
| 1702 Handle<Map> transition = lookup->transition_map(); | 1702 Handle<Map> transition = lookup->transition_map(); |
| 1703 // Currently not handled by CompileStoreTransition. | 1703 // Currently not handled by CompileStoreTransition. |
| 1704 if (!holder->HasFastProperties()) { | 1704 if (!holder->HasFastProperties()) { |
| 1705 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); | 1705 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); |
| 1706 break; | 1706 break; |
| 1707 } | 1707 } |
| 1708 | 1708 |
| 1709 DCHECK(lookup->IsCacheableTransition()); | 1709 DCHECK(lookup->IsCacheableTransition()); |
| 1710 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); | 1710 NamedStoreHandlerCompiler compiler(isolate(), receiver_map(), holder); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1761 } | 1761 } |
| 1762 break; | 1762 break; |
| 1763 } | 1763 } |
| 1764 | 1764 |
| 1765 case LookupIterator::DATA: { | 1765 case LookupIterator::DATA: { |
| 1766 if (lookup->is_dictionary_holder()) { | 1766 if (lookup->is_dictionary_holder()) { |
| 1767 if (holder->IsGlobalObject()) { | 1767 if (holder->IsGlobalObject()) { |
| 1768 DCHECK(holder.is_identical_to(receiver) || | 1768 DCHECK(holder.is_identical_to(receiver) || |
| 1769 receiver->map()->prototype() == *holder); | 1769 receiver->map()->prototype() == *holder); |
| 1770 auto cell = lookup->GetPropertyCell(); | 1770 auto cell = lookup->GetPropertyCell(); |
| 1771 return PropertyCellStoreHandler(isolate(), receiver, | 1771 return PropertyCellStoreHandler(isolate(), receiver, lookup->name(), |
| 1772 Handle<GlobalObject>::cast(holder), | 1772 cell, value); |
| 1773 lookup->name(), cell, value); | |
| 1774 } | 1773 } |
| 1775 DCHECK(holder.is_identical_to(receiver)); | 1774 DCHECK(holder.is_identical_to(receiver)); |
| 1776 return isolate()->builtins()->StoreIC_Normal(); | 1775 return isolate()->builtins()->StoreIC_Normal(); |
| 1777 } | 1776 } |
| 1778 | 1777 |
| 1779 // -------------- Fields -------------- | 1778 // -------------- Fields -------------- |
| 1780 if (lookup->property_details().type() == DATA) { | 1779 if (lookup->property_details().type() == DATA) { |
| 1781 bool use_stub = true; | 1780 bool use_stub = true; |
| 1782 if (lookup->representation().IsHeapObject()) { | 1781 if (lookup->representation().IsHeapObject()) { |
| 1783 // Only use a generic stub if no types need to be tracked. | 1782 // Only use a generic stub if no types need to be tracked. |
| (...skipping 1229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3013 static const Address IC_utilities[] = { | 3012 static const Address IC_utilities[] = { |
| 3014 #define ADDR(name) FUNCTION_ADDR(name), | 3013 #define ADDR(name) FUNCTION_ADDR(name), |
| 3015 IC_UTIL_LIST(ADDR) NULL | 3014 IC_UTIL_LIST(ADDR) NULL |
| 3016 #undef ADDR | 3015 #undef ADDR |
| 3017 }; | 3016 }; |
| 3018 | 3017 |
| 3019 | 3018 |
| 3020 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } | 3019 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } |
| 3021 } | 3020 } |
| 3022 } // namespace v8::internal | 3021 } // namespace v8::internal |
| OLD | NEW |