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

Side by Side Diff: src/ic.cc

Issue 8356039: Handlify upper layers of KeyedStoreIC. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address comments, rebase. Created 9 years, 2 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') | src/stub-cache.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 1718 matching lines...) Expand 10 before | Expand all | Expand 10 after
1729 return TypeError("non_object_property_store", object, name); 1729 return TypeError("non_object_property_store", object, name);
1730 } 1730 }
1731 1731
1732 // Ignore stores where the receiver is not a JSObject. 1732 // Ignore stores where the receiver is not a JSObject.
1733 if (!object->IsJSObject()) return *value; 1733 if (!object->IsJSObject()) return *value;
1734 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1734 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1735 1735
1736 // Check if the given name is an array index. 1736 // Check if the given name is an array index.
1737 uint32_t index; 1737 uint32_t index;
1738 if (name->AsArrayIndex(&index)) { 1738 if (name->AsArrayIndex(&index)) {
1739 HandleScope scope(isolate());
1740 Handle<Object> result = SetElement(receiver, index, value, strict_mode); 1739 Handle<Object> result = SetElement(receiver, index, value, strict_mode);
1741 if (result.is_null()) return Failure::Exception(); 1740 RETURN_IF_EMPTY_HANDLE(isolate(), result);
1742 return *value; 1741 return *value;
1743 } 1742 }
1744 1743
1745 // Lookup the property locally in the receiver. 1744 // Lookup the property locally in the receiver.
1746 LookupResult lookup(isolate()); 1745 LookupResult lookup(isolate());
1747 receiver->LocalLookup(*name, &lookup); 1746 receiver->LocalLookup(*name, &lookup);
1748 1747
1749 // Update inline cache and stub cache. 1748 // Update inline cache and stub cache.
1750 if (FLAG_use_ic) { 1749 if (FLAG_use_ic) {
1751 UpdateCaches(&lookup, state, strict_mode, receiver, name, value); 1750 UpdateCaches(&lookup, state, strict_mode, receiver, name, value);
1752 } 1751 }
1753 1752
1754 // Set the property. 1753 // Set the property.
1755 return receiver->SetProperty(*name, *value, NONE, strict_mode); 1754 return receiver->SetProperty(*name, *value, NONE, strict_mode);
1756 } 1755 }
1757 1756
1758 // Do not use ICs for objects that require access checks (including 1757 // Do not use ICs for objects that require access checks (including
1759 // the global object). 1758 // the global object).
1760 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded(); 1759 bool use_ic = FLAG_use_ic && !object->IsAccessCheckNeeded();
1761 ASSERT(!(use_ic && object->IsJSGlobalProxy())); 1760 ASSERT(!(use_ic && object->IsJSGlobalProxy()));
1762 1761
1763 if (use_ic) { 1762 if (use_ic) {
1764 Code* stub = (strict_mode == kStrictMode) 1763 Handle<Code> stub = (strict_mode == kStrictMode)
1765 ? generic_stub_strict() 1764 ? generic_stub_strict()
1766 : generic_stub(); 1765 : generic_stub();
1767 if (object->IsJSObject()) { 1766 if (object->IsJSObject()) {
1768 JSObject* receiver = JSObject::cast(*object); 1767 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1769 Heap* heap = Handle<JSObject>::cast(object)->GetHeap(); 1768 if (receiver->elements()->map() ==
1770 Map* elements_map = Handle<JSObject>::cast(object)->elements()->map(); 1769 isolate()->heap()->non_strict_arguments_elements_map()) {
1771 if (elements_map == heap->non_strict_arguments_elements_map()) {
1772 stub = non_strict_arguments_stub(); 1770 stub = non_strict_arguments_stub();
1773 } else if (!force_generic) { 1771 } else if (!force_generic) {
1774 if (key->IsSmi() && (target() != non_strict_arguments_stub())) { 1772 if (key->IsSmi() && (target() != *non_strict_arguments_stub())) {
1775 StubKind stub_kind = STORE_NO_TRANSITION; 1773 StubKind stub_kind = STORE_NO_TRANSITION;
1776 if (receiver->GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) { 1774 if (receiver->GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) {
1777 if (value->IsHeapNumber()) { 1775 if (value->IsHeapNumber()) {
1778 stub_kind = STORE_TRANSITION_SMI_TO_DOUBLE; 1776 stub_kind = STORE_TRANSITION_SMI_TO_DOUBLE;
1779 } else if (value->IsHeapObject()) { 1777 } else if (value->IsHeapObject()) {
1780 stub_kind = STORE_TRANSITION_SMI_TO_OBJECT; 1778 stub_kind = STORE_TRANSITION_SMI_TO_OBJECT;
1781 } 1779 }
1782 } else if (receiver->GetElementsKind() == FAST_DOUBLE_ELEMENTS) { 1780 } else if (receiver->GetElementsKind() == FAST_DOUBLE_ELEMENTS) {
1783 if (!value->IsSmi() && !value->IsHeapNumber()) { 1781 if (!value->IsSmi() && !value->IsHeapNumber()) {
1784 stub_kind = STORE_TRANSITION_DOUBLE_TO_OBJECT; 1782 stub_kind = STORE_TRANSITION_DOUBLE_TO_OBJECT;
1785 } 1783 }
1786 } 1784 }
1787 HandleScope scope(isolate()); 1785 stub = ComputeStub(receiver, stub_kind, strict_mode, stub);
1788 MaybeObject* maybe_stub = ComputeStub(receiver,
1789 stub_kind,
1790 strict_mode,
1791 stub);
1792 stub = maybe_stub->IsFailure() ?
1793 NULL : Code::cast(maybe_stub->ToObjectUnchecked());
1794 } 1786 }
1795 } 1787 }
1796 } 1788 }
1797 if (stub != NULL) set_target(stub); 1789 if (!stub.is_null()) set_target(*stub);
1798 } 1790 }
1799 1791
1800 #ifdef DEBUG 1792 #ifdef DEBUG
1801 TraceIC("KeyedStoreIC", key, state, target()); 1793 TraceIC("KeyedStoreIC", key, state, target());
1802 #endif 1794 #endif
1803 1795
1804 // Set the property. 1796 // Set the property.
1805 return Runtime::SetObjectProperty( 1797 return Runtime::SetObjectProperty(
1806 isolate(), object , key, value, NONE, strict_mode); 1798 isolate(), object , key, value, NONE, strict_mode);
1807 } 1799 }
(...skipping 16 matching lines...) Expand all
1824 if (lookup->IsReadOnly()) return; 1816 if (lookup->IsReadOnly()) return;
1825 1817
1826 // If the property has a non-field type allowing map transitions 1818 // If the property has a non-field type allowing map transitions
1827 // where there is extra room in the object, we leave the IC in its 1819 // where there is extra room in the object, we leave the IC in its
1828 // current state. 1820 // current state.
1829 PropertyType type = lookup->type(); 1821 PropertyType type = lookup->type();
1830 1822
1831 // Compute the code stub for this store; used for rewriting to 1823 // Compute the code stub for this store; used for rewriting to
1832 // monomorphic state and making sure that the code stub is in the 1824 // monomorphic state and making sure that the code stub is in the
1833 // stub cache. 1825 // stub cache.
1834 MaybeObject* maybe_code = NULL; 1826 Handle<Code> code;
1835 Object* code = NULL;
1836 1827
1837 switch (type) { 1828 switch (type) {
1838 case FIELD: { 1829 case FIELD:
1839 maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField( 1830 code = isolate()->stub_cache()->ComputeKeyedStoreField(
1840 *name, *receiver, lookup->GetFieldIndex(), NULL, strict_mode); 1831 name, receiver, lookup->GetFieldIndex(),
1832 Handle<Map>::null(), strict_mode);
1841 break; 1833 break;
1842 } 1834 case MAP_TRANSITION:
1843 case MAP_TRANSITION: {
1844 if (lookup->GetAttributes() == NONE) { 1835 if (lookup->GetAttributes() == NONE) {
1845 HandleScope scope(isolate());
1846 ASSERT(type == MAP_TRANSITION); 1836 ASSERT(type == MAP_TRANSITION);
1847 Handle<Map> transition(lookup->GetTransitionMap()); 1837 Handle<Map> transition(lookup->GetTransitionMap());
1848 int index = transition->PropertyIndexFor(*name); 1838 int index = transition->PropertyIndexFor(*name);
1849 maybe_code = isolate()->stub_cache()->ComputeKeyedStoreField( 1839 code = isolate()->stub_cache()->ComputeKeyedStoreField(
1850 *name, *receiver, index, *transition, strict_mode); 1840 name, receiver, index, transition, strict_mode);
1851 break; 1841 break;
1852 } 1842 }
1853 // fall through. 1843 // fall through.
1854 } 1844 default:
1855 default: {
1856 // Always rewrite to the generic case so that we do not 1845 // Always rewrite to the generic case so that we do not
1857 // repeatedly try to rewrite. 1846 // repeatedly try to rewrite.
1858 maybe_code = (strict_mode == kStrictMode) 1847 code = (strict_mode == kStrictMode)
1859 ? generic_stub_strict() 1848 ? generic_stub_strict()
1860 : generic_stub(); 1849 : generic_stub();
1861 break; 1850 break;
1862 }
1863 } 1851 }
1864 1852
1865 // If we're unable to compute the stub (not enough memory left), we 1853 ASSERT(!code.is_null());
1866 // simply avoid updating the caches.
1867 if (maybe_code == NULL || !maybe_code->ToObject(&code)) return;
1868 1854
1869 // Patch the call site depending on the state of the cache. Make 1855 // Patch the call site depending on the state of the cache. Make
1870 // sure to always rewrite from monomorphic to megamorphic. 1856 // sure to always rewrite from monomorphic to megamorphic.
1871 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE); 1857 ASSERT(state != MONOMORPHIC_PROTOTYPE_FAILURE);
1872 if (state == UNINITIALIZED || state == PREMONOMORPHIC) { 1858 if (state == UNINITIALIZED || state == PREMONOMORPHIC) {
1873 set_target(Code::cast(code)); 1859 set_target(*code);
1874 } else if (state == MONOMORPHIC) { 1860 } else if (state == MONOMORPHIC) {
1875 set_target((strict_mode == kStrictMode) 1861 set_target((strict_mode == kStrictMode)
1876 ? megamorphic_stub_strict() 1862 ? *megamorphic_stub_strict()
1877 : megamorphic_stub()); 1863 : *megamorphic_stub());
1878 } 1864 }
1879 1865
1880 #ifdef DEBUG 1866 #ifdef DEBUG
1881 TraceIC("KeyedStoreIC", name, state, target()); 1867 TraceIC("KeyedStoreIC", name, state, target());
1882 #endif 1868 #endif
1883 } 1869 }
1884 1870
1885 1871
1886 // ---------------------------------------------------------------------------- 1872 // ----------------------------------------------------------------------------
1887 // Static IC stub generators. 1873 // Static IC stub generators.
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
2028 object->set_properties(new_storage); 2014 object->set_properties(new_storage);
2029 object->set_map(transition); 2015 object->set_map(transition);
2030 2016
2031 // Return the stored value. 2017 // Return the stored value.
2032 return value; 2018 return value;
2033 } 2019 }
2034 2020
2035 2021
2036 // Used from ic-<arch>.cc. 2022 // Used from ic-<arch>.cc.
2037 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) { 2023 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_Miss) {
2038 NoHandleAllocation na; 2024 HandleScope scope(isolate);
2039 ASSERT(args.length() == 3); 2025 ASSERT(args.length() == 3);
2040 KeyedStoreIC ic(isolate); 2026 KeyedStoreIC ic(isolate);
2041 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 2027 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
2042 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); 2028 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
2043 return ic.Store(state, 2029 return ic.Store(state,
2044 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode), 2030 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode),
2045 args.at<Object>(0), 2031 args.at<Object>(0),
2046 args.at<Object>(1), 2032 args.at<Object>(1),
2047 args.at<Object>(2), 2033 args.at<Object>(2),
2048 false); 2034 false);
(...skipping 13 matching lines...) Expand all
2062 return Runtime::SetObjectProperty(isolate, 2048 return Runtime::SetObjectProperty(isolate,
2063 object, 2049 object,
2064 key, 2050 key,
2065 value, 2051 value,
2066 NONE, 2052 NONE,
2067 strict_mode); 2053 strict_mode);
2068 } 2054 }
2069 2055
2070 2056
2071 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) { 2057 RUNTIME_FUNCTION(MaybeObject*, KeyedStoreIC_MissForceGeneric) {
2072 NoHandleAllocation na; 2058 HandleScope scope(isolate);
2073 ASSERT(args.length() == 3); 2059 ASSERT(args.length() == 3);
2074 KeyedStoreIC ic(isolate); 2060 KeyedStoreIC ic(isolate);
2075 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]); 2061 IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
2076 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state(); 2062 Code::ExtraICState extra_ic_state = ic.target()->extra_ic_state();
2077 return ic.Store(state, 2063 return ic.Store(state,
2078 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode), 2064 static_cast<StrictModeFlag>(extra_ic_state & kStrictMode),
2079 args.at<Object>(0), 2065 args.at<Object>(0),
2080 args.at<Object>(1), 2066 args.at<Object>(1),
2081 args.at<Object>(2), 2067 args.at<Object>(2),
2082 true); 2068 true);
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
2497 #undef ADDR 2483 #undef ADDR
2498 }; 2484 };
2499 2485
2500 2486
2501 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2487 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2502 return IC_utilities[id]; 2488 return IC_utilities[id];
2503 } 2489 }
2504 2490
2505 2491
2506 } } // namespace v8::internal 2492 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698