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

Side by Side Diff: src/ic.cc

Issue 11824063: Separate MEGAMORPHIC and GENERIC ic states (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Move GENERIC from || to ASSERT(! 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') | src/objects.cc » ('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 // 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 29 matching lines...) Expand all
40 namespace internal { 40 namespace internal {
41 41
42 #ifdef DEBUG 42 #ifdef DEBUG
43 char IC::TransitionMarkFromState(IC::State state) { 43 char IC::TransitionMarkFromState(IC::State state) {
44 switch (state) { 44 switch (state) {
45 case UNINITIALIZED: return '0'; 45 case UNINITIALIZED: return '0';
46 case PREMONOMORPHIC: return '.'; 46 case PREMONOMORPHIC: return '.';
47 case MONOMORPHIC: return '1'; 47 case MONOMORPHIC: return '1';
48 case MONOMORPHIC_PROTOTYPE_FAILURE: return '^'; 48 case MONOMORPHIC_PROTOTYPE_FAILURE: return '^';
49 case POLYMORPHIC: return 'P'; 49 case POLYMORPHIC: return 'P';
50 case MEGAMORPHIC: return IsGeneric() ? 'G' : 'N'; 50 case MEGAMORPHIC: return 'N';
51 case GENERIC: return 'G';
51 52
52 // We never see the debugger states here, because the state is 53 // We never see the debugger states here, because the state is
53 // computed from the original code - not the patched code. Let 54 // computed from the original code - not the patched code. Let
54 // these cases fall through to the unreachable code below. 55 // these cases fall through to the unreachable code below.
55 case DEBUG_STUB: break; 56 case DEBUG_STUB: break;
56 } 57 }
57 UNREACHABLE(); 58 UNREACHABLE();
58 return 0; 59 return 0;
59 } 60 }
60 61
(...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 Handle<JSObject> cache_object = object->IsJSObject() 766 Handle<JSObject> cache_object = object->IsJSObject()
766 ? Handle<JSObject>::cast(object) 767 ? Handle<JSObject>::cast(object)
767 : Handle<JSObject>(JSObject::cast(object->GetPrototype())); 768 : Handle<JSObject>(JSObject::cast(object->GetPrototype()));
768 // Update the stub cache. 769 // Update the stub cache.
769 isolate()->stub_cache()->Set(*name, cache_object->map(), *code); 770 isolate()->stub_cache()->Set(*name, cache_object->map(), *code);
770 break; 771 break;
771 } 772 }
772 case DEBUG_STUB: 773 case DEBUG_STUB:
773 break; 774 break;
774 case POLYMORPHIC: 775 case POLYMORPHIC:
776 case GENERIC:
775 UNREACHABLE(); 777 UNREACHABLE();
776 break; 778 break;
777 } 779 }
778 780
779 TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", 781 TRACE_IC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC",
780 name, state, target()); 782 name, state, target());
781 } 783 }
782 784
783 785
784 MaybeObject* KeyedCallIC::LoadFunction(State state, 786 MaybeObject* KeyedCallIC::LoadFunction(State state,
785 Handle<Object> object, 787 Handle<Object> object,
786 Handle<Object> key) { 788 Handle<Object> key) {
787 if (key->IsSymbol()) { 789 if (key->IsSymbol()) {
788 return CallICBase::LoadFunction(state, 790 return CallICBase::LoadFunction(state,
789 Code::kNoExtraICState, 791 Code::kNoExtraICState,
790 object, 792 object,
791 Handle<String>::cast(key)); 793 Handle<String>::cast(key));
792 } 794 }
793 795
794 if (object->IsUndefined() || object->IsNull()) { 796 if (object->IsUndefined() || object->IsNull()) {
795 return TypeError("non_object_property_call", object, key); 797 return TypeError("non_object_property_call", object, key);
796 } 798 }
797 799
798 if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) { 800 if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) {
801 ASSERT(state != GENERIC);
799 int argc = target()->arguments_count(); 802 int argc = target()->arguments_count();
800 Handle<Map> map = 803 Handle<Map> map =
801 isolate()->factory()->non_strict_arguments_elements_map(); 804 isolate()->factory()->non_strict_arguments_elements_map();
802 if (object->IsJSObject() && 805 if (object->IsJSObject() &&
803 Handle<JSObject>::cast(object)->elements()->map() == *map) { 806 Handle<JSObject>::cast(object)->elements()->map() == *map) {
804 Handle<Code> code = isolate()->stub_cache()->ComputeCallArguments( 807 Handle<Code> code = isolate()->stub_cache()->ComputeCallArguments(
805 argc, Code::KEYED_CALL_IC); 808 argc, Code::KEYED_CALL_IC);
806 set_target(*code); 809 set_target(*code);
807 TRACE_IC("KeyedCallIC", key, state, target()); 810 TRACE_IC("KeyedCallIC", key, state, target());
808 } else if (!object->IsAccessCheckNeeded()) { 811 } else if (!object->IsAccessCheckNeeded()) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
848 Handle<Code> stub; 851 Handle<Code> stub;
849 if (state == UNINITIALIZED) { 852 if (state == UNINITIALIZED) {
850 stub = pre_monomorphic_stub(); 853 stub = pre_monomorphic_stub();
851 } else if (state == PREMONOMORPHIC) { 854 } else if (state == PREMONOMORPHIC) {
852 stub = object->IsString() 855 stub = object->IsString()
853 ? isolate()->builtins()->LoadIC_StringLength() 856 ? isolate()->builtins()->LoadIC_StringLength()
854 : isolate()->builtins()->LoadIC_StringWrapperLength(); 857 : isolate()->builtins()->LoadIC_StringWrapperLength();
855 } else if (state == MONOMORPHIC && object->IsStringWrapper()) { 858 } else if (state == MONOMORPHIC && object->IsStringWrapper()) {
856 stub = isolate()->builtins()->LoadIC_StringWrapperLength(); 859 stub = isolate()->builtins()->LoadIC_StringWrapperLength();
857 } else if (state != MEGAMORPHIC) { 860 } else if (state != MEGAMORPHIC) {
861 ASSERT(state != GENERIC);
858 stub = megamorphic_stub(); 862 stub = megamorphic_stub();
859 } 863 }
860 if (!stub.is_null()) { 864 if (!stub.is_null()) {
861 set_target(*stub); 865 set_target(*stub);
862 #ifdef DEBUG 866 #ifdef DEBUG
863 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n"); 867 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n");
864 #endif 868 #endif
865 } 869 }
866 // Get the string if we have a string wrapper object. 870 // Get the string if we have a string wrapper object.
867 Handle<Object> string = object->IsJSValue() 871 Handle<Object> string = object->IsJSValue()
868 ? Handle<Object>(Handle<JSValue>::cast(object)->value()) 872 ? Handle<Object>(Handle<JSValue>::cast(object)->value())
869 : object; 873 : object;
870 return Smi::FromInt(String::cast(*string)->length()); 874 return Smi::FromInt(String::cast(*string)->length());
871 } 875 }
872 876
873 // Use specialized code for getting the length of arrays. 877 // Use specialized code for getting the length of arrays.
874 if (object->IsJSArray() && 878 if (object->IsJSArray() &&
875 name->Equals(isolate()->heap()->length_symbol())) { 879 name->Equals(isolate()->heap()->length_symbol())) {
876 Handle<Code> stub; 880 Handle<Code> stub;
877 if (state == UNINITIALIZED) { 881 if (state == UNINITIALIZED) {
878 stub = pre_monomorphic_stub(); 882 stub = pre_monomorphic_stub();
879 } else if (state == PREMONOMORPHIC) { 883 } else if (state == PREMONOMORPHIC) {
880 stub = isolate()->builtins()->LoadIC_ArrayLength(); 884 stub = isolate()->builtins()->LoadIC_ArrayLength();
881 } else if (state != MEGAMORPHIC) { 885 } else if (state != MEGAMORPHIC) {
886 ASSERT(state != GENERIC);
882 stub = megamorphic_stub(); 887 stub = megamorphic_stub();
883 } 888 }
884 if (!stub.is_null()) { 889 if (!stub.is_null()) {
885 set_target(*stub); 890 set_target(*stub);
886 #ifdef DEBUG 891 #ifdef DEBUG
887 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n"); 892 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
888 #endif 893 #endif
889 } 894 }
890 return JSArray::cast(*object)->length(); 895 return JSArray::cast(*object)->length();
891 } 896 }
892 897
893 // Use specialized code for getting prototype of functions. 898 // Use specialized code for getting prototype of functions.
894 if (object->IsJSFunction() && 899 if (object->IsJSFunction() &&
895 name->Equals(isolate()->heap()->prototype_symbol()) && 900 name->Equals(isolate()->heap()->prototype_symbol()) &&
896 Handle<JSFunction>::cast(object)->should_have_prototype()) { 901 Handle<JSFunction>::cast(object)->should_have_prototype()) {
897 Handle<Code> stub; 902 Handle<Code> stub;
898 if (state == UNINITIALIZED) { 903 if (state == UNINITIALIZED) {
899 stub = pre_monomorphic_stub(); 904 stub = pre_monomorphic_stub();
900 } else if (state == PREMONOMORPHIC) { 905 } else if (state == PREMONOMORPHIC) {
901 stub = isolate()->builtins()->LoadIC_FunctionPrototype(); 906 stub = isolate()->builtins()->LoadIC_FunctionPrototype();
902 } else if (state != MEGAMORPHIC) { 907 } else if (state != MEGAMORPHIC) {
908 ASSERT(state != GENERIC);
903 stub = megamorphic_stub(); 909 stub = megamorphic_stub();
904 } 910 }
905 if (!stub.is_null()) { 911 if (!stub.is_null()) {
906 set_target(*stub); 912 set_target(*stub);
907 #ifdef DEBUG 913 #ifdef DEBUG
908 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); 914 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n");
909 #endif 915 #endif
910 } 916 }
911 return Accessors::FunctionGetPrototype(*object, 0); 917 return Accessors::FunctionGetPrototype(*object, 0);
912 } 918 }
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
1060 } 1066 }
1061 break; 1067 break;
1062 case MEGAMORPHIC: 1068 case MEGAMORPHIC:
1063 // Cache code holding map should be consistent with 1069 // Cache code holding map should be consistent with
1064 // GenerateMonomorphicCacheProbe. 1070 // GenerateMonomorphicCacheProbe.
1065 isolate()->stub_cache()->Set(*name, receiver->map(), *code); 1071 isolate()->stub_cache()->Set(*name, receiver->map(), *code);
1066 break; 1072 break;
1067 case DEBUG_STUB: 1073 case DEBUG_STUB:
1068 break; 1074 break;
1069 case POLYMORPHIC: 1075 case POLYMORPHIC:
1076 case GENERIC:
1070 UNREACHABLE(); 1077 UNREACHABLE();
1071 break; 1078 break;
1072 } 1079 }
1073 1080
1074 TRACE_IC("LoadIC", name, state, target()); 1081 TRACE_IC("LoadIC", name, state, target());
1075 } 1082 }
1076 1083
1077 1084
1078 Handle<Code> KeyedLoadIC::GetElementStubWithoutMapCheck( 1085 Handle<Code> KeyedLoadIC::GetElementStubWithoutMapCheck(
1079 bool is_js_array, 1086 bool is_js_array,
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
1332 case MONOMORPHIC: 1339 case MONOMORPHIC:
1333 // Only move to megamorphic if the target changes. 1340 // Only move to megamorphic if the target changes.
1334 if (target() != *code) { 1341 if (target() != *code) {
1335 set_target(*megamorphic_stub()); 1342 set_target(*megamorphic_stub());
1336 } 1343 }
1337 break; 1344 break;
1338 case MEGAMORPHIC: 1345 case MEGAMORPHIC:
1339 case DEBUG_STUB: 1346 case DEBUG_STUB:
1340 break; 1347 break;
1341 case MONOMORPHIC_PROTOTYPE_FAILURE: 1348 case MONOMORPHIC_PROTOTYPE_FAILURE:
1349 case GENERIC:
1342 UNREACHABLE(); 1350 UNREACHABLE();
1343 break; 1351 break;
1344 } 1352 }
1345 1353
1346 TRACE_IC("KeyedLoadIC", name, state, target()); 1354 TRACE_IC("KeyedLoadIC", name, state, target());
1347 } 1355 }
1348 1356
1349 1357
1350 static bool StoreICableLookup(LookupResult* lookup) { 1358 static bool StoreICableLookup(LookupResult* lookup) {
1351 // Bail out if we didn't find a result. 1359 // Bail out if we didn't find a result.
(...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after
1607 : megamorphic_stub()); 1615 : megamorphic_stub());
1608 } 1616 }
1609 break; 1617 break;
1610 case MEGAMORPHIC: 1618 case MEGAMORPHIC:
1611 // Update the stub cache. 1619 // Update the stub cache.
1612 isolate()->stub_cache()->Set(*name, receiver->map(), *code); 1620 isolate()->stub_cache()->Set(*name, receiver->map(), *code);
1613 break; 1621 break;
1614 case DEBUG_STUB: 1622 case DEBUG_STUB:
1615 break; 1623 break;
1616 case POLYMORPHIC: 1624 case POLYMORPHIC:
1625 case GENERIC:
1617 UNREACHABLE(); 1626 UNREACHABLE();
1618 break; 1627 break;
1619 } 1628 }
1620 1629
1621 TRACE_IC("StoreIC", name, state, target()); 1630 TRACE_IC("StoreIC", name, state, target());
1622 } 1631 }
1623 1632
1624 1633
1625 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps, 1634 static bool AddOneReceiverMapIfMissing(MapHandleList* receiver_maps,
1626 Handle<Map> new_receiver_map) { 1635 Handle<Map> new_receiver_map) {
(...skipping 24 matching lines...) Expand all
1651 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT); 1660 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
1652 for (RelocIterator it(*stub, mask); !it.done(); it.next()) { 1661 for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
1653 RelocInfo* info = it.rinfo(); 1662 RelocInfo* info = it.rinfo();
1654 Handle<Object> object(info->target_object()); 1663 Handle<Object> object(info->target_object());
1655 ASSERT(object->IsMap()); 1664 ASSERT(object->IsMap());
1656 AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object)); 1665 AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
1657 } 1666 }
1658 break; 1667 break;
1659 } 1668 }
1660 case MEGAMORPHIC: 1669 case MEGAMORPHIC:
1670 case GENERIC:
1661 break; 1671 break;
1662 case UNINITIALIZED: 1672 case UNINITIALIZED:
1663 case PREMONOMORPHIC: 1673 case PREMONOMORPHIC:
1664 case MONOMORPHIC_PROTOTYPE_FAILURE: 1674 case MONOMORPHIC_PROTOTYPE_FAILURE:
1665 case DEBUG_STUB: 1675 case DEBUG_STUB:
1666 UNREACHABLE(); 1676 UNREACHABLE();
1667 break; 1677 break;
1668 } 1678 }
1669 } 1679 }
1670 } 1680 }
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
2104 if (target() != *code) { 2114 if (target() != *code) {
2105 set_target((strict_mode == kStrictMode) 2115 set_target((strict_mode == kStrictMode)
2106 ? *megamorphic_stub_strict() 2116 ? *megamorphic_stub_strict()
2107 : *megamorphic_stub()); 2117 : *megamorphic_stub());
2108 } 2118 }
2109 break; 2119 break;
2110 case MEGAMORPHIC: 2120 case MEGAMORPHIC:
2111 case DEBUG_STUB: 2121 case DEBUG_STUB:
2112 break; 2122 break;
2113 case MONOMORPHIC_PROTOTYPE_FAILURE: 2123 case MONOMORPHIC_PROTOTYPE_FAILURE:
2124 case GENERIC:
2114 UNREACHABLE(); 2125 UNREACHABLE();
2115 break; 2126 break;
2116 } 2127 }
2117 2128
2118 TRACE_IC("KeyedStoreIC", name, state, target()); 2129 TRACE_IC("KeyedStoreIC", name, state, target());
2119 } 2130 }
2120 2131
2121 2132
2122 #undef TRACE_IC 2133 #undef TRACE_IC
2123 2134
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
2347 2358
2348 2359
2349 UnaryOpIC::State UnaryOpIC::ToState(TypeInfo type_info) { 2360 UnaryOpIC::State UnaryOpIC::ToState(TypeInfo type_info) {
2350 switch (type_info) { 2361 switch (type_info) {
2351 case UNINITIALIZED: 2362 case UNINITIALIZED:
2352 return ::v8::internal::UNINITIALIZED; 2363 return ::v8::internal::UNINITIALIZED;
2353 case SMI: 2364 case SMI:
2354 case HEAP_NUMBER: 2365 case HEAP_NUMBER:
2355 return MONOMORPHIC; 2366 return MONOMORPHIC;
2356 case GENERIC: 2367 case GENERIC:
2357 return MEGAMORPHIC; 2368 return ::v8::internal::GENERIC;
2358 } 2369 }
2359 UNREACHABLE(); 2370 UNREACHABLE();
2360 return ::v8::internal::UNINITIALIZED; 2371 return ::v8::internal::UNINITIALIZED;
2361 } 2372 }
2362 2373
2363 UnaryOpIC::TypeInfo UnaryOpIC::GetTypeInfo(Handle<Object> operand) { 2374 UnaryOpIC::TypeInfo UnaryOpIC::GetTypeInfo(Handle<Object> operand) {
2364 ::v8::internal::TypeInfo operand_type = 2375 ::v8::internal::TypeInfo operand_type =
2365 ::v8::internal::TypeInfo::TypeFromValue(operand); 2376 ::v8::internal::TypeInfo::TypeFromValue(operand);
2366 if (operand_type.IsSmi()) { 2377 if (operand_type.IsSmi()) {
2367 return SMI; 2378 return SMI;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2418 switch (type_info) { 2429 switch (type_info) {
2419 case UNINITIALIZED: 2430 case UNINITIALIZED:
2420 return ::v8::internal::UNINITIALIZED; 2431 return ::v8::internal::UNINITIALIZED;
2421 case SMI: 2432 case SMI:
2422 case INT32: 2433 case INT32:
2423 case HEAP_NUMBER: 2434 case HEAP_NUMBER:
2424 case ODDBALL: 2435 case ODDBALL:
2425 case STRING: 2436 case STRING:
2426 return MONOMORPHIC; 2437 return MONOMORPHIC;
2427 case GENERIC: 2438 case GENERIC:
2428 return MEGAMORPHIC; 2439 return ::v8::internal::GENERIC;
2429 } 2440 }
2430 UNREACHABLE(); 2441 UNREACHABLE();
2431 return ::v8::internal::UNINITIALIZED; 2442 return ::v8::internal::UNINITIALIZED;
2432 } 2443 }
2433 2444
2434 2445
2435 RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) { 2446 RUNTIME_FUNCTION(MaybeObject*, UnaryOp_Patch) {
2436 ASSERT(args.length() == 4); 2447 ASSERT(args.length() == 4);
2437 2448
2438 HandleScope scope(isolate); 2449 HandleScope scope(isolate);
(...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after
2857 #undef ADDR 2868 #undef ADDR
2858 }; 2869 };
2859 2870
2860 2871
2861 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2872 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2862 return IC_utilities[id]; 2873 return IC_utilities[id];
2863 } 2874 }
2864 2875
2865 2876
2866 } } // namespace v8::internal 2877 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698