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/ic/ic.h" | 5 #include "src/ic/ic.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 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
283 DCHECK(flag != kCacheOnPrototype || !receiver->IsJSReceiver()); | 283 DCHECK(flag != kCacheOnPrototype || !receiver->IsJSReceiver()); |
284 DCHECK(flag != kCacheOnPrototypeReceiverIsDictionary); | 284 DCHECK(flag != kCacheOnPrototypeReceiverIsDictionary); |
285 | 285 |
286 if (state() == MONOMORPHIC) { | 286 if (state() == MONOMORPHIC) { |
287 int index = ic_holder_map->IndexInCodeCache(*name, *target()); | 287 int index = ic_holder_map->IndexInCodeCache(*name, *target()); |
288 if (index >= 0) { | 288 if (index >= 0) { |
289 ic_holder_map->RemoveFromCodeCache(*name, *target(), index); | 289 ic_holder_map->RemoveFromCodeCache(*name, *target(), index); |
290 } | 290 } |
291 } | 291 } |
292 | 292 |
293 if (receiver->IsGlobalObject()) { | 293 if (receiver->IsJSGlobalObject()) { |
294 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); | 294 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(receiver); |
295 LookupIterator it(global, name, LookupIterator::OWN_SKIP_INTERCEPTOR); | 295 LookupIterator it(global, name, LookupIterator::OWN_SKIP_INTERCEPTOR); |
296 if (it.state() == LookupIterator::ACCESS_CHECK) return false; | 296 if (it.state() == LookupIterator::ACCESS_CHECK) return false; |
297 if (!it.IsFound()) return false; | 297 if (!it.IsFound()) return false; |
298 return it.property_details().cell_type() == PropertyCellType::kConstant; | 298 return it.property_details().cell_type() == PropertyCellType::kConstant; |
299 } | 299 } |
300 | 300 |
301 return true; | 301 return true; |
302 } | 302 } |
303 | 303 |
304 | 304 |
(...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 } | 688 } |
689 Handle<Object> result; | 689 Handle<Object> result; |
690 ASSIGN_RETURN_ON_EXCEPTION( | 690 ASSIGN_RETURN_ON_EXCEPTION( |
691 isolate(), result, | 691 isolate(), result, |
692 Object::GetElement(isolate(), object, index, language_mode()), Object); | 692 Object::GetElement(isolate(), object, index, language_mode()), Object); |
693 return result; | 693 return result; |
694 } | 694 } |
695 | 695 |
696 bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic; | 696 bool use_ic = MigrateDeprecated(object) ? false : FLAG_use_ic; |
697 | 697 |
698 if (object->IsGlobalObject() && name->IsString()) { | 698 if (object->IsJSGlobalObject() && name->IsString()) { |
699 // Look up in script context table. | 699 // Look up in script context table. |
700 Handle<String> str_name = Handle<String>::cast(name); | 700 Handle<String> str_name = Handle<String>::cast(name); |
701 Handle<GlobalObject> global = Handle<GlobalObject>::cast(object); | 701 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(object); |
702 Handle<ScriptContextTable> script_contexts( | 702 Handle<ScriptContextTable> script_contexts( |
703 global->native_context()->script_context_table()); | 703 global->native_context()->script_context_table()); |
704 | 704 |
705 ScriptContextTable::LookupResult lookup_result; | 705 ScriptContextTable::LookupResult lookup_result; |
706 if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) { | 706 if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) { |
707 Handle<Object> result = | 707 Handle<Object> result = |
708 FixedArray::get(ScriptContextTable::GetContext( | 708 FixedArray::get(ScriptContextTable::GetContext( |
709 script_contexts, lookup_result.context_index), | 709 script_contexts, lookup_result.context_index), |
710 lookup_result.slot_index); | 710 lookup_result.slot_index); |
711 if (*result == *isolate()->factory()->the_hole_value()) { | 711 if (*result == *isolate()->factory()->the_hole_value()) { |
(...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1231 function->shared()->internal_formal_parameter_count(); | 1231 function->shared()->internal_formal_parameter_count(); |
1232 return compiler.CompileLoadViaGetter( | 1232 return compiler.CompileLoadViaGetter( |
1233 lookup->name(), lookup->GetAccessorIndex(), expected_arguments); | 1233 lookup->name(), lookup->GetAccessorIndex(), expected_arguments); |
1234 } | 1234 } |
1235 break; | 1235 break; |
1236 } | 1236 } |
1237 | 1237 |
1238 case LookupIterator::DATA: { | 1238 case LookupIterator::DATA: { |
1239 if (lookup->is_dictionary_holder()) { | 1239 if (lookup->is_dictionary_holder()) { |
1240 if (kind() != Code::LOAD_IC) break; | 1240 if (kind() != Code::LOAD_IC) break; |
1241 if (holder->IsGlobalObject()) { | 1241 if (holder->IsJSGlobalObject()) { |
1242 NamedLoadHandlerCompiler compiler(isolate(), map, holder, | 1242 NamedLoadHandlerCompiler compiler(isolate(), map, holder, |
1243 cache_holder); | 1243 cache_holder); |
1244 Handle<PropertyCell> cell = lookup->GetPropertyCell(); | 1244 Handle<PropertyCell> cell = lookup->GetPropertyCell(); |
1245 Handle<Code> code = compiler.CompileLoadGlobal( | 1245 Handle<Code> code = compiler.CompileLoadGlobal( |
1246 cell, lookup->name(), lookup->IsConfigurable()); | 1246 cell, lookup->name(), lookup->IsConfigurable()); |
1247 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. | 1247 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. |
1248 CacheHolderFlag flag; | 1248 CacheHolderFlag flag; |
1249 Handle<Map> stub_holder_map = | 1249 Handle<Map> stub_holder_map = |
1250 GetHandlerCacheHolder(map, receiver_is_holder, isolate(), &flag); | 1250 GetHandlerCacheHolder(map, receiver_is_holder, isolate(), &flag); |
1251 Map::UpdateCodeCache(stub_holder_map, lookup->name(), code); | 1251 Map::UpdateCodeCache(stub_holder_map, lookup->name(), code); |
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1506 TRACE_GENERIC_IC(isolate(), "StoreIC", "name as array index"); | 1506 TRACE_GENERIC_IC(isolate(), "StoreIC", "name as array index"); |
1507 } | 1507 } |
1508 Handle<Object> result; | 1508 Handle<Object> result; |
1509 ASSIGN_RETURN_ON_EXCEPTION( | 1509 ASSIGN_RETURN_ON_EXCEPTION( |
1510 isolate(), result, | 1510 isolate(), result, |
1511 Object::SetElement(isolate(), object, index, value, language_mode()), | 1511 Object::SetElement(isolate(), object, index, value, language_mode()), |
1512 Object); | 1512 Object); |
1513 return result; | 1513 return result; |
1514 } | 1514 } |
1515 | 1515 |
1516 if (object->IsGlobalObject() && name->IsString()) { | 1516 if (object->IsJSGlobalObject() && name->IsString()) { |
1517 // Look up in script context table. | 1517 // Look up in script context table. |
1518 Handle<String> str_name = Handle<String>::cast(name); | 1518 Handle<String> str_name = Handle<String>::cast(name); |
1519 Handle<GlobalObject> global = Handle<GlobalObject>::cast(object); | 1519 Handle<JSGlobalObject> global = Handle<JSGlobalObject>::cast(object); |
1520 Handle<ScriptContextTable> script_contexts( | 1520 Handle<ScriptContextTable> script_contexts( |
1521 global->native_context()->script_context_table()); | 1521 global->native_context()->script_context_table()); |
1522 | 1522 |
1523 ScriptContextTable::LookupResult lookup_result; | 1523 ScriptContextTable::LookupResult lookup_result; |
1524 if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) { | 1524 if (ScriptContextTable::Lookup(script_contexts, str_name, &lookup_result)) { |
1525 Handle<Context> script_context = ScriptContextTable::GetContext( | 1525 Handle<Context> script_context = ScriptContextTable::GetContext( |
1526 script_contexts, lookup_result.context_index); | 1526 script_contexts, lookup_result.context_index); |
1527 if (lookup_result.mode == CONST) { | 1527 if (lookup_result.mode == CONST) { |
1528 return TypeError(MessageTemplate::kConstAssign, object, name); | 1528 return TypeError(MessageTemplate::kConstAssign, object, name); |
1529 } | 1529 } |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1691 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); | 1691 TRACE_GENERIC_IC(isolate(), "StoreIC", "LookupForWrite said 'false'"); |
1692 } | 1692 } |
1693 Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); | 1693 Handle<Code> code = use_ic ? ComputeHandler(lookup, value) : slow_stub(); |
1694 | 1694 |
1695 PatchCache(lookup->name(), code); | 1695 PatchCache(lookup->name(), code); |
1696 TRACE_IC("StoreIC", lookup->name()); | 1696 TRACE_IC("StoreIC", lookup->name()); |
1697 } | 1697 } |
1698 | 1698 |
1699 | 1699 |
1700 static Handle<Code> PropertyCellStoreHandler( | 1700 static Handle<Code> PropertyCellStoreHandler( |
1701 Isolate* isolate, Handle<JSObject> receiver, Handle<GlobalObject> holder, | 1701 Isolate* isolate, Handle<JSObject> receiver, Handle<JSGlobalObject> holder, |
1702 Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) { | 1702 Handle<Name> name, Handle<PropertyCell> cell, PropertyCellType type) { |
1703 auto constant_type = Nothing<PropertyCellConstantType>(); | 1703 auto constant_type = Nothing<PropertyCellConstantType>(); |
1704 if (type == PropertyCellType::kConstantType) { | 1704 if (type == PropertyCellType::kConstantType) { |
1705 constant_type = Just(cell->GetConstantType()); | 1705 constant_type = Just(cell->GetConstantType()); |
1706 } | 1706 } |
1707 StoreGlobalStub stub(isolate, type, constant_type, | 1707 StoreGlobalStub stub(isolate, type, constant_type, |
1708 receiver->IsJSGlobalProxy()); | 1708 receiver->IsJSGlobalProxy()); |
1709 auto code = stub.GetCodeCopyFromTemplate(holder, cell); | 1709 auto code = stub.GetCodeCopyFromTemplate(holder, cell); |
1710 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. | 1710 // TODO(verwaest): Move caching of these NORMAL stubs outside as well. |
1711 HeapObject::UpdateMapCodeCache(receiver, name, code); | 1711 HeapObject::UpdateMapCodeCache(receiver, name, code); |
1712 return code; | 1712 return code; |
1713 } | 1713 } |
1714 | 1714 |
1715 | 1715 |
1716 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, | 1716 Handle<Code> StoreIC::CompileHandler(LookupIterator* lookup, |
1717 Handle<Object> value, | 1717 Handle<Object> value, |
1718 CacheHolderFlag cache_holder) { | 1718 CacheHolderFlag cache_holder) { |
1719 DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); | 1719 DCHECK_NE(LookupIterator::JSPROXY, lookup->state()); |
1720 | 1720 |
1721 // This is currently guaranteed by checks in StoreIC::Store. | 1721 // This is currently guaranteed by checks in StoreIC::Store. |
1722 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); | 1722 Handle<JSObject> receiver = Handle<JSObject>::cast(lookup->GetReceiver()); |
1723 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); | 1723 Handle<JSObject> holder = lookup->GetHolder<JSObject>(); |
1724 DCHECK(!receiver->IsAccessCheckNeeded() || | 1724 DCHECK(!receiver->IsAccessCheckNeeded() || |
1725 isolate()->IsInternallyUsedPropertyName(lookup->name())); | 1725 isolate()->IsInternallyUsedPropertyName(lookup->name())); |
1726 | 1726 |
1727 switch (lookup->state()) { | 1727 switch (lookup->state()) { |
1728 case LookupIterator::TRANSITION: { | 1728 case LookupIterator::TRANSITION: { |
1729 auto store_target = lookup->GetStoreTarget(); | 1729 auto store_target = lookup->GetStoreTarget(); |
1730 if (store_target->IsGlobalObject()) { | 1730 if (store_target->IsJSGlobalObject()) { |
1731 // TODO(dcarney): this currently just deopts. Use the transition cell. | 1731 // TODO(dcarney): this currently just deopts. Use the transition cell. |
1732 auto cell = isolate()->factory()->NewPropertyCell(); | 1732 auto cell = isolate()->factory()->NewPropertyCell(); |
1733 cell->set_value(*value); | 1733 cell->set_value(*value); |
1734 auto code = PropertyCellStoreHandler( | 1734 auto code = PropertyCellStoreHandler( |
1735 isolate(), store_target, Handle<GlobalObject>::cast(store_target), | 1735 isolate(), store_target, Handle<JSGlobalObject>::cast(store_target), |
1736 lookup->name(), cell, PropertyCellType::kConstant); | 1736 lookup->name(), cell, PropertyCellType::kConstant); |
1737 cell->set_value(isolate()->heap()->the_hole_value()); | 1737 cell->set_value(isolate()->heap()->the_hole_value()); |
1738 return code; | 1738 return code; |
1739 } | 1739 } |
1740 Handle<Map> transition = lookup->transition_map(); | 1740 Handle<Map> transition = lookup->transition_map(); |
1741 // Currently not handled by CompileStoreTransition. | 1741 // Currently not handled by CompileStoreTransition. |
1742 if (!holder->HasFastProperties()) { | 1742 if (!holder->HasFastProperties()) { |
1743 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); | 1743 TRACE_GENERIC_IC(isolate(), "StoreIC", "transition from slow"); |
1744 break; | 1744 break; |
1745 } | 1745 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1803 function->shared()->internal_formal_parameter_count(); | 1803 function->shared()->internal_formal_parameter_count(); |
1804 return compiler.CompileStoreViaSetter(receiver, lookup->name(), | 1804 return compiler.CompileStoreViaSetter(receiver, lookup->name(), |
1805 lookup->GetAccessorIndex(), | 1805 lookup->GetAccessorIndex(), |
1806 expected_arguments); | 1806 expected_arguments); |
1807 } | 1807 } |
1808 break; | 1808 break; |
1809 } | 1809 } |
1810 | 1810 |
1811 case LookupIterator::DATA: { | 1811 case LookupIterator::DATA: { |
1812 if (lookup->is_dictionary_holder()) { | 1812 if (lookup->is_dictionary_holder()) { |
1813 if (holder->IsGlobalObject()) { | 1813 if (holder->IsJSGlobalObject()) { |
1814 DCHECK(holder.is_identical_to(receiver) || | 1814 DCHECK(holder.is_identical_to(receiver) || |
1815 receiver->map()->prototype() == *holder); | 1815 receiver->map()->prototype() == *holder); |
1816 auto cell = lookup->GetPropertyCell(); | 1816 auto cell = lookup->GetPropertyCell(); |
1817 auto updated_type = PropertyCell::UpdatedType( | 1817 auto updated_type = PropertyCell::UpdatedType( |
1818 cell, value, lookup->property_details()); | 1818 cell, value, lookup->property_details()); |
1819 auto code = PropertyCellStoreHandler( | 1819 auto code = PropertyCellStoreHandler( |
1820 isolate(), receiver, Handle<GlobalObject>::cast(holder), | 1820 isolate(), receiver, Handle<JSGlobalObject>::cast(holder), |
1821 lookup->name(), cell, updated_type); | 1821 lookup->name(), cell, updated_type); |
1822 return code; | 1822 return code; |
1823 } | 1823 } |
1824 DCHECK(holder.is_identical_to(receiver)); | 1824 DCHECK(holder.is_identical_to(receiver)); |
1825 return isolate()->builtins()->StoreIC_Normal(); | 1825 return isolate()->builtins()->StoreIC_Normal(); |
1826 } | 1826 } |
1827 | 1827 |
1828 // -------------- Fields -------------- | 1828 // -------------- Fields -------------- |
1829 if (lookup->property_details().type() == DATA) { | 1829 if (lookup->property_details().type() == DATA) { |
1830 bool use_stub = true; | 1830 bool use_stub = true; |
(...skipping 1302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3133 KeyedLoadICNexus nexus(vector, vector_slot); | 3133 KeyedLoadICNexus nexus(vector, vector_slot); |
3134 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 3134 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
3135 ic.UpdateState(receiver, key); | 3135 ic.UpdateState(receiver, key); |
3136 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 3136 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
3137 } | 3137 } |
3138 | 3138 |
3139 return *result; | 3139 return *result; |
3140 } | 3140 } |
3141 } // namespace internal | 3141 } // namespace internal |
3142 } // namespace v8 | 3142 } // namespace v8 |
OLD | NEW |