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

Side by Side Diff: src/ic.cc

Issue 12057003: Merge UpdateStoreCaches into a single function dispatching on ComputeStoreMonorphic and UpdateMegam… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | no next file » | 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 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 945 matching lines...) Expand 10 before | Expand all | Expand 10 after
956 return ReferenceError("not_defined", name); 956 return ReferenceError("not_defined", name);
957 } 957 }
958 return *result; 958 return *result;
959 } 959 }
960 960
961 // Get the property. 961 // Get the property.
962 return object->GetProperty(*object, &lookup, *name, &attr); 962 return object->GetProperty(*object, &lookup, *name, &attr);
963 } 963 }
964 964
965 965
966 void LoadIC::UpdateCaches(LookupResult* lookup, 966 void IC::PatchCache(State state,
967 State state, 967 StrictModeFlag strict_mode,
968 Handle<Object> object, 968 Handle<JSObject> receiver,
969 Handle<String> name) { 969 Handle<String> name,
970 // Bail out if the result is not cacheable. 970 Handle<Code> code) {
971 if (!lookup->IsCacheable()) return;
972
973 // Loading properties from values is not common, so don't try to
974 // deal with non-JS objects here.
975 if (!object->IsJSObject()) return;
976
977 if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return;
978
979 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
980 Handle<Code> code;
981 if (state == UNINITIALIZED) {
982 // This is the first time we execute this inline cache.
983 // Set the target to the pre monomorphic stub to delay
984 // setting the monomorphic state.
985 code = pre_monomorphic_stub();
986 } else {
987 code = ComputeLoadMonomorphic(lookup, receiver, name);
988 if (code.is_null()) return;
989 }
990
991 // Patch the call site depending on the state of the cache.
992 switch (state) { 971 switch (state) {
993 case UNINITIALIZED: 972 case UNINITIALIZED:
994 case PREMONOMORPHIC: 973 case PREMONOMORPHIC:
995 case MONOMORPHIC_PROTOTYPE_FAILURE: 974 case MONOMORPHIC_PROTOTYPE_FAILURE:
975 case POLYMORPHIC:
996 set_target(*code); 976 set_target(*code);
997 break; 977 break;
998 case MONOMORPHIC: 978 case MONOMORPHIC:
979 // Only move to megamorphic if the target changes.
999 if (target() != *code) { 980 if (target() != *code) {
1000 // We are transitioning from monomorphic to megamorphic case. 981 // We are transitioning from monomorphic to megamorphic case.
1001 // Place the current monomorphic stub and stub compiled for 982 // Place the current monomorphic stub and stub compiled for
1002 // the receiver into stub cache. 983 // the receiver into stub cache.
1003 Map* map = target()->FindFirstMap(); 984 Map* map = target()->FindFirstMap();
1004 if (map != NULL) { 985 if (map != NULL) {
1005 UpdateMegamorphicCache(map, *name, target()); 986 UpdateMegamorphicCache(map, *name, target());
1006 } 987 }
1007 UpdateMegamorphicCache(receiver->map(), *name, *code); 988 UpdateMegamorphicCache(receiver->map(), *name, *code);
1008 set_target(*megamorphic_stub()); 989 set_target((strict_mode == kStrictMode)
990 ? *megamorphic_stub_strict()
991 : *megamorphic_stub());
1009 } 992 }
1010 break; 993 break;
1011 case MEGAMORPHIC: 994 case MEGAMORPHIC:
995 // Update the stub cache.
1012 UpdateMegamorphicCache(receiver->map(), *name, *code); 996 UpdateMegamorphicCache(receiver->map(), *name, *code);
1013 break; 997 break;
998 case GENERIC:
1014 case DEBUG_STUB: 999 case DEBUG_STUB:
1015 break; 1000 break;
1016 case POLYMORPHIC: 1001 }
1017 case GENERIC: 1002 }
1018 UNREACHABLE(); 1003
1019 break; 1004
1005 void LoadIC::UpdateCaches(LookupResult* lookup,
1006 State state,
1007 Handle<Object> object,
1008 Handle<String> name) {
1009 // Bail out if the result is not cacheable.
1010 if (!lookup->IsCacheable()) return;
1011
1012 // Loading properties from values is not common, so don't try to
1013 // deal with non-JS objects here.
1014 if (!object->IsJSObject()) return;
1015
1016 if (HasNormalObjectsInPrototypeChain(isolate(), lookup, *object)) return;
1017
1018 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1019 Handle<Code> code;
1020 if (state == UNINITIALIZED) {
1021 // This is the first time we execute this inline cache.
1022 // Set the target to the pre monomorphic stub to delay
1023 // setting the monomorphic state.
1024 code = pre_monomorphic_stub();
1025 } else {
1026 code = ComputeLoadMonomorphic(lookup, receiver, name);
1027 if (code.is_null()) return;
1020 } 1028 }
1021 1029
1030 PatchCache(state, kNonStrictMode, receiver, name, code);
1022 TRACE_IC("LoadIC", name, state, target()); 1031 TRACE_IC("LoadIC", name, state, target());
1023 } 1032 }
1024 1033
1025 1034
1026 void LoadIC::UpdateMegamorphicCache(Map* map, String* name, Code* code) { 1035 void IC::UpdateMegamorphicCache(Map* map, String* name, Code* code) {
1027 // Cache code holding map should be consistent with 1036 // Cache code holding map should be consistent with
1028 // GenerateMonomorphicCacheProbe. 1037 // GenerateMonomorphicCacheProbe.
1029 isolate()->stub_cache()->Set(name, map, code); 1038 isolate()->stub_cache()->Set(name, map, code);
1030 } 1039 }
1031 1040
1032 1041
1033 Handle<Code> LoadIC::ComputeLoadMonomorphic(LookupResult* lookup, 1042 Handle<Code> LoadIC::ComputeLoadMonomorphic(LookupResult* lookup,
1034 Handle<JSObject> receiver, 1043 Handle<JSObject> receiver,
1035 Handle<String> name) { 1044 Handle<String> name) {
1036 if (!lookup->IsProperty()) { 1045 if (!lookup->IsProperty()) {
(...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after
1417 : global_proxy_stub(); 1426 : global_proxy_stub();
1418 set_target(*stub); 1427 set_target(*stub);
1419 TRACE_IC("StoreIC", name, state, *stub); 1428 TRACE_IC("StoreIC", name, state, *stub);
1420 } 1429 }
1421 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); 1430 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
1422 } 1431 }
1423 1432
1424 LookupResult lookup(isolate()); 1433 LookupResult lookup(isolate());
1425 if (LookupForWrite(receiver, name, &lookup)) { 1434 if (LookupForWrite(receiver, name, &lookup)) {
1426 if (FLAG_use_ic) { 1435 if (FLAG_use_ic) {
1427 UpdateStoreCaches(&lookup, state, strict_mode, receiver, name, value); 1436 UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
1428 } 1437 }
1429 } else if (strict_mode == kStrictMode && 1438 } else if (strict_mode == kStrictMode &&
1430 !(lookup.IsProperty() && lookup.IsReadOnly()) && 1439 !(lookup.IsProperty() && lookup.IsReadOnly()) &&
1431 IsUndeclaredGlobal(object)) { 1440 IsUndeclaredGlobal(object)) {
1432 // Strict mode doesn't allow setting non-existent global property. 1441 // Strict mode doesn't allow setting non-existent global property.
1433 return ReferenceError("not_defined", name); 1442 return ReferenceError("not_defined", name);
1434 } 1443 }
1435 1444
1436 // Set the property. 1445 // Set the property.
1437 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode); 1446 return receiver->SetProperty(*name, *value, NONE, strict_mode, store_mode);
1438 } 1447 }
1439 1448
1440 1449
1441 void StoreIC::UpdateStoreCaches(LookupResult* lookup, 1450 void StoreIC::UpdateCaches(LookupResult* lookup,
1442 State state, 1451 State state,
1443 StrictModeFlag strict_mode, 1452 StrictModeFlag strict_mode,
1444 Handle<JSObject> receiver, 1453 Handle<JSObject> receiver,
1445 Handle<String> name, 1454 Handle<String> name,
1446 Handle<Object> value) { 1455 Handle<Object> value) {
1447 ASSERT(!receiver->IsJSGlobalProxy()); 1456 ASSERT(!receiver->IsJSGlobalProxy());
1448 ASSERT(StoreICableLookup(lookup)); 1457 ASSERT(StoreICableLookup(lookup));
1449 ASSERT(lookup->IsFound()); 1458 ASSERT(lookup->IsFound());
1450 1459
1451 // These are not cacheable, so we never see such LookupResults here. 1460 // These are not cacheable, so we never see such LookupResults here.
1452 ASSERT(!lookup->IsHandler()); 1461 ASSERT(!lookup->IsHandler());
1453 1462
1454 // If the property has a non-field type allowing map transitions 1463 Handle<Code> code =
1455 // where there is extra room in the object, we leave the IC in its 1464 ComputeStoreMonomorphic(lookup, strict_mode, receiver, name);
1456 // current state. 1465 if (code.is_null()) return;
1457 PropertyType type = lookup->type();
1458 1466
1459 // Compute the code stub for this store; used for rewriting to 1467 PatchCache(state, strict_mode, receiver, name, code);
1460 // monomorphic state and making sure that the code stub is in the 1468 TRACE_IC("StoreIC", name, state, target());
1461 // stub cache. 1469 }
1470
1471
1472 Handle<Code> StoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
1473 StrictModeFlag strict_mode,
1474 Handle<JSObject> receiver,
1475 Handle<String> name) {
1462 Handle<JSObject> holder(lookup->holder()); 1476 Handle<JSObject> holder(lookup->holder());
1463 Handle<Code> code; 1477 switch (lookup->type()) {
1464 switch (type) {
1465 case FIELD: 1478 case FIELD:
1466 code = isolate()->stub_cache()->ComputeStoreField( 1479 return isolate()->stub_cache()->ComputeStoreField(
1467 name, receiver, lookup->GetFieldIndex().field_index(), 1480 name, receiver, lookup->GetFieldIndex().field_index(),
1468 Handle<Map>::null(), strict_mode); 1481 Handle<Map>::null(), strict_mode);
1469 break;
1470 case NORMAL: 1482 case NORMAL:
1471 if (receiver->IsGlobalObject()) { 1483 if (receiver->IsGlobalObject()) {
1472 // The stub generated for the global object picks the value directly 1484 // The stub generated for the global object picks the value directly
1473 // from the property cell. So the property must be directly on the 1485 // from the property cell. So the property must be directly on the
1474 // global object. 1486 // global object.
1475 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); 1487 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
1476 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup)); 1488 Handle<JSGlobalPropertyCell> cell(global->GetPropertyCell(lookup));
1477 code = isolate()->stub_cache()->ComputeStoreGlobal( 1489 return isolate()->stub_cache()->ComputeStoreGlobal(
1478 name, global, cell, strict_mode); 1490 name, global, cell, strict_mode);
1479 } else {
1480 if (!holder.is_identical_to(receiver)) return;
1481 code = isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
1482 } 1491 }
1483 break; 1492 if (!holder.is_identical_to(receiver)) break;
1493 return isolate()->stub_cache()->ComputeStoreNormal(strict_mode);
1484 case CALLBACKS: { 1494 case CALLBACKS: {
1485 Handle<Object> callback(lookup->GetCallbackObject()); 1495 Handle<Object> callback(lookup->GetCallbackObject());
1486 if (callback->IsAccessorInfo()) { 1496 if (callback->IsAccessorInfo()) {
1487 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback); 1497 Handle<AccessorInfo> info = Handle<AccessorInfo>::cast(callback);
1488 if (v8::ToCData<Address>(info->setter()) == 0) return; 1498 if (v8::ToCData<Address>(info->setter()) == 0) break;
1489 if (!holder->HasFastProperties()) return; 1499 if (!holder->HasFastProperties()) break;
1490 if (!info->IsCompatibleReceiver(*receiver)) return; 1500 if (!info->IsCompatibleReceiver(*receiver)) break;
1491 code = isolate()->stub_cache()->ComputeStoreCallback( 1501 return isolate()->stub_cache()->ComputeStoreCallback(
1492 name, receiver, holder, info, strict_mode); 1502 name, receiver, holder, info, strict_mode);
1493 } else if (callback->IsAccessorPair()) { 1503 } else if (callback->IsAccessorPair()) {
1494 Handle<Object> setter(Handle<AccessorPair>::cast(callback)->setter()); 1504 Handle<Object> setter(Handle<AccessorPair>::cast(callback)->setter());
1495 if (!setter->IsJSFunction()) return; 1505 if (!setter->IsJSFunction()) break;
1496 if (holder->IsGlobalObject()) return; 1506 if (holder->IsGlobalObject()) break;
1497 if (!holder->HasFastProperties()) return; 1507 if (!holder->HasFastProperties()) break;
1498 code = isolate()->stub_cache()->ComputeStoreViaSetter( 1508 return isolate()->stub_cache()->ComputeStoreViaSetter(
1499 name, receiver, holder, Handle<JSFunction>::cast(setter), 1509 name, receiver, holder, Handle<JSFunction>::cast(setter),
1500 strict_mode); 1510 strict_mode);
1501 } else {
1502 ASSERT(callback->IsForeign());
1503 // No IC support for old-style native accessors.
1504 return;
1505 } 1511 }
1512 ASSERT(callback->IsForeign());
1513 // No IC support for old-style native accessors.
1506 break; 1514 break;
1507 } 1515 }
1508 case INTERCEPTOR: 1516 case INTERCEPTOR:
1509 ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined()); 1517 ASSERT(!receiver->GetNamedInterceptor()->setter()->IsUndefined());
1510 code = isolate()->stub_cache()->ComputeStoreInterceptor( 1518 return isolate()->stub_cache()->ComputeStoreInterceptor(
1511 name, receiver, strict_mode); 1519 name, receiver, strict_mode);
1520 case CONSTANT_FUNCTION:
1512 break; 1521 break;
1513 case CONSTANT_FUNCTION:
1514 return;
1515 case TRANSITION: { 1522 case TRANSITION: {
1516 Handle<Map> transition(lookup->GetTransitionTarget()); 1523 Handle<Map> transition(lookup->GetTransitionTarget());
1517 int descriptor = transition->LastAdded(); 1524 int descriptor = transition->LastAdded();
1518 1525
1519 DescriptorArray* target_descriptors = transition->instance_descriptors(); 1526 DescriptorArray* target_descriptors = transition->instance_descriptors();
1520 PropertyDetails details = target_descriptors->GetDetails(descriptor); 1527 PropertyDetails details = target_descriptors->GetDetails(descriptor);
1521 1528
1522 if (details.type() != FIELD || details.attributes() != NONE) return; 1529 if (details.type() != FIELD || details.attributes() != NONE) break;
1523 1530
1524 int field_index = target_descriptors->GetFieldIndex(descriptor); 1531 int field_index = target_descriptors->GetFieldIndex(descriptor);
1525 code = isolate()->stub_cache()->ComputeStoreField( 1532 return isolate()->stub_cache()->ComputeStoreField(
1526 name, receiver, field_index, transition, strict_mode); 1533 name, receiver, field_index, transition, strict_mode);
1527
1528 break;
1529 } 1534 }
1530 case NONEXISTENT: 1535 case NONEXISTENT:
1531 case HANDLER: 1536 case HANDLER:
1532 UNREACHABLE(); 1537 UNREACHABLE();
1533 return;
1534 }
1535
1536 // Patch the call site depending on the state of the cache.
1537 switch (state) {
1538 case UNINITIALIZED:
1539 case PREMONOMORPHIC:
1540 case MONOMORPHIC_PROTOTYPE_FAILURE:
1541 set_target(*code);
1542 break;
1543 case MONOMORPHIC:
1544 // Only move to megamorphic if the target changes.
1545 if (target() != *code) {
1546 // We are transitioning from monomorphic to megamorphic case.
1547 // Place the current monomorphic stub and stub compiled for
1548 // the receiver into stub cache.
1549 Map* map = target()->FindFirstMap();
1550 if (map != NULL) {
1551 isolate()->stub_cache()->Set(*name, map, target());
1552 }
1553 isolate()->stub_cache()->Set(*name, receiver->map(), *code);
1554 set_target((strict_mode == kStrictMode)
1555 ? *megamorphic_stub_strict()
1556 : *megamorphic_stub());
1557 }
1558 break;
1559 case MEGAMORPHIC:
1560 // Update the stub cache.
1561 isolate()->stub_cache()->Set(*name, receiver->map(), *code);
1562 break;
1563 case DEBUG_STUB:
1564 break;
1565 case POLYMORPHIC:
1566 case GENERIC:
1567 UNREACHABLE();
1568 break; 1538 break;
1569 } 1539 }
1570 1540 return Handle<Code>::null();
1571 TRACE_IC("StoreIC", name, state, target());
1572 } 1541 }
1573 1542
1574 1543
1575 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver, 1544 Handle<Code> KeyedStoreIC::StoreElementStub(Handle<JSObject> receiver,
1576 StubKind stub_kind, 1545 StubKind stub_kind,
1577 StrictModeFlag strict_mode) { 1546 StrictModeFlag strict_mode) {
1578 State ic_state = target()->ic_state(); 1547 State ic_state = target()->ic_state();
1579 KeyedAccessGrowMode grow_mode = IsGrowStubKind(stub_kind) 1548 KeyedAccessGrowMode grow_mode = IsGrowStubKind(stub_kind)
1580 ? ALLOW_JSARRAY_GROWTH 1549 ? ALLOW_JSARRAY_GROWTH
1581 : DO_NOT_ALLOW_JSARRAY_GROWTH; 1550 : DO_NOT_ALLOW_JSARRAY_GROWTH;
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1797 } 1766 }
1798 1767
1799 TRACE_IC("KeyedStoreIC", key, state, target()); 1768 TRACE_IC("KeyedStoreIC", key, state, target());
1800 1769
1801 // Set the property. 1770 // Set the property.
1802 return Runtime::SetObjectProperty( 1771 return Runtime::SetObjectProperty(
1803 isolate(), object , key, value, NONE, strict_mode); 1772 isolate(), object , key, value, NONE, strict_mode);
1804 } 1773 }
1805 1774
1806 1775
1807 void KeyedStoreIC::UpdateStoreCaches(LookupResult* lookup, 1776 Handle<Code> KeyedStoreIC::ComputeStoreMonomorphic(LookupResult* lookup,
1808 State state, 1777 StrictModeFlag strict_mode,
1809 StrictModeFlag strict_mode, 1778 Handle<JSObject> receiver,
1810 Handle<JSObject> receiver, 1779 Handle<String> name) {
1811 Handle<String> name,
1812 Handle<Object> value) {
1813 ASSERT(!receiver->IsJSGlobalProxy());
1814 ASSERT(StoreICableLookup(lookup));
1815 ASSERT(lookup->IsFound());
1816
1817 // These are not cacheable, so we never see such LookupResults here.
1818 ASSERT(!lookup->IsHandler());
1819
1820 // If the property has a non-field type allowing map transitions 1780 // If the property has a non-field type allowing map transitions
1821 // where there is extra room in the object, we leave the IC in its 1781 // where there is extra room in the object, we leave the IC in its
1822 // current state. 1782 // current state.
1823 PropertyType type = lookup->type(); 1783 switch (lookup->type()) {
1824
1825 // Compute the code stub for this store; used for rewriting to
1826 // monomorphic state and making sure that the code stub is in the
1827 // stub cache.
1828 Handle<Code> code;
1829
1830 switch (type) {
1831 case FIELD: 1784 case FIELD:
1832 code = isolate()->stub_cache()->ComputeKeyedStoreField( 1785 return isolate()->stub_cache()->ComputeKeyedStoreField(
1833 name, receiver, lookup->GetFieldIndex().field_index(), 1786 name, receiver, lookup->GetFieldIndex().field_index(),
1834 Handle<Map>::null(), strict_mode); 1787 Handle<Map>::null(), strict_mode);
1835 break;
1836 case TRANSITION: { 1788 case TRANSITION: {
1837 Handle<Map> transition(lookup->GetTransitionTarget()); 1789 Handle<Map> transition(lookup->GetTransitionTarget());
1838 int descriptor = transition->LastAdded(); 1790 int descriptor = transition->LastAdded();
1839 1791
1840 DescriptorArray* target_descriptors = transition->instance_descriptors(); 1792 DescriptorArray* target_descriptors = transition->instance_descriptors();
1841 PropertyDetails details = target_descriptors->GetDetails(descriptor); 1793 PropertyDetails details = target_descriptors->GetDetails(descriptor);
1842 1794
1843 if (details.type() == FIELD && details.attributes() == NONE) { 1795 if (details.type() == FIELD && details.attributes() == NONE) {
1844 int field_index = target_descriptors->GetFieldIndex(descriptor); 1796 int field_index = target_descriptors->GetFieldIndex(descriptor);
1845 code = isolate()->stub_cache()->ComputeKeyedStoreField( 1797 return isolate()->stub_cache()->ComputeKeyedStoreField(
1846 name, receiver, field_index, transition, strict_mode); 1798 name, receiver, field_index, transition, strict_mode);
1847 break;
1848 } 1799 }
1849 // fall through. 1800 // fall through.
1850 } 1801 }
1851 case NORMAL: 1802 case NORMAL:
1852 case CONSTANT_FUNCTION: 1803 case CONSTANT_FUNCTION:
1853 case CALLBACKS: 1804 case CALLBACKS:
1854 case INTERCEPTOR: 1805 case INTERCEPTOR:
1855 // Always rewrite to the generic case so that we do not 1806 // Always rewrite to the generic case so that we do not
1856 // repeatedly try to rewrite. 1807 // repeatedly try to rewrite.
1857 code = (strict_mode == kStrictMode) 1808 return (strict_mode == kStrictMode)
1858 ? generic_stub_strict() 1809 ? generic_stub_strict()
1859 : generic_stub(); 1810 : generic_stub();
1860 break;
1861 case HANDLER: 1811 case HANDLER:
1862 case NONEXISTENT: 1812 case NONEXISTENT:
1863 UNREACHABLE(); 1813 UNREACHABLE();
1864 return;
1865 }
1866
1867 ASSERT(!code.is_null());
1868
1869 // Patch the call site depending on the state of the cache.
1870 switch (state) {
1871 case UNINITIALIZED:
1872 case PREMONOMORPHIC:
1873 case POLYMORPHIC:
1874 set_target(*code);
1875 break;
1876 case MONOMORPHIC:
1877 // Only move to megamorphic if the target changes.
1878 if (target() != *code) {
1879 set_target((strict_mode == kStrictMode)
1880 ? *megamorphic_stub_strict()
1881 : *megamorphic_stub());
1882 }
1883 break;
1884 case MEGAMORPHIC:
1885 case GENERIC:
1886 case DEBUG_STUB:
1887 break;
1888 case MONOMORPHIC_PROTOTYPE_FAILURE:
1889 UNREACHABLE();
1890 break; 1814 break;
1891 } 1815 }
1892 1816 return Handle<Code>::null();
1893 TRACE_IC("KeyedStoreIC", name, state, target());
1894 } 1817 }
1895 1818
1896 1819
1897 #undef TRACE_IC 1820 #undef TRACE_IC
1898 1821
1899 1822
1900 // ---------------------------------------------------------------------------- 1823 // ----------------------------------------------------------------------------
1901 // Static IC stub generators. 1824 // Static IC stub generators.
1902 // 1825 //
1903 1826
(...skipping 731 matching lines...) Expand 10 before | Expand all | Expand 10 after
2635 #undef ADDR 2558 #undef ADDR
2636 }; 2559 };
2637 2560
2638 2561
2639 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2562 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2640 return IC_utilities[id]; 2563 return IC_utilities[id];
2641 } 2564 }
2642 2565
2643 2566
2644 } } // namespace v8::internal 2567 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698