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

Side by Side Diff: src/ic.cc

Issue 411973002: Restructure the IC / Handler compilers (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 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
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/codegen.h" 10 #include "src/codegen.h"
(...skipping 859 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 870
871 Handle<Code> IC::ComputeHandler(LookupResult* lookup, 871 Handle<Code> IC::ComputeHandler(LookupResult* lookup,
872 Handle<Object> object, 872 Handle<Object> object,
873 Handle<String> name, 873 Handle<String> name,
874 Handle<Object> value) { 874 Handle<Object> value) {
875 bool receiver_is_holder = lookup->ReceiverIsHolder(object); 875 bool receiver_is_holder = lookup->ReceiverIsHolder(object);
876 CacheHolderFlag flag; 876 CacheHolderFlag flag;
877 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder( 877 Handle<Map> stub_holder_map = IC::GetHandlerCacheHolder(
878 *receiver_type(), receiver_is_holder, isolate(), &flag); 878 *receiver_type(), receiver_is_holder, isolate(), &flag);
879 879
880 Handle<Code> code = isolate()->stub_cache()->FindHandler( 880 Handle<Code> code = PropertyHandlerCompiler::Find(
881 name, stub_holder_map, handler_kind(), flag, 881 name, stub_holder_map, handler_kind(), flag,
882 lookup->holder()->HasFastProperties() ? Code::FAST : Code::NORMAL); 882 lookup->holder()->HasFastProperties() ? Code::FAST : Code::NORMAL);
883 // Use the cached value if it exists, and if it is different from the 883 // Use the cached value if it exists, and if it is different from the
884 // handler that just missed. 884 // handler that just missed.
885 if (!code.is_null()) { 885 if (!code.is_null()) {
886 if (!maybe_handler_.is_null() && 886 if (!maybe_handler_.is_null() &&
887 !maybe_handler_.ToHandleChecked().is_identical_to(code)) { 887 !maybe_handler_.ToHandleChecked().is_identical_to(code)) {
888 return code; 888 return code;
889 } 889 }
890 if (maybe_handler_.is_null()) { 890 if (maybe_handler_.is_null()) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 StringLengthStub string_length_stub(isolate()); 927 StringLengthStub string_length_stub(isolate());
928 return string_length_stub.GetCode(); 928 return string_length_stub.GetCode();
929 } 929 }
930 930
931 // Use specialized code for getting prototype of functions. 931 // Use specialized code for getting prototype of functions.
932 if (object->IsJSFunction() && 932 if (object->IsJSFunction() &&
933 String::Equals(isolate()->factory()->prototype_string(), name) && 933 String::Equals(isolate()->factory()->prototype_string(), name) &&
934 Handle<JSFunction>::cast(object)->should_have_prototype() && 934 Handle<JSFunction>::cast(object)->should_have_prototype() &&
935 !Handle<JSFunction>::cast(object)->map()->has_non_instance_prototype()) { 935 !Handle<JSFunction>::cast(object)->map()->has_non_instance_prototype()) {
936 Handle<Code> stub; 936 Handle<Code> stub;
937 FunctionPrototypeStub function_prototype_stub(isolate(), kind()); 937 FunctionPrototypeStub function_prototype_stub(isolate());
938 return function_prototype_stub.GetCode(); 938 return function_prototype_stub.GetCode();
939 } 939 }
940 940
941 Handle<HeapType> type = receiver_type(); 941 Handle<HeapType> type = receiver_type();
942 Handle<JSObject> holder(lookup->holder()); 942 Handle<JSObject> holder(lookup->holder());
943 bool receiver_is_holder = object.is_identical_to(holder); 943 bool receiver_is_holder = object.is_identical_to(holder);
944 LoadStubCompiler compiler(isolate(), handler_kind(), kNoExtraICState, 944 NamedLoadHandlerCompiler compiler(isolate(), handler_kind(), kNoExtraICState,
945 cache_holder); 945 cache_holder);
946 946
947 switch (lookup->type()) { 947 switch (lookup->type()) {
948 case FIELD: { 948 case FIELD: {
949 FieldIndex field = lookup->GetFieldIndex(); 949 FieldIndex field = lookup->GetFieldIndex();
950 if (receiver_is_holder) { 950 if (receiver_is_holder) {
951 return SimpleFieldLoad(field); 951 return SimpleFieldLoad(field);
952 } 952 }
953 return compiler.CompileLoadField( 953 return compiler.CompileLoadField(
954 type, holder, name, field, lookup->representation()); 954 type, holder, name, field, lookup->representation());
955 } 955 }
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 Handle<Object> object, Handle<String> name, 1385 Handle<Object> object, Handle<String> name,
1386 Handle<Object> value, 1386 Handle<Object> value,
1387 CacheHolderFlag cache_holder) { 1387 CacheHolderFlag cache_holder) {
1388 if (object->IsAccessCheckNeeded()) return slow_stub(); 1388 if (object->IsAccessCheckNeeded()) return slow_stub();
1389 ASSERT(cache_holder == kCacheOnReceiver || lookup->type() == CALLBACKS || 1389 ASSERT(cache_holder == kCacheOnReceiver || lookup->type() == CALLBACKS ||
1390 (object->IsJSGlobalProxy() && lookup->holder()->IsJSGlobalObject())); 1390 (object->IsJSGlobalProxy() && lookup->holder()->IsJSGlobalObject()));
1391 // This is currently guaranteed by checks in StoreIC::Store. 1391 // This is currently guaranteed by checks in StoreIC::Store.
1392 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1392 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1393 1393
1394 Handle<JSObject> holder(lookup->holder()); 1394 Handle<JSObject> holder(lookup->holder());
1395 // Handlers do not use strict mode. 1395 NamedStoreHandlerCompiler compiler(isolate(), kind());
1396 StoreStubCompiler compiler(isolate(), SLOPPY, kind()); 1396
1397 if (lookup->IsTransition()) { 1397 if (lookup->IsTransition()) {
1398 // Explicitly pass in the receiver map since LookupForWrite may have 1398 // Explicitly pass in the receiver map since LookupForWrite may have
1399 // stored something else than the receiver in the holder. 1399 // stored something else than the receiver in the holder.
1400 Handle<Map> transition(lookup->GetTransitionTarget()); 1400 Handle<Map> transition(lookup->GetTransitionTarget());
1401 PropertyDetails details = lookup->GetPropertyDetails(); 1401 PropertyDetails details = lookup->GetPropertyDetails();
1402 1402
1403 if (details.type() != CALLBACKS && details.attributes() == NONE) { 1403 if (details.type() != CALLBACKS && details.attributes() == NONE) {
1404 return compiler.CompileStoreTransition( 1404 return compiler.CompileStoreTransition(
1405 receiver, lookup, transition, name); 1405 receiver, lookup, transition, name);
1406 } 1406 }
(...skipping 332 matching lines...) Expand 10 before | Expand all | Expand 10 after
1739 1739
1740 if (key->IsInternalizedString()) { 1740 if (key->IsInternalizedString()) {
1741 ASSIGN_RETURN_ON_EXCEPTION( 1741 ASSIGN_RETURN_ON_EXCEPTION(
1742 isolate(), 1742 isolate(),
1743 store_handle, 1743 store_handle,
1744 StoreIC::Store(object, 1744 StoreIC::Store(object,
1745 Handle<String>::cast(key), 1745 Handle<String>::cast(key),
1746 value, 1746 value,
1747 JSReceiver::MAY_BE_STORE_FROM_KEYED), 1747 JSReceiver::MAY_BE_STORE_FROM_KEYED),
1748 Object); 1748 Object);
1749 } else { 1749 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic");
1750 bool use_ic = FLAG_use_ic && 1750 set_target(*stub);
1751 !object->IsStringWrapper() && 1751 return store_handle;
1752 !object->IsAccessCheckNeeded() && 1752 }
1753 !object->IsJSGlobalProxy() &&
1754 !(object->IsJSObject() &&
1755 JSObject::cast(*object)->map()->is_observed());
1756 if (use_ic && !object->IsSmi()) {
1757 // Don't use ICs for maps of the objects in Array's prototype chain. We
1758 // expect to be able to trap element sets to objects with those maps in
1759 // the runtime to enable optimization of element hole access.
1760 Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
1761 if (heap_object->map()->IsMapInArrayPrototypeChain()) use_ic = false;
1762 }
1763 1753
1764 if (use_ic) { 1754 bool use_ic =
1765 ASSERT(!object->IsAccessCheckNeeded()); 1755 FLAG_use_ic && !object->IsStringWrapper() &&
1756 !object->IsAccessCheckNeeded() && !object->IsJSGlobalProxy() &&
1757 !(object->IsJSObject() && JSObject::cast(*object)->map()->is_observed());
1758 if (use_ic && !object->IsSmi()) {
1759 // Don't use ICs for maps of the objects in Array's prototype chain. We
1760 // expect to be able to trap element sets to objects with those maps in
1761 // the runtime to enable optimization of element hole access.
1762 Handle<HeapObject> heap_object = Handle<HeapObject>::cast(object);
1763 if (heap_object->map()->IsMapInArrayPrototypeChain()) use_ic = false;
1764 }
1766 1765
1767 if (object->IsJSObject()) { 1766 if (use_ic) {
1768 Handle<JSObject> receiver = Handle<JSObject>::cast(object); 1767 ASSERT(!object->IsAccessCheckNeeded());
1769 bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null(); 1768
1770 if (receiver->elements()->map() == 1769 if (object->IsJSObject()) {
1771 isolate()->heap()->sloppy_arguments_elements_map()) { 1770 Handle<JSObject> receiver = Handle<JSObject>::cast(object);
1772 if (strict_mode() == SLOPPY) { 1771 bool key_is_smi_like = !Object::ToSmi(isolate(), key).is_null();
1773 stub = sloppy_arguments_stub(); 1772 if (receiver->elements()->map() ==
1774 } 1773 isolate()->heap()->sloppy_arguments_elements_map()) {
1775 } else if (key_is_smi_like && 1774 if (strict_mode() == SLOPPY) {
1776 !(target().is_identical_to(sloppy_arguments_stub()))) { 1775 stub = sloppy_arguments_stub();
1777 // We should go generic if receiver isn't a dictionary, but our 1776 }
1778 // prototype chain does have dictionary elements. This ensures that 1777 } else if (key_is_smi_like &&
1779 // other non-dictionary receivers in the polymorphic case benefit 1778 !(target().is_identical_to(sloppy_arguments_stub()))) {
1780 // from fast path keyed stores. 1779 // We should go generic if receiver isn't a dictionary, but our
1781 if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) { 1780 // prototype chain does have dictionary elements. This ensures that
1782 KeyedAccessStoreMode store_mode = 1781 // other non-dictionary receivers in the polymorphic case benefit
1783 GetStoreMode(receiver, key, value); 1782 // from fast path keyed stores.
1784 stub = StoreElementStub(receiver, store_mode); 1783 if (!(receiver->map()->DictionaryElementsInPrototypeChainOnly())) {
1785 } 1784 KeyedAccessStoreMode store_mode = GetStoreMode(receiver, key, value);
1785 stub = StoreElementStub(receiver, store_mode);
1786 } 1786 }
1787 } 1787 }
1788 } 1788 }
1789 } 1789 }
1790 1790
1791 if (store_handle.is_null()) { 1791 if (store_handle.is_null()) {
1792 ASSIGN_RETURN_ON_EXCEPTION( 1792 ASSIGN_RETURN_ON_EXCEPTION(
1793 isolate(), 1793 isolate(),
1794 store_handle, 1794 store_handle,
1795 Runtime::SetObjectProperty( 1795 Runtime::SetObjectProperty(
1796 isolate(), object, key, value, strict_mode()), 1796 isolate(), object, key, value, strict_mode()),
1797 Object); 1797 Object);
1798 } 1798 }
1799 1799
1800 if (!is_target_set()) { 1800 ASSERT(!is_target_set());
1801 Code* generic = *generic_stub(); 1801 Code* generic = *generic_stub();
1802 if (*stub == generic) { 1802 if (*stub == generic) {
1803 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic"); 1803 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", "set generic");
1804 }
1805 ASSERT(!stub.is_null());
1806 set_target(*stub);
1807 TRACE_IC("StoreIC", key);
1808 } 1804 }
1805 ASSERT(!stub.is_null());
1806 set_target(*stub);
1807 TRACE_IC("StoreIC", key);
1809 1808
1810 return store_handle; 1809 return store_handle;
1811 } 1810 }
1812 1811
1813 1812
1814 CallIC::State::State(ExtraICState extra_ic_state) 1813 CallIC::State::State(ExtraICState extra_ic_state)
1815 : argc_(ArgcBits::decode(extra_ic_state)), 1814 : argc_(ArgcBits::decode(extra_ic_state)),
1816 call_type_(CallTypeBits::decode(extra_ic_state)) { 1815 call_type_(CallTypeBits::decode(extra_ic_state)) {
1817 } 1816 }
1818 1817
(...skipping 1217 matching lines...) Expand 10 before | Expand all | Expand 10 after
3036 #undef ADDR 3035 #undef ADDR
3037 }; 3036 };
3038 3037
3039 3038
3040 Address IC::AddressFromUtilityId(IC::UtilityId id) { 3039 Address IC::AddressFromUtilityId(IC::UtilityId id) {
3041 return IC_utilities[id]; 3040 return IC_utilities[id];
3042 } 3041 }
3043 3042
3044 3043
3045 } } // namespace v8::internal 3044 } } // namespace v8::internal
OLDNEW
« src/ia32/stub-cache-ia32.cc ('K') | « src/ia32/stub-cache-ia32.cc ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698