Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: src/ic/ic.cc

Issue 894683003: Introduce LanguageMode, drop StrictMode. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: . Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 566 matching lines...) Expand 10 before | Expand all | Expand 10 after
577 target->extra_ic_state()); 577 target->extra_ic_state());
578 SetTargetAtAddress(address, code, constant_pool); 578 SetTargetAtAddress(address, code, constant_pool);
579 } 579 }
580 580
581 581
582 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target, 582 void KeyedStoreIC::Clear(Isolate* isolate, Address address, Code* target,
583 ConstantPoolArray* constant_pool) { 583 ConstantPoolArray* constant_pool) {
584 if (IsCleared(target)) return; 584 if (IsCleared(target)) return;
585 SetTargetAtAddress( 585 SetTargetAtAddress(
586 address, *pre_monomorphic_stub( 586 address, *pre_monomorphic_stub(
587 isolate, StoreIC::GetStrictMode(target->extra_ic_state())), 587 isolate, StoreIC::GetLanguageMode(target->extra_ic_state())),
588 constant_pool); 588 constant_pool);
589 } 589 }
590 590
591 591
592 void CompareIC::Clear(Isolate* isolate, Address address, Code* target, 592 void CompareIC::Clear(Isolate* isolate, Address address, Code* target,
593 ConstantPoolArray* constant_pool) { 593 ConstantPoolArray* constant_pool) {
594 DCHECK(CodeStub::GetMajorKey(target) == CodeStub::CompareIC); 594 DCHECK(CodeStub::GetMajorKey(target) == CodeStub::CompareIC);
595 CompareICStub stub(target->stub_key(), isolate); 595 CompareICStub stub(target->stub_key(), isolate);
596 // Only clear CompareICs that can retain objects. 596 // Only clear CompareICs that can retain objects.
597 if (stub.state() != CompareICState::KNOWN_OBJECT) return; 597 if (stub.state() != CompareICState::KNOWN_OBJECT) return;
(...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 cache_holder); 1209 cache_holder);
1210 return compiler.CompileLoadCallback(lookup->name(), info); 1210 return compiler.CompileLoadCallback(lookup->name(), info);
1211 } 1211 }
1212 if (accessors->IsAccessorPair()) { 1212 if (accessors->IsAccessorPair()) {
1213 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(), 1213 Handle<Object> getter(Handle<AccessorPair>::cast(accessors)->getter(),
1214 isolate()); 1214 isolate());
1215 if (!getter->IsJSFunction()) break; 1215 if (!getter->IsJSFunction()) break;
1216 if (!holder->HasFastProperties()) break; 1216 if (!holder->HasFastProperties()) break;
1217 Handle<JSFunction> function = Handle<JSFunction>::cast(getter); 1217 Handle<JSFunction> function = Handle<JSFunction>::cast(getter);
1218 if (!receiver->IsJSObject() && !function->IsBuiltin() && 1218 if (!receiver->IsJSObject() && !function->IsBuiltin() &&
1219 function->shared()->strict_mode() == SLOPPY) { 1219 !is_strict(function->shared()->language_mode())) {
1220 // Calling sloppy non-builtins with a value as the receiver 1220 // Calling sloppy non-builtins with a value as the receiver
1221 // requires boxing. 1221 // requires boxing.
1222 break; 1222 break;
1223 } 1223 }
1224 CallOptimization call_optimization(function); 1224 CallOptimization call_optimization(function);
1225 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder, 1225 NamedLoadHandlerCompiler compiler(isolate(), receiver_type(), holder,
1226 cache_holder); 1226 cache_holder);
1227 if (call_optimization.is_simple_api_call() && 1227 if (call_optimization.is_simple_api_call() &&
1228 call_optimization.IsCompatibleReceiver(receiver, holder)) { 1228 call_optimization.IsCompatibleReceiver(receiver, holder)) {
1229 return compiler.CompileLoadCallback(lookup->name(), call_optimization, 1229 return compiler.CompileLoadCallback(lookup->name(), call_optimization,
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after
1533 return value; 1533 return value;
1534 } 1534 }
1535 } 1535 }
1536 1536
1537 // TODO(verwaest): Let SetProperty do the migration, since storing a property 1537 // TODO(verwaest): Let SetProperty do the migration, since storing a property
1538 // might deprecate the current map again, if value does not fit. 1538 // might deprecate the current map again, if value does not fit.
1539 if (MigrateDeprecated(object) || object->IsJSProxy()) { 1539 if (MigrateDeprecated(object) || object->IsJSProxy()) {
1540 Handle<Object> result; 1540 Handle<Object> result;
1541 ASSIGN_RETURN_ON_EXCEPTION( 1541 ASSIGN_RETURN_ON_EXCEPTION(
1542 isolate(), result, 1542 isolate(), result,
1543 Object::SetProperty(object, name, value, strict_mode()), Object); 1543 Object::SetProperty(object, name, value, language_mode()), Object);
1544 return result; 1544 return result;
1545 } 1545 }
1546 1546
1547 // If the object is undefined or null it's illegal to try to set any 1547 // If the object is undefined or null it's illegal to try to set any
1548 // properties on it; throw a TypeError in that case. 1548 // properties on it; throw a TypeError in that case.
1549 if (object->IsUndefined() || object->IsNull()) { 1549 if (object->IsUndefined() || object->IsNull()) {
1550 return TypeError("non_object_property_store", object, name); 1550 return TypeError("non_object_property_store", object, name);
1551 } 1551 }
1552 1552
1553 // Check if the given name is an array index. 1553 // Check if the given name is an array index.
1554 uint32_t index; 1554 uint32_t index;
1555 if (name->AsArrayIndex(&index)) { 1555 if (name->AsArrayIndex(&index)) {
1556 // Ignore other stores where the receiver is not a JSObject. 1556 // Ignore other stores where the receiver is not a JSObject.
1557 // TODO(1475): Must check prototype chains of object wrappers. 1557 // TODO(1475): Must check prototype chains of object wrappers.
1558 if (!object->IsJSObject()) return value; 1558 if (!object->IsJSObject()) return value;
1559 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1559 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1560 1560
1561 Handle<Object> result; 1561 Handle<Object> result;
1562 ASSIGN_RETURN_ON_EXCEPTION( 1562 ASSIGN_RETURN_ON_EXCEPTION(
1563 isolate(), result, 1563 isolate(), result,
1564 JSObject::SetElement(receiver, index, value, NONE, strict_mode()), 1564 JSObject::SetElement(receiver, index, value, NONE, language_mode()),
1565 Object); 1565 Object);
1566 return value; 1566 return value;
1567 } 1567 }
1568 1568
1569 // Observed objects are always modified through the runtime. 1569 // Observed objects are always modified through the runtime.
1570 if (object->IsHeapObject() && 1570 if (object->IsHeapObject() &&
1571 Handle<HeapObject>::cast(object)->map()->is_observed()) { 1571 Handle<HeapObject>::cast(object)->map()->is_observed()) {
1572 Handle<Object> result; 1572 Handle<Object> result;
1573 ASSIGN_RETURN_ON_EXCEPTION( 1573 ASSIGN_RETURN_ON_EXCEPTION(
1574 isolate(), result, 1574 isolate(), result,
1575 Object::SetProperty(object, name, value, strict_mode(), store_mode), 1575 Object::SetProperty(object, name, value, language_mode(), store_mode),
1576 Object); 1576 Object);
1577 return result; 1577 return result;
1578 } 1578 }
1579 1579
1580 LookupIterator it(object, name); 1580 LookupIterator it(object, name);
1581 if (FLAG_use_ic) UpdateCaches(&it, value, store_mode); 1581 if (FLAG_use_ic) UpdateCaches(&it, value, store_mode);
1582 1582
1583 // Set the property. 1583 // Set the property.
1584 Handle<Object> result; 1584 Handle<Object> result;
1585 ASSIGN_RETURN_ON_EXCEPTION( 1585 ASSIGN_RETURN_ON_EXCEPTION(
1586 isolate(), result, 1586 isolate(), result,
1587 Object::SetProperty(&it, value, strict_mode(), store_mode), Object); 1587 Object::SetProperty(&it, value, language_mode(), store_mode), Object);
1588 return result; 1588 return result;
1589 } 1589 }
1590 1590
1591 1591
1592 Handle<Code> CallIC::initialize_stub(Isolate* isolate, int argc, 1592 Handle<Code> CallIC::initialize_stub(Isolate* isolate, int argc,
1593 CallICState::CallType call_type) { 1593 CallICState::CallType call_type) {
1594 CallICTrampolineStub stub(isolate, CallICState(argc, call_type)); 1594 CallICTrampolineStub stub(isolate, CallICState(argc, call_type));
1595 Handle<Code> code = stub.GetCode(); 1595 Handle<Code> code = stub.GetCode();
1596 return code; 1596 return code;
1597 } 1597 }
1598 1598
1599 1599
1600 Handle<Code> CallIC::initialize_stub_in_optimized_code( 1600 Handle<Code> CallIC::initialize_stub_in_optimized_code(
1601 Isolate* isolate, int argc, CallICState::CallType call_type) { 1601 Isolate* isolate, int argc, CallICState::CallType call_type) {
1602 CallICStub stub(isolate, CallICState(argc, call_type)); 1602 CallICStub stub(isolate, CallICState(argc, call_type));
1603 Handle<Code> code = stub.GetCode(); 1603 Handle<Code> code = stub.GetCode();
1604 return code; 1604 return code;
1605 } 1605 }
1606 1606
1607 1607
1608 Handle<Code> StoreIC::initialize_stub(Isolate* isolate, 1608 Handle<Code> StoreIC::initialize_stub(Isolate* isolate,
1609 StrictMode strict_mode) { 1609 LanguageMode language_mode) {
1610 ExtraICState extra_state = ComputeExtraICState(strict_mode); 1610 ExtraICState extra_state = ComputeExtraICState(language_mode);
1611 Handle<Code> ic = 1611 Handle<Code> ic =
1612 PropertyICCompiler::ComputeStore(isolate, UNINITIALIZED, extra_state); 1612 PropertyICCompiler::ComputeStore(isolate, UNINITIALIZED, extra_state);
1613 return ic; 1613 return ic;
1614 } 1614 }
1615 1615
1616 1616
1617 Handle<Code> StoreIC::megamorphic_stub() { 1617 Handle<Code> StoreIC::megamorphic_stub() {
1618 if (kind() == Code::STORE_IC) { 1618 if (kind() == Code::STORE_IC) {
1619 return PropertyICCompiler::ComputeStore(isolate(), MEGAMORPHIC, 1619 return PropertyICCompiler::ComputeStore(isolate(), MEGAMORPHIC,
1620 extra_ic_state()); 1620 extra_ic_state());
1621 } else { 1621 } else {
1622 DCHECK(kind() == Code::KEYED_STORE_IC); 1622 DCHECK(kind() == Code::KEYED_STORE_IC);
1623 if (strict_mode() == STRICT) { 1623 if (is_strict(language_mode())) {
1624 return isolate()->builtins()->KeyedStoreIC_Megamorphic_Strict(); 1624 return isolate()->builtins()->KeyedStoreIC_Megamorphic_Strict();
1625 } else { 1625 } else {
1626 return isolate()->builtins()->KeyedStoreIC_Megamorphic(); 1626 return isolate()->builtins()->KeyedStoreIC_Megamorphic();
1627 } 1627 }
1628 } 1628 }
1629 } 1629 }
1630 1630
1631 1631
1632 Handle<Code> StoreIC::slow_stub() const { 1632 Handle<Code> StoreIC::slow_stub() const {
1633 if (kind() == Code::STORE_IC) { 1633 if (kind() == Code::STORE_IC) {
1634 return isolate()->builtins()->StoreIC_Slow(); 1634 return isolate()->builtins()->StoreIC_Slow();
1635 } else { 1635 } else {
1636 DCHECK(kind() == Code::KEYED_STORE_IC); 1636 DCHECK(kind() == Code::KEYED_STORE_IC);
1637 return isolate()->builtins()->KeyedStoreIC_Slow(); 1637 return isolate()->builtins()->KeyedStoreIC_Slow();
1638 } 1638 }
1639 } 1639 }
1640 1640
1641 1641
1642 Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate, 1642 Handle<Code> StoreIC::pre_monomorphic_stub(Isolate* isolate,
1643 StrictMode strict_mode) { 1643 LanguageMode language_mode) {
1644 ExtraICState state = ComputeExtraICState(strict_mode); 1644 ExtraICState state = ComputeExtraICState(language_mode);
1645 return PropertyICCompiler::ComputeStore(isolate, PREMONOMORPHIC, state); 1645 return PropertyICCompiler::ComputeStore(isolate, PREMONOMORPHIC, state);
1646 } 1646 }
1647 1647
1648 1648
1649 void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value, 1649 void StoreIC::UpdateCaches(LookupIterator* lookup, Handle<Object> value,
1650 JSReceiver::StoreFromKeyed store_mode) { 1650 JSReceiver::StoreFromKeyed store_mode) {
1651 if (state() == UNINITIALIZED) { 1651 if (state() == UNINITIALIZED) {
1652 // This is the first time we execute this inline cache. Set the target to 1652 // This is the first time we execute this inline cache. Set the target to
1653 // the pre monomorphic stub to delay setting the monomorphic state. 1653 // the pre monomorphic stub to delay setting the monomorphic state.
1654 set_target(*pre_monomorphic_stub()); 1654 set_target(*pre_monomorphic_stub());
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
1804 } 1804 }
1805 1805
1806 Handle<Map> receiver_map(receiver->map(), isolate()); 1806 Handle<Map> receiver_map(receiver->map(), isolate());
1807 MapHandleList target_receiver_maps; 1807 MapHandleList target_receiver_maps;
1808 TargetMaps(&target_receiver_maps); 1808 TargetMaps(&target_receiver_maps);
1809 if (target_receiver_maps.length() == 0) { 1809 if (target_receiver_maps.length() == 0) {
1810 Handle<Map> monomorphic_map = 1810 Handle<Map> monomorphic_map =
1811 ComputeTransitionedMap(receiver_map, store_mode); 1811 ComputeTransitionedMap(receiver_map, store_mode);
1812 store_mode = GetNonTransitioningStoreMode(store_mode); 1812 store_mode = GetNonTransitioningStoreMode(store_mode);
1813 return PropertyICCompiler::ComputeKeyedStoreMonomorphic( 1813 return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
1814 monomorphic_map, strict_mode(), store_mode); 1814 monomorphic_map, language_mode(), store_mode);
1815 } 1815 }
1816 1816
1817 // There are several special cases where an IC that is MONOMORPHIC can still 1817 // There are several special cases where an IC that is MONOMORPHIC can still
1818 // transition to a different GetNonTransitioningStoreMode IC that handles a 1818 // transition to a different GetNonTransitioningStoreMode IC that handles a
1819 // superset of the original IC. Handle those here if the receiver map hasn't 1819 // superset of the original IC. Handle those here if the receiver map hasn't
1820 // changed or it has transitioned to a more general kind. 1820 // changed or it has transitioned to a more general kind.
1821 KeyedAccessStoreMode old_store_mode = 1821 KeyedAccessStoreMode old_store_mode =
1822 KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); 1822 KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state());
1823 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); 1823 Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
1824 if (state() == MONOMORPHIC) { 1824 if (state() == MONOMORPHIC) {
1825 Handle<Map> transitioned_receiver_map = receiver_map; 1825 Handle<Map> transitioned_receiver_map = receiver_map;
1826 if (IsTransitionStoreMode(store_mode)) { 1826 if (IsTransitionStoreMode(store_mode)) {
1827 transitioned_receiver_map = 1827 transitioned_receiver_map =
1828 ComputeTransitionedMap(receiver_map, store_mode); 1828 ComputeTransitionedMap(receiver_map, store_mode);
1829 } 1829 }
1830 if ((receiver_map.is_identical_to(previous_receiver_map) && 1830 if ((receiver_map.is_identical_to(previous_receiver_map) &&
1831 IsTransitionStoreMode(store_mode)) || 1831 IsTransitionStoreMode(store_mode)) ||
1832 IsTransitionOfMonomorphicTarget(*previous_receiver_map, 1832 IsTransitionOfMonomorphicTarget(*previous_receiver_map,
1833 *transitioned_receiver_map)) { 1833 *transitioned_receiver_map)) {
1834 // If the "old" and "new" maps are in the same elements map family, or 1834 // If the "old" and "new" maps are in the same elements map family, or
1835 // if they at least come from the same origin for a transitioning store, 1835 // if they at least come from the same origin for a transitioning store,
1836 // stay MONOMORPHIC and use the map for the most generic ElementsKind. 1836 // stay MONOMORPHIC and use the map for the most generic ElementsKind.
1837 store_mode = GetNonTransitioningStoreMode(store_mode); 1837 store_mode = GetNonTransitioningStoreMode(store_mode);
1838 return PropertyICCompiler::ComputeKeyedStoreMonomorphic( 1838 return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
1839 transitioned_receiver_map, strict_mode(), store_mode); 1839 transitioned_receiver_map, language_mode(), store_mode);
1840 } else if (*previous_receiver_map == receiver->map() && 1840 } else if (*previous_receiver_map == receiver->map() &&
1841 old_store_mode == STANDARD_STORE && 1841 old_store_mode == STANDARD_STORE &&
1842 (store_mode == STORE_AND_GROW_NO_TRANSITION || 1842 (store_mode == STORE_AND_GROW_NO_TRANSITION ||
1843 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 1843 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
1844 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { 1844 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) {
1845 // A "normal" IC that handles stores can switch to a version that can 1845 // A "normal" IC that handles stores can switch to a version that can
1846 // grow at the end of the array, handle OOB accesses or copy COW arrays 1846 // grow at the end of the array, handle OOB accesses or copy COW arrays
1847 // and still stay MONOMORPHIC. 1847 // and still stay MONOMORPHIC.
1848 return PropertyICCompiler::ComputeKeyedStoreMonomorphic( 1848 return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
1849 receiver_map, strict_mode(), store_mode); 1849 receiver_map, language_mode(), store_mode);
1850 } 1850 }
1851 } 1851 }
1852 1852
1853 DCHECK(state() != GENERIC); 1853 DCHECK(state() != GENERIC);
1854 1854
1855 bool map_added = 1855 bool map_added =
1856 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); 1856 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
1857 1857
1858 if (IsTransitionStoreMode(store_mode)) { 1858 if (IsTransitionStoreMode(store_mode)) {
1859 Handle<Map> transitioned_receiver_map = 1859 Handle<Map> transitioned_receiver_map =
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1900 } 1900 }
1901 if (external_arrays != 0 && 1901 if (external_arrays != 0 &&
1902 external_arrays != target_receiver_maps.length()) { 1902 external_arrays != target_receiver_maps.length()) {
1903 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", 1903 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
1904 "unsupported combination of external and normal arrays"); 1904 "unsupported combination of external and normal arrays");
1905 return megamorphic_stub(); 1905 return megamorphic_stub();
1906 } 1906 }
1907 } 1907 }
1908 1908
1909 return PropertyICCompiler::ComputeKeyedStorePolymorphic( 1909 return PropertyICCompiler::ComputeKeyedStorePolymorphic(
1910 &target_receiver_maps, store_mode, strict_mode()); 1910 &target_receiver_maps, store_mode, language_mode());
1911 } 1911 }
1912 1912
1913 1913
1914 Handle<Map> KeyedStoreIC::ComputeTransitionedMap( 1914 Handle<Map> KeyedStoreIC::ComputeTransitionedMap(
1915 Handle<Map> map, KeyedAccessStoreMode store_mode) { 1915 Handle<Map> map, KeyedAccessStoreMode store_mode) {
1916 switch (store_mode) { 1916 switch (store_mode) {
1917 case STORE_TRANSITION_SMI_TO_OBJECT: 1917 case STORE_TRANSITION_SMI_TO_OBJECT:
1918 case STORE_TRANSITION_DOUBLE_TO_OBJECT: 1918 case STORE_TRANSITION_DOUBLE_TO_OBJECT:
1919 case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT: 1919 case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT:
1920 case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT: 1920 case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT:
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2030 2030
2031 MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object, 2031 MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
2032 Handle<Object> key, 2032 Handle<Object> key,
2033 Handle<Object> value) { 2033 Handle<Object> value) {
2034 // TODO(verwaest): Let SetProperty do the migration, since storing a property 2034 // TODO(verwaest): Let SetProperty do the migration, since storing a property
2035 // might deprecate the current map again, if value does not fit. 2035 // might deprecate the current map again, if value does not fit.
2036 if (MigrateDeprecated(object)) { 2036 if (MigrateDeprecated(object)) {
2037 Handle<Object> result; 2037 Handle<Object> result;
2038 ASSIGN_RETURN_ON_EXCEPTION( 2038 ASSIGN_RETURN_ON_EXCEPTION(
2039 isolate(), result, Runtime::SetObjectProperty(isolate(), object, key, 2039 isolate(), result, Runtime::SetObjectProperty(isolate(), object, key,
2040 value, strict_mode()), 2040 value, language_mode()),
2041 Object); 2041 Object);
2042 return result; 2042 return result;
2043 } 2043 }
2044 2044
2045 // Check for non-string values that can be converted into an 2045 // Check for non-string values that can be converted into an
2046 // internalized string directly or is representable as a smi. 2046 // internalized string directly or is representable as a smi.
2047 key = TryConvertKey(key, isolate()); 2047 key = TryConvertKey(key, isolate());
2048 2048
2049 Handle<Object> store_handle; 2049 Handle<Object> store_handle;
2050 Handle<Code> stub = megamorphic_stub(); 2050 Handle<Code> stub = megamorphic_stub();
(...skipping 29 matching lines...) Expand all
2080 } 2080 }
2081 2081
2082 if (use_ic) { 2082 if (use_ic) {
2083 DCHECK(!object->IsAccessCheckNeeded()); 2083 DCHECK(!object->IsAccessCheckNeeded());
2084 2084
2085 if (object->IsJSObject()) { 2085 if (object->IsJSObject()) {
2086 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 2086 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
2087 bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null(); 2087 bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null();
2088 if (receiver->elements()->map() == 2088 if (receiver->elements()->map() ==
2089 isolate()->heap()->sloppy_arguments_elements_map()) { 2089 isolate()->heap()->sloppy_arguments_elements_map()) {
2090 if (strict_mode() == SLOPPY) { 2090 if (!is_strict(language_mode())) {
2091 stub = sloppy_arguments_stub(); 2091 stub = sloppy_arguments_stub();
2092 } else { 2092 } else {
2093 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver"); 2093 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver");
2094 } 2094 }
2095 } else if (key_is_smi_like && 2095 } else if (key_is_smi_like &&
2096 !(target().is_identical_to(sloppy_arguments_stub()))) { 2096 !(target().is_identical_to(sloppy_arguments_stub()))) {
2097 // We should go generic if receiver isn't a dictionary, but our 2097 // We should go generic if receiver isn't a dictionary, but our
2098 // prototype chain does have dictionary elements. This ensures that 2098 // prototype chain does have dictionary elements. This ensures that
2099 // other non-dictionary receivers in the polymorphic case benefit 2099 // other non-dictionary receivers in the polymorphic case benefit
2100 // from fast path keyed stores. 2100 // from fast path keyed stores.
2101 if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) { 2101 if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) {
2102 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value); 2102 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value);
2103 stub = StoreElementStub(receiver, store_mode); 2103 stub = StoreElementStub(receiver, store_mode);
2104 } else { 2104 } else {
2105 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "dictionary prototype"); 2105 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "dictionary prototype");
2106 } 2106 }
2107 } else { 2107 } else {
2108 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-smi-like key"); 2108 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-smi-like key");
2109 } 2109 }
2110 } else { 2110 } else {
2111 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-JSObject receiver"); 2111 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-JSObject receiver");
2112 } 2112 }
2113 } 2113 }
2114 2114
2115 if (store_handle.is_null()) { 2115 if (store_handle.is_null()) {
2116 ASSIGN_RETURN_ON_EXCEPTION( 2116 ASSIGN_RETURN_ON_EXCEPTION(
2117 isolate(), store_handle, 2117 isolate(), store_handle,
2118 Runtime::SetObjectProperty(isolate(), object, key, value, 2118 Runtime::SetObjectProperty(isolate(), object, key, value,
2119 strict_mode()), 2119 language_mode()),
2120 Object); 2120 Object);
2121 } 2121 }
2122 2122
2123 DCHECK(!is_target_set()); 2123 DCHECK(!is_target_set());
2124 Code* megamorphic = *megamorphic_stub(); 2124 Code* megamorphic = *megamorphic_stub();
2125 if (*stub == megamorphic) { 2125 if (*stub == megamorphic) {
2126 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic"); 2126 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic");
2127 } 2127 }
2128 if (*stub == *slow_stub()) { 2128 if (*stub == *slow_stub()) {
2129 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub"); 2129 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub");
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
2439 } 2439 }
2440 2440
2441 2441
2442 RUNTIME_FUNCTION(StoreIC_Slow) { 2442 RUNTIME_FUNCTION(StoreIC_Slow) {
2443 HandleScope scope(isolate); 2443 HandleScope scope(isolate);
2444 DCHECK(args.length() == 3); 2444 DCHECK(args.length() == 3);
2445 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2445 StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2446 Handle<Object> object = args.at<Object>(0); 2446 Handle<Object> object = args.at<Object>(0);
2447 Handle<Object> key = args.at<Object>(1); 2447 Handle<Object> key = args.at<Object>(1);
2448 Handle<Object> value = args.at<Object>(2); 2448 Handle<Object> value = args.at<Object>(2);
2449 StrictMode strict_mode = ic.strict_mode(); 2449 LanguageMode language_mode = ic.language_mode();
2450 Handle<Object> result; 2450 Handle<Object> result;
2451 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2451 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2452 isolate, result, 2452 isolate, result,
2453 Runtime::SetObjectProperty(isolate, object, key, value, strict_mode)); 2453 Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
2454 return *result; 2454 return *result;
2455 } 2455 }
2456 2456
2457 2457
2458 RUNTIME_FUNCTION(KeyedStoreIC_Slow) { 2458 RUNTIME_FUNCTION(KeyedStoreIC_Slow) {
2459 HandleScope scope(isolate); 2459 HandleScope scope(isolate);
2460 DCHECK(args.length() == 3); 2460 DCHECK(args.length() == 3);
2461 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2461 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2462 Handle<Object> object = args.at<Object>(0); 2462 Handle<Object> object = args.at<Object>(0);
2463 Handle<Object> key = args.at<Object>(1); 2463 Handle<Object> key = args.at<Object>(1);
2464 Handle<Object> value = args.at<Object>(2); 2464 Handle<Object> value = args.at<Object>(2);
2465 StrictMode strict_mode = ic.strict_mode(); 2465 LanguageMode language_mode = ic.language_mode();
2466 Handle<Object> result; 2466 Handle<Object> result;
2467 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2467 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2468 isolate, result, 2468 isolate, result,
2469 Runtime::SetObjectProperty(isolate, object, key, value, strict_mode)); 2469 Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
2470 return *result; 2470 return *result;
2471 } 2471 }
2472 2472
2473 2473
2474 RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss) { 2474 RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss) {
2475 TimerEventScope<TimerEventIcMiss> timer(isolate); 2475 TimerEventScope<TimerEventIcMiss> timer(isolate);
2476 HandleScope scope(isolate); 2476 HandleScope scope(isolate);
2477 DCHECK(args.length() == 4); 2477 DCHECK(args.length() == 4);
2478 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2478 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
2479 Handle<Object> value = args.at<Object>(0); 2479 Handle<Object> value = args.at<Object>(0);
2480 Handle<Map> map = args.at<Map>(1); 2480 Handle<Map> map = args.at<Map>(1);
2481 Handle<Object> key = args.at<Object>(2); 2481 Handle<Object> key = args.at<Object>(2);
2482 Handle<Object> object = args.at<Object>(3); 2482 Handle<Object> object = args.at<Object>(3);
2483 StrictMode strict_mode = ic.strict_mode(); 2483 LanguageMode language_mode = ic.language_mode();
2484 if (object->IsJSObject()) { 2484 if (object->IsJSObject()) {
2485 JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), 2485 JSObject::TransitionElementsKind(Handle<JSObject>::cast(object),
2486 map->elements_kind()); 2486 map->elements_kind());
2487 } 2487 }
2488 Handle<Object> result; 2488 Handle<Object> result;
2489 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2489 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2490 isolate, result, 2490 isolate, result,
2491 Runtime::SetObjectProperty(isolate, object, key, value, strict_mode)); 2491 Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
2492 return *result; 2492 return *result;
2493 } 2493 }
2494 2494
2495 2495
2496 MaybeHandle<Object> BinaryOpIC::Transition( 2496 MaybeHandle<Object> BinaryOpIC::Transition(
2497 Handle<AllocationSite> allocation_site, Handle<Object> left, 2497 Handle<AllocationSite> allocation_site, Handle<Object> left,
2498 Handle<Object> right) { 2498 Handle<Object> right) {
2499 BinaryOpICState state(isolate(), target()->extra_ic_state()); 2499 BinaryOpICState state(isolate(), target()->extra_ic_state());
2500 2500
2501 // Compute the actual result using the builtin for the binary operation. 2501 // Compute the actual result using the builtin for the binary operation.
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
2932 Handle<JSObject>::cast(current)->HasNamedInterceptor()) { 2932 Handle<JSObject>::cast(current)->HasNamedInterceptor()) {
2933 found = true; 2933 found = true;
2934 break; 2934 break;
2935 } 2935 }
2936 } 2936 }
2937 DCHECK(found); 2937 DCHECK(found);
2938 #endif 2938 #endif
2939 Handle<Object> result; 2939 Handle<Object> result;
2940 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2940 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2941 isolate, result, 2941 isolate, result,
2942 JSObject::SetProperty(receiver, name, value, ic.strict_mode())); 2942 JSObject::SetProperty(receiver, name, value, ic.language_mode()));
2943 return *result; 2943 return *result;
2944 } 2944 }
2945 2945
2946 2946
2947 RUNTIME_FUNCTION(LoadElementWithInterceptor) { 2947 RUNTIME_FUNCTION(LoadElementWithInterceptor) {
2948 HandleScope scope(isolate); 2948 HandleScope scope(isolate);
2949 Handle<JSObject> receiver = args.at<JSObject>(0); 2949 Handle<JSObject> receiver = args.at<JSObject>(0);
2950 DCHECK(args.smi_at(1) >= 0); 2950 DCHECK(args.smi_at(1) >= 0);
2951 uint32_t index = args.smi_at(1); 2951 uint32_t index = args.smi_at(1);
2952 Handle<Object> result; 2952 Handle<Object> result;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3000 static const Address IC_utilities[] = { 3000 static const Address IC_utilities[] = {
3001 #define ADDR(name) FUNCTION_ADDR(name), 3001 #define ADDR(name) FUNCTION_ADDR(name),
3002 IC_UTIL_LIST(ADDR) NULL 3002 IC_UTIL_LIST(ADDR) NULL
3003 #undef ADDR 3003 #undef ADDR
3004 }; 3004 };
3005 3005
3006 3006
3007 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } 3007 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; }
3008 } 3008 }
3009 } // namespace v8::internal 3009 } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698