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

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: rebased (w/ conflicts) 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
« no previous file with comments | « src/ic/ic.h ('k') | src/ic/ic-compiler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_sloppy(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 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1806 } 1806 }
1807 1807
1808 Handle<Map> receiver_map(receiver->map(), isolate()); 1808 Handle<Map> receiver_map(receiver->map(), isolate());
1809 MapHandleList target_receiver_maps; 1809 MapHandleList target_receiver_maps;
1810 TargetMaps(&target_receiver_maps); 1810 TargetMaps(&target_receiver_maps);
1811 if (target_receiver_maps.length() == 0) { 1811 if (target_receiver_maps.length() == 0) {
1812 Handle<Map> monomorphic_map = 1812 Handle<Map> monomorphic_map =
1813 ComputeTransitionedMap(receiver_map, store_mode); 1813 ComputeTransitionedMap(receiver_map, store_mode);
1814 store_mode = GetNonTransitioningStoreMode(store_mode); 1814 store_mode = GetNonTransitioningStoreMode(store_mode);
1815 return PropertyICCompiler::ComputeKeyedStoreMonomorphic( 1815 return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
1816 monomorphic_map, strict_mode(), store_mode); 1816 monomorphic_map, language_mode(), store_mode);
1817 } 1817 }
1818 1818
1819 // There are several special cases where an IC that is MONOMORPHIC can still 1819 // There are several special cases where an IC that is MONOMORPHIC can still
1820 // transition to a different GetNonTransitioningStoreMode IC that handles a 1820 // transition to a different GetNonTransitioningStoreMode IC that handles a
1821 // superset of the original IC. Handle those here if the receiver map hasn't 1821 // superset of the original IC. Handle those here if the receiver map hasn't
1822 // changed or it has transitioned to a more general kind. 1822 // changed or it has transitioned to a more general kind.
1823 KeyedAccessStoreMode old_store_mode = 1823 KeyedAccessStoreMode old_store_mode =
1824 KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); 1824 KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state());
1825 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); 1825 Handle<Map> previous_receiver_map = target_receiver_maps.at(0);
1826 if (state() == MONOMORPHIC) { 1826 if (state() == MONOMORPHIC) {
1827 Handle<Map> transitioned_receiver_map = receiver_map; 1827 Handle<Map> transitioned_receiver_map = receiver_map;
1828 if (IsTransitionStoreMode(store_mode)) { 1828 if (IsTransitionStoreMode(store_mode)) {
1829 transitioned_receiver_map = 1829 transitioned_receiver_map =
1830 ComputeTransitionedMap(receiver_map, store_mode); 1830 ComputeTransitionedMap(receiver_map, store_mode);
1831 } 1831 }
1832 if ((receiver_map.is_identical_to(previous_receiver_map) && 1832 if ((receiver_map.is_identical_to(previous_receiver_map) &&
1833 IsTransitionStoreMode(store_mode)) || 1833 IsTransitionStoreMode(store_mode)) ||
1834 IsTransitionOfMonomorphicTarget(*previous_receiver_map, 1834 IsTransitionOfMonomorphicTarget(*previous_receiver_map,
1835 *transitioned_receiver_map)) { 1835 *transitioned_receiver_map)) {
1836 // If the "old" and "new" maps are in the same elements map family, or 1836 // If the "old" and "new" maps are in the same elements map family, or
1837 // if they at least come from the same origin for a transitioning store, 1837 // if they at least come from the same origin for a transitioning store,
1838 // stay MONOMORPHIC and use the map for the most generic ElementsKind. 1838 // stay MONOMORPHIC and use the map for the most generic ElementsKind.
1839 store_mode = GetNonTransitioningStoreMode(store_mode); 1839 store_mode = GetNonTransitioningStoreMode(store_mode);
1840 return PropertyICCompiler::ComputeKeyedStoreMonomorphic( 1840 return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
1841 transitioned_receiver_map, strict_mode(), store_mode); 1841 transitioned_receiver_map, language_mode(), store_mode);
1842 } else if (*previous_receiver_map == receiver->map() && 1842 } else if (*previous_receiver_map == receiver->map() &&
1843 old_store_mode == STANDARD_STORE && 1843 old_store_mode == STANDARD_STORE &&
1844 (store_mode == STORE_AND_GROW_NO_TRANSITION || 1844 (store_mode == STORE_AND_GROW_NO_TRANSITION ||
1845 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || 1845 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS ||
1846 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { 1846 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) {
1847 // A "normal" IC that handles stores can switch to a version that can 1847 // A "normal" IC that handles stores can switch to a version that can
1848 // grow at the end of the array, handle OOB accesses or copy COW arrays 1848 // grow at the end of the array, handle OOB accesses or copy COW arrays
1849 // and still stay MONOMORPHIC. 1849 // and still stay MONOMORPHIC.
1850 return PropertyICCompiler::ComputeKeyedStoreMonomorphic( 1850 return PropertyICCompiler::ComputeKeyedStoreMonomorphic(
1851 receiver_map, strict_mode(), store_mode); 1851 receiver_map, language_mode(), store_mode);
1852 } 1852 }
1853 } 1853 }
1854 1854
1855 DCHECK(state() != GENERIC); 1855 DCHECK(state() != GENERIC);
1856 1856
1857 bool map_added = 1857 bool map_added =
1858 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); 1858 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
1859 1859
1860 if (IsTransitionStoreMode(store_mode)) { 1860 if (IsTransitionStoreMode(store_mode)) {
1861 Handle<Map> transitioned_receiver_map = 1861 Handle<Map> transitioned_receiver_map =
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1902 } 1902 }
1903 if (external_arrays != 0 && 1903 if (external_arrays != 0 &&
1904 external_arrays != target_receiver_maps.length()) { 1904 external_arrays != target_receiver_maps.length()) {
1905 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", 1905 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC",
1906 "unsupported combination of external and normal arrays"); 1906 "unsupported combination of external and normal arrays");
1907 return megamorphic_stub(); 1907 return megamorphic_stub();
1908 } 1908 }
1909 } 1909 }
1910 1910
1911 return PropertyICCompiler::ComputeKeyedStorePolymorphic( 1911 return PropertyICCompiler::ComputeKeyedStorePolymorphic(
1912 &target_receiver_maps, store_mode, strict_mode()); 1912 &target_receiver_maps, store_mode, language_mode());
1913 } 1913 }
1914 1914
1915 1915
1916 Handle<Map> KeyedStoreIC::ComputeTransitionedMap( 1916 Handle<Map> KeyedStoreIC::ComputeTransitionedMap(
1917 Handle<Map> map, KeyedAccessStoreMode store_mode) { 1917 Handle<Map> map, KeyedAccessStoreMode store_mode) {
1918 switch (store_mode) { 1918 switch (store_mode) {
1919 case STORE_TRANSITION_SMI_TO_OBJECT: 1919 case STORE_TRANSITION_SMI_TO_OBJECT:
1920 case STORE_TRANSITION_DOUBLE_TO_OBJECT: 1920 case STORE_TRANSITION_DOUBLE_TO_OBJECT:
1921 case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT: 1921 case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT:
1922 case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT: 1922 case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT:
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2032 2032
2033 MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object, 2033 MaybeHandle<Object> KeyedStoreIC::Store(Handle<Object> object,
2034 Handle<Object> key, 2034 Handle<Object> key,
2035 Handle<Object> value) { 2035 Handle<Object> value) {
2036 // TODO(verwaest): Let SetProperty do the migration, since storing a property 2036 // TODO(verwaest): Let SetProperty do the migration, since storing a property
2037 // might deprecate the current map again, if value does not fit. 2037 // might deprecate the current map again, if value does not fit.
2038 if (MigrateDeprecated(object)) { 2038 if (MigrateDeprecated(object)) {
2039 Handle<Object> result; 2039 Handle<Object> result;
2040 ASSIGN_RETURN_ON_EXCEPTION( 2040 ASSIGN_RETURN_ON_EXCEPTION(
2041 isolate(), result, Runtime::SetObjectProperty(isolate(), object, key, 2041 isolate(), result, Runtime::SetObjectProperty(isolate(), object, key,
2042 value, strict_mode()), 2042 value, language_mode()),
2043 Object); 2043 Object);
2044 return result; 2044 return result;
2045 } 2045 }
2046 2046
2047 // Check for non-string values that can be converted into an 2047 // Check for non-string values that can be converted into an
2048 // internalized string directly or is representable as a smi. 2048 // internalized string directly or is representable as a smi.
2049 key = TryConvertKey(key, isolate()); 2049 key = TryConvertKey(key, isolate());
2050 2050
2051 Handle<Object> store_handle; 2051 Handle<Object> store_handle;
2052 Handle<Code> stub = megamorphic_stub(); 2052 Handle<Code> stub = megamorphic_stub();
(...skipping 29 matching lines...) Expand all
2082 } 2082 }
2083 2083
2084 if (use_ic) { 2084 if (use_ic) {
2085 DCHECK(!object->IsAccessCheckNeeded()); 2085 DCHECK(!object->IsAccessCheckNeeded());
2086 2086
2087 if (object->IsJSObject()) { 2087 if (object->IsJSObject()) {
2088 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 2088 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
2089 bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null(); 2089 bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null();
2090 if (receiver->elements()->map() == 2090 if (receiver->elements()->map() ==
2091 isolate()->heap()->sloppy_arguments_elements_map()) { 2091 isolate()->heap()->sloppy_arguments_elements_map()) {
2092 if (strict_mode() == SLOPPY) { 2092 if (is_sloppy(language_mode())) {
2093 stub = sloppy_arguments_stub(); 2093 stub = sloppy_arguments_stub();
2094 } else { 2094 } else {
2095 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver"); 2095 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "arguments receiver");
2096 } 2096 }
2097 } else if (key_is_smi_like && 2097 } else if (key_is_smi_like &&
2098 !(target().is_identical_to(sloppy_arguments_stub()))) { 2098 !(target().is_identical_to(sloppy_arguments_stub()))) {
2099 // We should go generic if receiver isn't a dictionary, but our 2099 // We should go generic if receiver isn't a dictionary, but our
2100 // prototype chain does have dictionary elements. This ensures that 2100 // prototype chain does have dictionary elements. This ensures that
2101 // other non-dictionary receivers in the polymorphic case benefit 2101 // other non-dictionary receivers in the polymorphic case benefit
2102 // from fast path keyed stores. 2102 // from fast path keyed stores.
2103 if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) { 2103 if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) {
2104 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value); 2104 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value);
2105 stub = StoreElementStub(receiver, store_mode); 2105 stub = StoreElementStub(receiver, store_mode);
2106 } else { 2106 } else {
2107 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "dictionary prototype"); 2107 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "dictionary prototype");
2108 } 2108 }
2109 } else { 2109 } else {
2110 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-smi-like key"); 2110 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-smi-like key");
2111 } 2111 }
2112 } else { 2112 } else {
2113 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-JSObject receiver"); 2113 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "non-JSObject receiver");
2114 } 2114 }
2115 } 2115 }
2116 2116
2117 if (store_handle.is_null()) { 2117 if (store_handle.is_null()) {
2118 ASSIGN_RETURN_ON_EXCEPTION( 2118 ASSIGN_RETURN_ON_EXCEPTION(
2119 isolate(), store_handle, 2119 isolate(), store_handle,
2120 Runtime::SetObjectProperty(isolate(), object, key, value, 2120 Runtime::SetObjectProperty(isolate(), object, key, value,
2121 strict_mode()), 2121 language_mode()),
2122 Object); 2122 Object);
2123 } 2123 }
2124 2124
2125 DCHECK(!is_target_set()); 2125 DCHECK(!is_target_set());
2126 Code* megamorphic = *megamorphic_stub(); 2126 Code* megamorphic = *megamorphic_stub();
2127 if (*stub == megamorphic) { 2127 if (*stub == megamorphic) {
2128 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic"); 2128 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic");
2129 } 2129 }
2130 if (*stub == *slow_stub()) { 2130 if (*stub == *slow_stub()) {
2131 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub"); 2131 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "slow stub");
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
2441 } 2441 }
2442 2442
2443 2443
2444 RUNTIME_FUNCTION(StoreIC_Slow) { 2444 RUNTIME_FUNCTION(StoreIC_Slow) {
2445 HandleScope scope(isolate); 2445 HandleScope scope(isolate);
2446 DCHECK(args.length() == 3); 2446 DCHECK(args.length() == 3);
2447 StoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2447 StoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2448 Handle<Object> object = args.at<Object>(0); 2448 Handle<Object> object = args.at<Object>(0);
2449 Handle<Object> key = args.at<Object>(1); 2449 Handle<Object> key = args.at<Object>(1);
2450 Handle<Object> value = args.at<Object>(2); 2450 Handle<Object> value = args.at<Object>(2);
2451 StrictMode strict_mode = ic.strict_mode(); 2451 LanguageMode language_mode = ic.language_mode();
2452 Handle<Object> result; 2452 Handle<Object> result;
2453 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2453 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2454 isolate, result, 2454 isolate, result,
2455 Runtime::SetObjectProperty(isolate, object, key, value, strict_mode)); 2455 Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
2456 return *result; 2456 return *result;
2457 } 2457 }
2458 2458
2459 2459
2460 RUNTIME_FUNCTION(KeyedStoreIC_Slow) { 2460 RUNTIME_FUNCTION(KeyedStoreIC_Slow) {
2461 HandleScope scope(isolate); 2461 HandleScope scope(isolate);
2462 DCHECK(args.length() == 3); 2462 DCHECK(args.length() == 3);
2463 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate); 2463 KeyedStoreIC ic(IC::NO_EXTRA_FRAME, isolate);
2464 Handle<Object> object = args.at<Object>(0); 2464 Handle<Object> object = args.at<Object>(0);
2465 Handle<Object> key = args.at<Object>(1); 2465 Handle<Object> key = args.at<Object>(1);
2466 Handle<Object> value = args.at<Object>(2); 2466 Handle<Object> value = args.at<Object>(2);
2467 StrictMode strict_mode = ic.strict_mode(); 2467 LanguageMode language_mode = ic.language_mode();
2468 Handle<Object> result; 2468 Handle<Object> result;
2469 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2469 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2470 isolate, result, 2470 isolate, result,
2471 Runtime::SetObjectProperty(isolate, object, key, value, strict_mode)); 2471 Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
2472 return *result; 2472 return *result;
2473 } 2473 }
2474 2474
2475 2475
2476 RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss) { 2476 RUNTIME_FUNCTION(ElementsTransitionAndStoreIC_Miss) {
2477 TimerEventScope<TimerEventIcMiss> timer(isolate); 2477 TimerEventScope<TimerEventIcMiss> timer(isolate);
2478 HandleScope scope(isolate); 2478 HandleScope scope(isolate);
2479 DCHECK(args.length() == 4); 2479 DCHECK(args.length() == 4);
2480 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate); 2480 KeyedStoreIC ic(IC::EXTRA_CALL_FRAME, isolate);
2481 Handle<Object> value = args.at<Object>(0); 2481 Handle<Object> value = args.at<Object>(0);
2482 Handle<Map> map = args.at<Map>(1); 2482 Handle<Map> map = args.at<Map>(1);
2483 Handle<Object> key = args.at<Object>(2); 2483 Handle<Object> key = args.at<Object>(2);
2484 Handle<Object> object = args.at<Object>(3); 2484 Handle<Object> object = args.at<Object>(3);
2485 StrictMode strict_mode = ic.strict_mode(); 2485 LanguageMode language_mode = ic.language_mode();
2486 if (object->IsJSObject()) { 2486 if (object->IsJSObject()) {
2487 JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), 2487 JSObject::TransitionElementsKind(Handle<JSObject>::cast(object),
2488 map->elements_kind()); 2488 map->elements_kind());
2489 } 2489 }
2490 Handle<Object> result; 2490 Handle<Object> result;
2491 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2491 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2492 isolate, result, 2492 isolate, result,
2493 Runtime::SetObjectProperty(isolate, object, key, value, strict_mode)); 2493 Runtime::SetObjectProperty(isolate, object, key, value, language_mode));
2494 return *result; 2494 return *result;
2495 } 2495 }
2496 2496
2497 2497
2498 MaybeHandle<Object> BinaryOpIC::Transition( 2498 MaybeHandle<Object> BinaryOpIC::Transition(
2499 Handle<AllocationSite> allocation_site, Handle<Object> left, 2499 Handle<AllocationSite> allocation_site, Handle<Object> left,
2500 Handle<Object> right) { 2500 Handle<Object> right) {
2501 BinaryOpICState state(isolate(), target()->extra_ic_state()); 2501 BinaryOpICState state(isolate(), target()->extra_ic_state());
2502 2502
2503 // Compute the actual result using the builtin for the binary operation. 2503 // Compute the actual result using the builtin for the binary operation.
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
2934 Handle<JSObject>::cast(current)->HasNamedInterceptor()) { 2934 Handle<JSObject>::cast(current)->HasNamedInterceptor()) {
2935 found = true; 2935 found = true;
2936 break; 2936 break;
2937 } 2937 }
2938 } 2938 }
2939 DCHECK(found); 2939 DCHECK(found);
2940 #endif 2940 #endif
2941 Handle<Object> result; 2941 Handle<Object> result;
2942 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( 2942 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
2943 isolate, result, 2943 isolate, result,
2944 JSObject::SetProperty(receiver, name, value, ic.strict_mode())); 2944 JSObject::SetProperty(receiver, name, value, ic.language_mode()));
2945 return *result; 2945 return *result;
2946 } 2946 }
2947 2947
2948 2948
2949 RUNTIME_FUNCTION(LoadElementWithInterceptor) { 2949 RUNTIME_FUNCTION(LoadElementWithInterceptor) {
2950 HandleScope scope(isolate); 2950 HandleScope scope(isolate);
2951 Handle<JSObject> receiver = args.at<JSObject>(0); 2951 Handle<JSObject> receiver = args.at<JSObject>(0);
2952 DCHECK(args.smi_at(1) >= 0); 2952 DCHECK(args.smi_at(1) >= 0);
2953 uint32_t index = args.smi_at(1); 2953 uint32_t index = args.smi_at(1);
2954 Handle<Object> result; 2954 Handle<Object> result;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3002 static const Address IC_utilities[] = { 3002 static const Address IC_utilities[] = {
3003 #define ADDR(name) FUNCTION_ADDR(name), 3003 #define ADDR(name) FUNCTION_ADDR(name),
3004 IC_UTIL_LIST(ADDR) NULL 3004 IC_UTIL_LIST(ADDR) NULL
3005 #undef ADDR 3005 #undef ADDR
3006 }; 3006 };
3007 3007
3008 3008
3009 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; } 3009 Address IC::AddressFromUtilityId(IC::UtilityId id) { return IC_utilities[id]; }
3010 } 3010 }
3011 } // namespace v8::internal 3011 } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic/ic.h ('k') | src/ic/ic-compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698