OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |