| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 } | 587 } |
| 588 return code; | 588 return code; |
| 589 } | 589 } |
| 590 | 590 |
| 591 #define CALL_LOGGER_TAG(kind, type) \ | 591 #define CALL_LOGGER_TAG(kind, type) \ |
| 592 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) | 592 (kind == Code::CALL_IC ? Logger::type : Logger::KEYED_##type) |
| 593 | 593 |
| 594 MaybeObject* StubCache::ComputeCallConstant(int argc, | 594 MaybeObject* StubCache::ComputeCallConstant(int argc, |
| 595 InLoopFlag in_loop, | 595 InLoopFlag in_loop, |
| 596 Code::Kind kind, | 596 Code::Kind kind, |
| 597 Code::ExtraICState extra_ic_state, |
| 597 String* name, | 598 String* name, |
| 598 Object* object, | 599 Object* object, |
| 599 JSObject* holder, | 600 JSObject* holder, |
| 600 JSFunction* function) { | 601 JSFunction* function) { |
| 601 // Compute the check type and the map. | 602 // Compute the check type and the map. |
| 602 InlineCacheHolderFlag cache_holder = | 603 InlineCacheHolderFlag cache_holder = |
| 603 IC::GetCodeCacheForObject(object, holder); | 604 IC::GetCodeCacheForObject(object, holder); |
| 604 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); | 605 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); |
| 605 | 606 |
| 606 // Compute check type based on receiver/holder. | 607 // Compute check type based on receiver/holder. |
| 607 CheckType check = RECEIVER_MAP_CHECK; | 608 CheckType check = RECEIVER_MAP_CHECK; |
| 608 if (object->IsString()) { | 609 if (object->IsString()) { |
| 609 check = STRING_CHECK; | 610 check = STRING_CHECK; |
| 610 } else if (object->IsNumber()) { | 611 } else if (object->IsNumber()) { |
| 611 check = NUMBER_CHECK; | 612 check = NUMBER_CHECK; |
| 612 } else if (object->IsBoolean()) { | 613 } else if (object->IsBoolean()) { |
| 613 check = BOOLEAN_CHECK; | 614 check = BOOLEAN_CHECK; |
| 614 } | 615 } |
| 615 | 616 |
| 616 Code::Flags flags = | 617 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, |
| 617 Code::ComputeMonomorphicFlags(kind, | 618 CONSTANT_FUNCTION, |
| 618 CONSTANT_FUNCTION, | 619 extra_ic_state, |
| 619 cache_holder, | 620 cache_holder, |
| 620 in_loop, | 621 in_loop, |
| 621 argc); | 622 argc); |
| 622 Object* code = map_holder->map()->FindInCodeCache(name, flags); | 623 Object* code = map_holder->map()->FindInCodeCache(name, flags); |
| 623 if (code->IsUndefined()) { | 624 if (code->IsUndefined()) { |
| 624 // If the function hasn't been compiled yet, we cannot do it now | 625 // If the function hasn't been compiled yet, we cannot do it now |
| 625 // because it may cause GC. To avoid this issue, we return an | 626 // because it may cause GC. To avoid this issue, we return an |
| 626 // internal error which will make sure we do not update any | 627 // internal error which will make sure we do not update any |
| 627 // caches. | 628 // caches. |
| 628 if (!function->is_compiled()) return Failure::InternalError(); | 629 if (!function->is_compiled()) return Failure::InternalError(); |
| 629 // Compile the stub - only create stubs for fully compiled functions. | 630 // Compile the stub - only create stubs for fully compiled functions. |
| 630 CallStubCompiler compiler(argc, in_loop, kind, cache_holder); | 631 CallStubCompiler compiler( |
| 632 argc, in_loop, kind, extra_ic_state, cache_holder); |
| 631 { MaybeObject* maybe_code = | 633 { MaybeObject* maybe_code = |
| 632 compiler.CompileCallConstant(object, holder, function, name, check); | 634 compiler.CompileCallConstant(object, holder, function, name, check); |
| 633 if (!maybe_code->ToObject(&code)) return maybe_code; | 635 if (!maybe_code->ToObject(&code)) return maybe_code; |
| 634 } | 636 } |
| 635 Code::cast(code)->set_check_type(check); | 637 Code::cast(code)->set_check_type(check); |
| 636 ASSERT_EQ(flags, Code::cast(code)->flags()); | 638 ASSERT_EQ(flags, Code::cast(code)->flags()); |
| 637 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 639 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
| 638 Code::cast(code), name)); | 640 Code::cast(code), name)); |
| 639 Object* result; | 641 Object* result; |
| 640 { MaybeObject* maybe_result = | 642 { MaybeObject* maybe_result = |
| (...skipping 19 matching lines...) Expand all Loading... |
| 660 | 662 |
| 661 // TODO(1233596): We cannot do receiver map check for non-JS objects | 663 // TODO(1233596): We cannot do receiver map check for non-JS objects |
| 662 // because they may be represented as immediates without a | 664 // because they may be represented as immediates without a |
| 663 // map. Instead, we check against the map in the holder. | 665 // map. Instead, we check against the map in the holder. |
| 664 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { | 666 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { |
| 665 object = holder; | 667 object = holder; |
| 666 } | 668 } |
| 667 | 669 |
| 668 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, | 670 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, |
| 669 FIELD, | 671 FIELD, |
| 672 Code::kNoExtraICState, |
| 670 cache_holder, | 673 cache_holder, |
| 671 in_loop, | 674 in_loop, |
| 672 argc); | 675 argc); |
| 673 Object* code = map_holder->map()->FindInCodeCache(name, flags); | 676 Object* code = map_holder->map()->FindInCodeCache(name, flags); |
| 674 if (code->IsUndefined()) { | 677 if (code->IsUndefined()) { |
| 675 CallStubCompiler compiler(argc, in_loop, kind, cache_holder); | 678 CallStubCompiler compiler( |
| 679 argc, in_loop, kind, Code::kNoExtraICState, cache_holder); |
| 676 { MaybeObject* maybe_code = | 680 { MaybeObject* maybe_code = |
| 677 compiler.CompileCallField(JSObject::cast(object), | 681 compiler.CompileCallField(JSObject::cast(object), |
| 678 holder, | 682 holder, |
| 679 index, | 683 index, |
| 680 name); | 684 name); |
| 681 if (!maybe_code->ToObject(&code)) return maybe_code; | 685 if (!maybe_code->ToObject(&code)) return maybe_code; |
| 682 } | 686 } |
| 683 ASSERT_EQ(flags, Code::cast(code)->flags()); | 687 ASSERT_EQ(flags, Code::cast(code)->flags()); |
| 684 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 688 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
| 685 Code::cast(code), name)); | 689 Code::cast(code), name)); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 703 IC::GetCodeCacheForObject(object, holder); | 707 IC::GetCodeCacheForObject(object, holder); |
| 704 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); | 708 JSObject* map_holder = IC::GetCodeCacheHolder(object, cache_holder); |
| 705 | 709 |
| 706 // TODO(1233596): We cannot do receiver map check for non-JS objects | 710 // TODO(1233596): We cannot do receiver map check for non-JS objects |
| 707 // because they may be represented as immediates without a | 711 // because they may be represented as immediates without a |
| 708 // map. Instead, we check against the map in the holder. | 712 // map. Instead, we check against the map in the holder. |
| 709 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { | 713 if (object->IsNumber() || object->IsBoolean() || object->IsString()) { |
| 710 object = holder; | 714 object = holder; |
| 711 } | 715 } |
| 712 | 716 |
| 713 Code::Flags flags = | 717 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, |
| 714 Code::ComputeMonomorphicFlags(kind, | 718 INTERCEPTOR, |
| 715 INTERCEPTOR, | 719 Code::kNoExtraICState, |
| 716 cache_holder, | 720 cache_holder, |
| 717 NOT_IN_LOOP, | 721 NOT_IN_LOOP, |
| 718 argc); | 722 argc); |
| 719 Object* code = map_holder->map()->FindInCodeCache(name, flags); | 723 Object* code = map_holder->map()->FindInCodeCache(name, flags); |
| 720 if (code->IsUndefined()) { | 724 if (code->IsUndefined()) { |
| 721 CallStubCompiler compiler(argc, NOT_IN_LOOP, kind, cache_holder); | 725 CallStubCompiler compiler( |
| 726 argc, NOT_IN_LOOP, kind, Code::kNoExtraICState, cache_holder); |
| 722 { MaybeObject* maybe_code = | 727 { MaybeObject* maybe_code = |
| 723 compiler.CompileCallInterceptor(JSObject::cast(object), holder, name); | 728 compiler.CompileCallInterceptor(JSObject::cast(object), holder, name); |
| 724 if (!maybe_code->ToObject(&code)) return maybe_code; | 729 if (!maybe_code->ToObject(&code)) return maybe_code; |
| 725 } | 730 } |
| 726 ASSERT_EQ(flags, Code::cast(code)->flags()); | 731 ASSERT_EQ(flags, Code::cast(code)->flags()); |
| 727 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 732 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
| 728 Code::cast(code), name)); | 733 Code::cast(code), name)); |
| 729 Object* result; | 734 Object* result; |
| 730 { MaybeObject* maybe_result = | 735 { MaybeObject* maybe_result = |
| 731 map_holder->UpdateMapCodeCache(name, Code::cast(code)); | 736 map_holder->UpdateMapCodeCache(name, Code::cast(code)); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 753 InLoopFlag in_loop, | 758 InLoopFlag in_loop, |
| 754 Code::Kind kind, | 759 Code::Kind kind, |
| 755 String* name, | 760 String* name, |
| 756 JSObject* receiver, | 761 JSObject* receiver, |
| 757 GlobalObject* holder, | 762 GlobalObject* holder, |
| 758 JSGlobalPropertyCell* cell, | 763 JSGlobalPropertyCell* cell, |
| 759 JSFunction* function) { | 764 JSFunction* function) { |
| 760 InlineCacheHolderFlag cache_holder = | 765 InlineCacheHolderFlag cache_holder = |
| 761 IC::GetCodeCacheForObject(receiver, holder); | 766 IC::GetCodeCacheForObject(receiver, holder); |
| 762 JSObject* map_holder = IC::GetCodeCacheHolder(receiver, cache_holder); | 767 JSObject* map_holder = IC::GetCodeCacheHolder(receiver, cache_holder); |
| 763 Code::Flags flags = | 768 Code::Flags flags = Code::ComputeMonomorphicFlags(kind, |
| 764 Code::ComputeMonomorphicFlags(kind, | 769 NORMAL, |
| 765 NORMAL, | 770 Code::kNoExtraICState, |
| 766 cache_holder, | 771 cache_holder, |
| 767 in_loop, | 772 in_loop, |
| 768 argc); | 773 argc); |
| 769 Object* code = map_holder->map()->FindInCodeCache(name, flags); | 774 Object* code = map_holder->map()->FindInCodeCache(name, flags); |
| 770 if (code->IsUndefined()) { | 775 if (code->IsUndefined()) { |
| 771 // If the function hasn't been compiled yet, we cannot do it now | 776 // If the function hasn't been compiled yet, we cannot do it now |
| 772 // because it may cause GC. To avoid this issue, we return an | 777 // because it may cause GC. To avoid this issue, we return an |
| 773 // internal error which will make sure we do not update any | 778 // internal error which will make sure we do not update any |
| 774 // caches. | 779 // caches. |
| 775 if (!function->is_compiled()) return Failure::InternalError(); | 780 if (!function->is_compiled()) return Failure::InternalError(); |
| 776 CallStubCompiler compiler(argc, in_loop, kind, cache_holder); | 781 CallStubCompiler compiler( |
| 782 argc, in_loop, kind, Code::kNoExtraICState, cache_holder); |
| 777 { MaybeObject* maybe_code = | 783 { MaybeObject* maybe_code = |
| 778 compiler.CompileCallGlobal(receiver, holder, cell, function, name); | 784 compiler.CompileCallGlobal(receiver, holder, cell, function, name); |
| 779 if (!maybe_code->ToObject(&code)) return maybe_code; | 785 if (!maybe_code->ToObject(&code)) return maybe_code; |
| 780 } | 786 } |
| 781 ASSERT_EQ(flags, Code::cast(code)->flags()); | 787 ASSERT_EQ(flags, Code::cast(code)->flags()); |
| 782 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), | 788 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_IC_TAG), |
| 783 Code::cast(code), name)); | 789 Code::cast(code), name)); |
| 784 Object* result; | 790 Object* result; |
| 785 { MaybeObject* maybe_result = | 791 { MaybeObject* maybe_result = |
| 786 map_holder->UpdateMapCodeCache(name, Code::cast(code)); | 792 map_holder->UpdateMapCodeCache(name, Code::cast(code)); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 832 CHECK(GetProbeValue(Code::cast(code)->flags()) == code); | 838 CHECK(GetProbeValue(Code::cast(code)->flags()) == code); |
| 833 } | 839 } |
| 834 } | 840 } |
| 835 return maybe_code; | 841 return maybe_code; |
| 836 } | 842 } |
| 837 | 843 |
| 838 | 844 |
| 839 Code* StubCache::FindCallInitialize(int argc, | 845 Code* StubCache::FindCallInitialize(int argc, |
| 840 InLoopFlag in_loop, | 846 InLoopFlag in_loop, |
| 841 Code::Kind kind) { | 847 Code::Kind kind) { |
| 842 Code::Flags flags = | 848 Code::Flags flags = Code::ComputeFlags(kind, |
| 843 Code::ComputeFlags(kind, in_loop, UNINITIALIZED, NORMAL, argc); | 849 in_loop, |
| 850 UNINITIALIZED, |
| 851 Code::kNoExtraICState, |
| 852 NORMAL, |
| 853 argc); |
| 844 Object* result = ProbeCache(flags)->ToObjectUnchecked(); | 854 Object* result = ProbeCache(flags)->ToObjectUnchecked(); |
| 845 ASSERT(!result->IsUndefined()); | 855 ASSERT(!result->IsUndefined()); |
| 846 // This might be called during the marking phase of the collector | 856 // This might be called during the marking phase of the collector |
| 847 // hence the unchecked cast. | 857 // hence the unchecked cast. |
| 848 return reinterpret_cast<Code*>(result); | 858 return reinterpret_cast<Code*>(result); |
| 849 } | 859 } |
| 850 | 860 |
| 851 | 861 |
| 852 MaybeObject* StubCache::ComputeCallInitialize(int argc, | 862 MaybeObject* StubCache::ComputeCallInitialize(int argc, |
| 853 InLoopFlag in_loop, | 863 InLoopFlag in_loop, |
| 854 Code::Kind kind) { | 864 Code::Kind kind) { |
| 855 Code::Flags flags = | 865 Code::Flags flags = Code::ComputeFlags(kind, |
| 856 Code::ComputeFlags(kind, in_loop, UNINITIALIZED, NORMAL, argc); | 866 in_loop, |
| 867 UNINITIALIZED, |
| 868 Code::kNoExtraICState, |
| 869 NORMAL, |
| 870 argc); |
| 857 Object* probe; | 871 Object* probe; |
| 858 { MaybeObject* maybe_probe = ProbeCache(flags); | 872 { MaybeObject* maybe_probe = ProbeCache(flags); |
| 859 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 873 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
| 860 } | 874 } |
| 861 if (!probe->IsUndefined()) return probe; | 875 if (!probe->IsUndefined()) return probe; |
| 862 StubCompiler compiler; | 876 StubCompiler compiler; |
| 863 return FillCache(compiler.CompileCallInitialize(flags)); | 877 return FillCache(compiler.CompileCallInitialize(flags)); |
| 864 } | 878 } |
| 865 | 879 |
| 866 | 880 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 888 ComputeKeyedCallInitialize(argc, NOT_IN_LOOP); | 902 ComputeKeyedCallInitialize(argc, NOT_IN_LOOP); |
| 889 } | 903 } |
| 890 CALL_HEAP_FUNCTION( | 904 CALL_HEAP_FUNCTION( |
| 891 ComputeCallInitialize(argc, in_loop, Code::KEYED_CALL_IC), Code); | 905 ComputeCallInitialize(argc, in_loop, Code::KEYED_CALL_IC), Code); |
| 892 } | 906 } |
| 893 | 907 |
| 894 | 908 |
| 895 MaybeObject* StubCache::ComputeCallPreMonomorphic(int argc, | 909 MaybeObject* StubCache::ComputeCallPreMonomorphic(int argc, |
| 896 InLoopFlag in_loop, | 910 InLoopFlag in_loop, |
| 897 Code::Kind kind) { | 911 Code::Kind kind) { |
| 898 Code::Flags flags = | 912 Code::Flags flags = Code::ComputeFlags(kind, |
| 899 Code::ComputeFlags(kind, in_loop, PREMONOMORPHIC, NORMAL, argc); | 913 in_loop, |
| 914 PREMONOMORPHIC, |
| 915 Code::kNoExtraICState, |
| 916 NORMAL, |
| 917 argc); |
| 900 Object* probe; | 918 Object* probe; |
| 901 { MaybeObject* maybe_probe = ProbeCache(flags); | 919 { MaybeObject* maybe_probe = ProbeCache(flags); |
| 902 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 920 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
| 903 } | 921 } |
| 904 if (!probe->IsUndefined()) return probe; | 922 if (!probe->IsUndefined()) return probe; |
| 905 StubCompiler compiler; | 923 StubCompiler compiler; |
| 906 return FillCache(compiler.CompileCallPreMonomorphic(flags)); | 924 return FillCache(compiler.CompileCallPreMonomorphic(flags)); |
| 907 } | 925 } |
| 908 | 926 |
| 909 | 927 |
| 910 MaybeObject* StubCache::ComputeCallNormal(int argc, | 928 MaybeObject* StubCache::ComputeCallNormal(int argc, |
| 911 InLoopFlag in_loop, | 929 InLoopFlag in_loop, |
| 912 Code::Kind kind) { | 930 Code::Kind kind) { |
| 913 Code::Flags flags = | 931 Code::Flags flags = Code::ComputeFlags(kind, |
| 914 Code::ComputeFlags(kind, in_loop, MONOMORPHIC, NORMAL, argc); | 932 in_loop, |
| 933 MONOMORPHIC, |
| 934 Code::kNoExtraICState, |
| 935 NORMAL, |
| 936 argc); |
| 915 Object* probe; | 937 Object* probe; |
| 916 { MaybeObject* maybe_probe = ProbeCache(flags); | 938 { MaybeObject* maybe_probe = ProbeCache(flags); |
| 917 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 939 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
| 918 } | 940 } |
| 919 if (!probe->IsUndefined()) return probe; | 941 if (!probe->IsUndefined()) return probe; |
| 920 StubCompiler compiler; | 942 StubCompiler compiler; |
| 921 return FillCache(compiler.CompileCallNormal(flags)); | 943 return FillCache(compiler.CompileCallNormal(flags)); |
| 922 } | 944 } |
| 923 | 945 |
| 924 | 946 |
| 925 MaybeObject* StubCache::ComputeCallMegamorphic(int argc, | 947 MaybeObject* StubCache::ComputeCallMegamorphic(int argc, |
| 926 InLoopFlag in_loop, | 948 InLoopFlag in_loop, |
| 927 Code::Kind kind) { | 949 Code::Kind kind) { |
| 928 Code::Flags flags = | 950 Code::Flags flags = Code::ComputeFlags(kind, |
| 929 Code::ComputeFlags(kind, in_loop, MEGAMORPHIC, NORMAL, argc); | 951 in_loop, |
| 952 MEGAMORPHIC, |
| 953 Code::kNoExtraICState, |
| 954 NORMAL, |
| 955 argc); |
| 930 Object* probe; | 956 Object* probe; |
| 931 { MaybeObject* maybe_probe = ProbeCache(flags); | 957 { MaybeObject* maybe_probe = ProbeCache(flags); |
| 932 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 958 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
| 933 } | 959 } |
| 934 if (!probe->IsUndefined()) return probe; | 960 if (!probe->IsUndefined()) return probe; |
| 935 StubCompiler compiler; | 961 StubCompiler compiler; |
| 936 return FillCache(compiler.CompileCallMegamorphic(flags)); | 962 return FillCache(compiler.CompileCallMegamorphic(flags)); |
| 937 } | 963 } |
| 938 | 964 |
| 939 | 965 |
| 940 MaybeObject* StubCache::ComputeCallMiss(int argc, Code::Kind kind) { | 966 MaybeObject* StubCache::ComputeCallMiss(int argc, |
| 967 Code::Kind kind, |
| 968 Code::ExtraICState extra_ic_state) { |
| 941 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs | 969 // MONOMORPHIC_PROTOTYPE_FAILURE state is used to make sure that miss stubs |
| 942 // and monomorphic stubs are not mixed up together in the stub cache. | 970 // and monomorphic stubs are not mixed up together in the stub cache. |
| 943 Code::Flags flags = Code::ComputeFlags( | 971 Code::Flags flags = Code::ComputeFlags(kind, |
| 944 kind, NOT_IN_LOOP, MONOMORPHIC_PROTOTYPE_FAILURE, NORMAL, argc); | 972 NOT_IN_LOOP, |
| 973 MONOMORPHIC_PROTOTYPE_FAILURE, |
| 974 extra_ic_state, |
| 975 NORMAL, |
| 976 argc, |
| 977 OWN_MAP); |
| 945 Object* probe; | 978 Object* probe; |
| 946 { MaybeObject* maybe_probe = ProbeCache(flags); | 979 { MaybeObject* maybe_probe = ProbeCache(flags); |
| 947 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 980 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
| 948 } | 981 } |
| 949 if (!probe->IsUndefined()) return probe; | 982 if (!probe->IsUndefined()) return probe; |
| 950 StubCompiler compiler; | 983 StubCompiler compiler; |
| 951 return FillCache(compiler.CompileCallMiss(flags)); | 984 return FillCache(compiler.CompileCallMiss(flags)); |
| 952 } | 985 } |
| 953 | 986 |
| 954 | 987 |
| 955 #ifdef ENABLE_DEBUGGER_SUPPORT | 988 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 956 MaybeObject* StubCache::ComputeCallDebugBreak(int argc, Code::Kind kind) { | 989 MaybeObject* StubCache::ComputeCallDebugBreak(int argc, Code::Kind kind) { |
| 957 Code::Flags flags = | 990 Code::Flags flags = Code::ComputeFlags(kind, |
| 958 Code::ComputeFlags(kind, NOT_IN_LOOP, DEBUG_BREAK, NORMAL, argc); | 991 NOT_IN_LOOP, |
| 992 DEBUG_BREAK, |
| 993 Code::kNoExtraICState, |
| 994 NORMAL, |
| 995 argc); |
| 959 Object* probe; | 996 Object* probe; |
| 960 { MaybeObject* maybe_probe = ProbeCache(flags); | 997 { MaybeObject* maybe_probe = ProbeCache(flags); |
| 961 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 998 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
| 962 } | 999 } |
| 963 if (!probe->IsUndefined()) return probe; | 1000 if (!probe->IsUndefined()) return probe; |
| 964 StubCompiler compiler; | 1001 StubCompiler compiler; |
| 965 return FillCache(compiler.CompileCallDebugBreak(flags)); | 1002 return FillCache(compiler.CompileCallDebugBreak(flags)); |
| 966 } | 1003 } |
| 967 | 1004 |
| 968 | 1005 |
| 969 MaybeObject* StubCache::ComputeCallDebugPrepareStepIn(int argc, | 1006 MaybeObject* StubCache::ComputeCallDebugPrepareStepIn(int argc, |
| 970 Code::Kind kind) { | 1007 Code::Kind kind) { |
| 971 Code::Flags flags = | 1008 Code::Flags flags = Code::ComputeFlags(kind, |
| 972 Code::ComputeFlags(kind, | 1009 NOT_IN_LOOP, |
| 973 NOT_IN_LOOP, | 1010 DEBUG_PREPARE_STEP_IN, |
| 974 DEBUG_PREPARE_STEP_IN, | 1011 Code::kNoExtraICState, |
| 975 NORMAL, | 1012 NORMAL, |
| 976 argc); | 1013 argc); |
| 977 Object* probe; | 1014 Object* probe; |
| 978 { MaybeObject* maybe_probe = ProbeCache(flags); | 1015 { MaybeObject* maybe_probe = ProbeCache(flags); |
| 979 if (!maybe_probe->ToObject(&probe)) return maybe_probe; | 1016 if (!maybe_probe->ToObject(&probe)) return maybe_probe; |
| 980 } | 1017 } |
| 981 if (!probe->IsUndefined()) return probe; | 1018 if (!probe->IsUndefined()) return probe; |
| 982 StubCompiler compiler; | 1019 StubCompiler compiler; |
| 983 return FillCache(compiler.CompileCallDebugPrepareStepIn(flags)); | 1020 return FillCache(compiler.CompileCallDebugPrepareStepIn(flags)); |
| 984 } | 1021 } |
| 985 #endif | 1022 #endif |
| 986 | 1023 |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1329 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), | 1366 PROFILE(CodeCreateEvent(CALL_LOGGER_TAG(kind, CALL_MEGAMORPHIC_TAG), |
| 1330 code, code->arguments_count())); | 1367 code, code->arguments_count())); |
| 1331 return result; | 1368 return result; |
| 1332 } | 1369 } |
| 1333 | 1370 |
| 1334 | 1371 |
| 1335 MaybeObject* StubCompiler::CompileCallMiss(Code::Flags flags) { | 1372 MaybeObject* StubCompiler::CompileCallMiss(Code::Flags flags) { |
| 1336 HandleScope scope; | 1373 HandleScope scope; |
| 1337 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1374 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 1338 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1375 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1376 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); |
| 1339 if (kind == Code::CALL_IC) { | 1377 if (kind == Code::CALL_IC) { |
| 1340 CallIC::GenerateMiss(masm(), argc); | 1378 CallIC::GenerateMiss(masm(), extra_ic_state, argc); |
| 1341 } else { | 1379 } else { |
| 1342 KeyedCallIC::GenerateMiss(masm(), argc); | 1380 KeyedCallIC::GenerateMiss(masm(), argc); |
| 1343 } | 1381 } |
| 1344 Object* result; | 1382 Object* result; |
| 1345 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallMiss"); | 1383 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "CompileCallMiss"); |
| 1346 if (!maybe_result->ToObject(&result)) return maybe_result; | 1384 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1347 } | 1385 } |
| 1348 Counters::call_megamorphic_stubs.Increment(); | 1386 Counters::call_megamorphic_stubs.Increment(); |
| 1349 Code* code = Code::cast(result); | 1387 Code* code = Code::cast(result); |
| 1350 USE(code); | 1388 USE(code); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1372 return result; | 1410 return result; |
| 1373 } | 1411 } |
| 1374 | 1412 |
| 1375 | 1413 |
| 1376 MaybeObject* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { | 1414 MaybeObject* StubCompiler::CompileCallDebugPrepareStepIn(Code::Flags flags) { |
| 1377 HandleScope scope; | 1415 HandleScope scope; |
| 1378 // Use the same code for the the step in preparations as we do for | 1416 // Use the same code for the the step in preparations as we do for |
| 1379 // the miss case. | 1417 // the miss case. |
| 1380 int argc = Code::ExtractArgumentsCountFromFlags(flags); | 1418 int argc = Code::ExtractArgumentsCountFromFlags(flags); |
| 1381 Code::Kind kind = Code::ExtractKindFromFlags(flags); | 1419 Code::Kind kind = Code::ExtractKindFromFlags(flags); |
| 1420 Code::ExtraICState extra_ic_state = Code::ExtractExtraICStateFromFlags(flags); |
| 1382 if (kind == Code::CALL_IC) { | 1421 if (kind == Code::CALL_IC) { |
| 1383 CallIC::GenerateMiss(masm(), argc); | 1422 CallIC::GenerateMiss(masm(), extra_ic_state, argc); |
| 1384 } else { | 1423 } else { |
| 1385 KeyedCallIC::GenerateMiss(masm(), argc); | 1424 KeyedCallIC::GenerateMiss(masm(), argc); |
| 1386 } | 1425 } |
| 1387 Object* result; | 1426 Object* result; |
| 1388 { MaybeObject* maybe_result = | 1427 { MaybeObject* maybe_result = |
| 1389 GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); | 1428 GetCodeWithFlags(flags, "CompileCallDebugPrepareStepIn"); |
| 1390 if (!maybe_result->ToObject(&result)) return maybe_result; | 1429 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1391 } | 1430 } |
| 1392 Code* code = Code::cast(result); | 1431 Code* code = Code::cast(result); |
| 1393 USE(code); | 1432 USE(code); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1486 Code::cast(result->ToObjectUnchecked()), | 1525 Code::cast(result->ToObjectUnchecked()), |
| 1487 name)); | 1526 name)); |
| 1488 } | 1527 } |
| 1489 return result; | 1528 return result; |
| 1490 } | 1529 } |
| 1491 | 1530 |
| 1492 | 1531 |
| 1493 CallStubCompiler::CallStubCompiler(int argc, | 1532 CallStubCompiler::CallStubCompiler(int argc, |
| 1494 InLoopFlag in_loop, | 1533 InLoopFlag in_loop, |
| 1495 Code::Kind kind, | 1534 Code::Kind kind, |
| 1535 Code::ExtraICState extra_ic_state, |
| 1496 InlineCacheHolderFlag cache_holder) | 1536 InlineCacheHolderFlag cache_holder) |
| 1497 : arguments_(argc) | 1537 : arguments_(argc), |
| 1498 , in_loop_(in_loop) | 1538 in_loop_(in_loop), |
| 1499 , kind_(kind) | 1539 kind_(kind), |
| 1500 , cache_holder_(cache_holder) { | 1540 extra_ic_state_(extra_ic_state), |
| 1541 cache_holder_(cache_holder) { |
| 1501 } | 1542 } |
| 1502 | 1543 |
| 1503 | 1544 |
| 1504 bool CallStubCompiler::HasCustomCallGenerator(BuiltinFunctionId id) { | 1545 bool CallStubCompiler::HasCustomCallGenerator(BuiltinFunctionId id) { |
| 1505 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true; | 1546 #define CALL_GENERATOR_CASE(name) if (id == k##name) return true; |
| 1506 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) | 1547 CUSTOM_CALL_IC_GENERATORS(CALL_GENERATOR_CASE) |
| 1507 #undef CALL_GENERATOR_CASE | 1548 #undef CALL_GENERATOR_CASE |
| 1508 return false; | 1549 return false; |
| 1509 } | 1550 } |
| 1510 | 1551 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1527 #undef CALL_GENERATOR_CASE | 1568 #undef CALL_GENERATOR_CASE |
| 1528 ASSERT(!HasCustomCallGenerator(id)); | 1569 ASSERT(!HasCustomCallGenerator(id)); |
| 1529 return Heap::undefined_value(); | 1570 return Heap::undefined_value(); |
| 1530 } | 1571 } |
| 1531 | 1572 |
| 1532 | 1573 |
| 1533 MaybeObject* CallStubCompiler::GetCode(PropertyType type, String* name) { | 1574 MaybeObject* CallStubCompiler::GetCode(PropertyType type, String* name) { |
| 1534 int argc = arguments_.immediate(); | 1575 int argc = arguments_.immediate(); |
| 1535 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, | 1576 Code::Flags flags = Code::ComputeMonomorphicFlags(kind_, |
| 1536 type, | 1577 type, |
| 1578 extra_ic_state_, |
| 1537 cache_holder_, | 1579 cache_holder_, |
| 1538 in_loop_, | 1580 in_loop_, |
| 1539 argc); | 1581 argc); |
| 1540 return GetCodeWithFlags(flags, name); | 1582 return GetCodeWithFlags(flags, name); |
| 1541 } | 1583 } |
| 1542 | 1584 |
| 1543 | 1585 |
| 1544 MaybeObject* CallStubCompiler::GetCode(JSFunction* function) { | 1586 MaybeObject* CallStubCompiler::GetCode(JSFunction* function) { |
| 1545 String* function_name = NULL; | 1587 String* function_name = NULL; |
| 1546 if (function->shared()->name()->IsString()) { | 1588 if (function->shared()->name()->IsString()) { |
| 1547 function_name = String::cast(function->shared()->name()); | 1589 function_name = String::cast(function->shared()->name()); |
| 1548 } | 1590 } |
| 1549 return GetCode(CONSTANT_FUNCTION, function_name); | 1591 return GetCode(CONSTANT_FUNCTION, function_name); |
| 1550 } | 1592 } |
| 1551 | 1593 |
| 1552 | 1594 |
| 1595 MaybeObject* CallStubCompiler::GenerateMissBranch() { |
| 1596 return GenerateBranchHelper(extra_ic_state_); |
| 1597 } |
| 1598 |
| 1599 |
| 1600 MaybeObject* CallStubCompiler::GenerateExtraStateChangeBranch( |
| 1601 Code::ExtraICState new_extra_ic_state) { |
| 1602 ASSERT(extra_ic_state_ != new_extra_ic_state); |
| 1603 return GenerateBranchHelper(new_extra_ic_state); |
| 1604 } |
| 1605 |
| 1606 |
| 1553 MaybeObject* ConstructStubCompiler::GetCode() { | 1607 MaybeObject* ConstructStubCompiler::GetCode() { |
| 1554 Code::Flags flags = Code::ComputeFlags(Code::STUB); | 1608 Code::Flags flags = Code::ComputeFlags(Code::STUB); |
| 1555 Object* result; | 1609 Object* result; |
| 1556 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "ConstructStub"); | 1610 { MaybeObject* maybe_result = GetCodeWithFlags(flags, "ConstructStub"); |
| 1557 if (!maybe_result->ToObject(&result)) return maybe_result; | 1611 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1558 } | 1612 } |
| 1559 Code* code = Code::cast(result); | 1613 Code* code = Code::cast(result); |
| 1560 USE(code); | 1614 USE(code); |
| 1561 PROFILE(CodeCreateEvent(Logger::STUB_TAG, code, "ConstructStub")); | 1615 PROFILE(CodeCreateEvent(Logger::STUB_TAG, code, "ConstructStub")); |
| 1562 return result; | 1616 return result; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1624 expected_receiver_type_ = | 1678 expected_receiver_type_ = |
| 1625 FunctionTemplateInfo::cast(signature->receiver()); | 1679 FunctionTemplateInfo::cast(signature->receiver()); |
| 1626 } | 1680 } |
| 1627 } | 1681 } |
| 1628 | 1682 |
| 1629 is_simple_api_call_ = true; | 1683 is_simple_api_call_ = true; |
| 1630 } | 1684 } |
| 1631 | 1685 |
| 1632 | 1686 |
| 1633 } } // namespace v8::internal | 1687 } } // namespace v8::internal |
| OLD | NEW |