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 2677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2688 | 2688 |
2689 // Return the generated code. | 2689 // Return the generated code. |
2690 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC); | 2690 return GetCode(NORMAL, factory()->empty_string(), MEGAMORPHIC); |
2691 } | 2691 } |
2692 | 2692 |
2693 | 2693 |
2694 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name, | 2694 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(Handle<String> name, |
2695 Handle<JSObject> object, | 2695 Handle<JSObject> object, |
2696 Handle<JSObject> last) { | 2696 Handle<JSObject> last) { |
2697 // ----------- S t a t e ------------- | 2697 // ----------- S t a t e ------------- |
2698 // -- eax : receiver | |
2699 // -- ecx : name | 2698 // -- ecx : name |
| 2699 // -- edx : receiver |
2700 // -- esp[0] : return address | 2700 // -- esp[0] : return address |
2701 // ----------------------------------- | 2701 // ----------------------------------- |
2702 Label miss; | 2702 Label miss; |
2703 | 2703 |
2704 // Check that the receiver isn't a smi. | 2704 // Check that the receiver isn't a smi. |
2705 __ JumpIfSmi(eax, &miss); | 2705 __ JumpIfSmi(edx, &miss); |
2706 | 2706 |
2707 ASSERT(last->IsGlobalObject() || last->HasFastProperties()); | 2707 ASSERT(last->IsGlobalObject() || last->HasFastProperties()); |
2708 | 2708 |
2709 // Check the maps of the full prototype chain. Also check that | 2709 // Check the maps of the full prototype chain. Also check that |
2710 // global property cells up to (but not including) the last object | 2710 // global property cells up to (but not including) the last object |
2711 // in the prototype chain are empty. | 2711 // in the prototype chain are empty. |
2712 CheckPrototypes(object, eax, last, ebx, edx, edi, name, &miss); | 2712 CheckPrototypes(object, edx, last, ebx, eax, edi, name, &miss); |
2713 | 2713 |
2714 // If the last object in the prototype chain is a global object, | 2714 // If the last object in the prototype chain is a global object, |
2715 // check that the global property cell is empty. | 2715 // check that the global property cell is empty. |
2716 if (last->IsGlobalObject()) { | 2716 if (last->IsGlobalObject()) { |
2717 GenerateCheckPropertyCell( | 2717 GenerateCheckPropertyCell( |
2718 masm(), Handle<GlobalObject>::cast(last), name, edx, &miss); | 2718 masm(), Handle<GlobalObject>::cast(last), name, eax, &miss); |
2719 } | 2719 } |
2720 | 2720 |
2721 // Return undefined if maps of the full prototype chain are still the | 2721 // Return undefined if maps of the full prototype chain are still the |
2722 // same and no global property with this name contains a value. | 2722 // same and no global property with this name contains a value. |
2723 __ mov(eax, isolate()->factory()->undefined_value()); | 2723 __ mov(eax, isolate()->factory()->undefined_value()); |
2724 __ ret(0); | 2724 __ ret(0); |
2725 | 2725 |
2726 __ bind(&miss); | 2726 __ bind(&miss); |
2727 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2727 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2728 | 2728 |
2729 // Return the generated code. | 2729 // Return the generated code. |
2730 return GetCode(NONEXISTENT, factory()->empty_string()); | 2730 return GetCode(NONEXISTENT, factory()->empty_string()); |
2731 } | 2731 } |
2732 | 2732 |
2733 | 2733 |
2734 Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object, | 2734 Handle<Code> LoadStubCompiler::CompileLoadField(Handle<JSObject> object, |
2735 Handle<JSObject> holder, | 2735 Handle<JSObject> holder, |
2736 int index, | 2736 int index, |
2737 Handle<String> name) { | 2737 Handle<String> name) { |
2738 // ----------- S t a t e ------------- | 2738 // ----------- S t a t e ------------- |
2739 // -- eax : receiver | |
2740 // -- ecx : name | 2739 // -- ecx : name |
| 2740 // -- edx : receiver |
2741 // -- esp[0] : return address | 2741 // -- esp[0] : return address |
2742 // ----------------------------------- | 2742 // ----------------------------------- |
2743 Label miss; | 2743 Label miss; |
2744 | 2744 |
2745 GenerateLoadField(object, holder, eax, ebx, edx, edi, index, name, &miss); | 2745 GenerateLoadField(object, holder, edx, ebx, eax, edi, index, name, &miss); |
2746 __ bind(&miss); | 2746 __ bind(&miss); |
2747 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2747 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2748 | 2748 |
2749 // Return the generated code. | 2749 // Return the generated code. |
2750 return GetCode(FIELD, name); | 2750 return GetCode(FIELD, name); |
2751 } | 2751 } |
2752 | 2752 |
2753 | 2753 |
2754 Handle<Code> LoadStubCompiler::CompileLoadCallback( | 2754 Handle<Code> LoadStubCompiler::CompileLoadCallback( |
2755 Handle<String> name, | 2755 Handle<String> name, |
2756 Handle<JSObject> object, | 2756 Handle<JSObject> object, |
2757 Handle<JSObject> holder, | 2757 Handle<JSObject> holder, |
2758 Handle<AccessorInfo> callback) { | 2758 Handle<AccessorInfo> callback) { |
2759 // ----------- S t a t e ------------- | 2759 // ----------- S t a t e ------------- |
2760 // -- eax : receiver | |
2761 // -- ecx : name | 2760 // -- ecx : name |
| 2761 // -- edx : receiver |
2762 // -- esp[0] : return address | 2762 // -- esp[0] : return address |
2763 // ----------------------------------- | 2763 // ----------------------------------- |
2764 Label miss; | 2764 Label miss; |
2765 | 2765 |
2766 GenerateLoadCallback(object, holder, eax, ecx, ebx, edx, edi, callback, | 2766 GenerateLoadCallback(object, holder, edx, ecx, ebx, eax, edi, callback, |
2767 name, &miss); | 2767 name, &miss); |
2768 __ bind(&miss); | 2768 __ bind(&miss); |
2769 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2769 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2770 | 2770 |
2771 // Return the generated code. | 2771 // Return the generated code. |
2772 return GetCode(CALLBACKS, name); | 2772 return GetCode(CALLBACKS, name); |
2773 } | 2773 } |
2774 | 2774 |
2775 | 2775 |
2776 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object, | 2776 Handle<Code> LoadStubCompiler::CompileLoadConstant(Handle<JSObject> object, |
2777 Handle<JSObject> holder, | 2777 Handle<JSObject> holder, |
2778 Handle<JSFunction> value, | 2778 Handle<JSFunction> value, |
2779 Handle<String> name) { | 2779 Handle<String> name) { |
2780 // ----------- S t a t e ------------- | 2780 // ----------- S t a t e ------------- |
2781 // -- eax : receiver | |
2782 // -- ecx : name | 2781 // -- ecx : name |
| 2782 // -- edx : receiver |
2783 // -- esp[0] : return address | 2783 // -- esp[0] : return address |
2784 // ----------------------------------- | 2784 // ----------------------------------- |
2785 Label miss; | 2785 Label miss; |
2786 | 2786 |
2787 GenerateLoadConstant(object, holder, eax, ebx, edx, edi, value, name, &miss); | 2787 GenerateLoadConstant(object, holder, edx, ebx, eax, edi, value, name, &miss); |
2788 __ bind(&miss); | 2788 __ bind(&miss); |
2789 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2789 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2790 | 2790 |
2791 // Return the generated code. | 2791 // Return the generated code. |
2792 return GetCode(CONSTANT_FUNCTION, name); | 2792 return GetCode(CONSTANT_FUNCTION, name); |
2793 } | 2793 } |
2794 | 2794 |
2795 | 2795 |
2796 Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> receiver, | 2796 Handle<Code> LoadStubCompiler::CompileLoadInterceptor(Handle<JSObject> receiver, |
2797 Handle<JSObject> holder, | 2797 Handle<JSObject> holder, |
2798 Handle<String> name) { | 2798 Handle<String> name) { |
2799 // ----------- S t a t e ------------- | 2799 // ----------- S t a t e ------------- |
2800 // -- eax : receiver | |
2801 // -- ecx : name | 2800 // -- ecx : name |
| 2801 // -- edx : receiver |
2802 // -- esp[0] : return address | 2802 // -- esp[0] : return address |
2803 // ----------------------------------- | 2803 // ----------------------------------- |
2804 Label miss; | 2804 Label miss; |
2805 | 2805 |
2806 LookupResult lookup(isolate()); | 2806 LookupResult lookup(isolate()); |
2807 LookupPostInterceptor(holder, name, &lookup); | 2807 LookupPostInterceptor(holder, name, &lookup); |
2808 | 2808 |
2809 // TODO(368): Compile in the whole chain: all the interceptors in | 2809 // TODO(368): Compile in the whole chain: all the interceptors in |
2810 // prototypes and ultimate answer. | 2810 // prototypes and ultimate answer. |
2811 GenerateLoadInterceptor(receiver, holder, &lookup, eax, ecx, edx, ebx, edi, | 2811 GenerateLoadInterceptor(receiver, holder, &lookup, edx, ecx, eax, ebx, edi, |
2812 name, &miss); | 2812 name, &miss); |
2813 | 2813 |
2814 __ bind(&miss); | 2814 __ bind(&miss); |
2815 GenerateLoadMiss(masm(), Code::LOAD_IC); | 2815 GenerateLoadMiss(masm(), Code::LOAD_IC); |
2816 | 2816 |
2817 // Return the generated code. | 2817 // Return the generated code. |
2818 return GetCode(INTERCEPTOR, name); | 2818 return GetCode(INTERCEPTOR, name); |
2819 } | 2819 } |
2820 | 2820 |
2821 | 2821 |
2822 Handle<Code> LoadStubCompiler::CompileLoadGlobal( | 2822 Handle<Code> LoadStubCompiler::CompileLoadGlobal( |
2823 Handle<JSObject> object, | 2823 Handle<JSObject> object, |
2824 Handle<GlobalObject> holder, | 2824 Handle<GlobalObject> holder, |
2825 Handle<JSGlobalPropertyCell> cell, | 2825 Handle<JSGlobalPropertyCell> cell, |
2826 Handle<String> name, | 2826 Handle<String> name, |
2827 bool is_dont_delete) { | 2827 bool is_dont_delete) { |
2828 // ----------- S t a t e ------------- | 2828 // ----------- S t a t e ------------- |
2829 // -- eax : receiver | |
2830 // -- ecx : name | 2829 // -- ecx : name |
| 2830 // -- edx : receiver |
2831 // -- esp[0] : return address | 2831 // -- esp[0] : return address |
2832 // ----------------------------------- | 2832 // ----------------------------------- |
2833 Label miss; | 2833 Label miss; |
2834 | 2834 |
2835 // Check that the maps haven't changed. | 2835 // Check that the maps haven't changed. |
2836 __ JumpIfSmi(eax, &miss); | 2836 __ JumpIfSmi(edx, &miss); |
2837 CheckPrototypes(object, eax, holder, ebx, edx, edi, name, &miss); | 2837 CheckPrototypes(object, edx, holder, ebx, eax, edi, name, &miss); |
2838 | 2838 |
2839 // Get the value from the cell. | 2839 // Get the value from the cell. |
2840 if (Serializer::enabled()) { | 2840 if (Serializer::enabled()) { |
2841 __ mov(ebx, Immediate(cell)); | 2841 __ mov(ebx, Immediate(cell)); |
2842 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); | 2842 __ mov(ebx, FieldOperand(ebx, JSGlobalPropertyCell::kValueOffset)); |
2843 } else { | 2843 } else { |
2844 __ mov(ebx, Operand::Cell(cell)); | 2844 __ mov(ebx, Operand::Cell(cell)); |
2845 } | 2845 } |
2846 | 2846 |
2847 // Check for deleted property if property can actually be deleted. | 2847 // Check for deleted property if property can actually be deleted. |
(...skipping 17 matching lines...) Expand all Loading... |
2865 // Return the generated code. | 2865 // Return the generated code. |
2866 return GetCode(NORMAL, name); | 2866 return GetCode(NORMAL, name); |
2867 } | 2867 } |
2868 | 2868 |
2869 | 2869 |
2870 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, | 2870 Handle<Code> KeyedLoadStubCompiler::CompileLoadField(Handle<String> name, |
2871 Handle<JSObject> receiver, | 2871 Handle<JSObject> receiver, |
2872 Handle<JSObject> holder, | 2872 Handle<JSObject> holder, |
2873 int index) { | 2873 int index) { |
2874 // ----------- S t a t e ------------- | 2874 // ----------- S t a t e ------------- |
2875 // -- eax : key | 2875 // -- ecx : key |
2876 // -- edx : receiver | 2876 // -- edx : receiver |
2877 // -- esp[0] : return address | 2877 // -- esp[0] : return address |
2878 // ----------------------------------- | 2878 // ----------------------------------- |
2879 Label miss; | 2879 Label miss; |
2880 | 2880 |
2881 Counters* counters = isolate()->counters(); | 2881 Counters* counters = isolate()->counters(); |
2882 __ IncrementCounter(counters->keyed_load_field(), 1); | 2882 __ IncrementCounter(counters->keyed_load_field(), 1); |
2883 | 2883 |
2884 // Check that the name has not changed. | 2884 // Check that the name has not changed. |
2885 __ cmp(eax, Immediate(name)); | 2885 __ cmp(ecx, Immediate(name)); |
2886 __ j(not_equal, &miss); | 2886 __ j(not_equal, &miss); |
2887 | 2887 |
2888 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); | 2888 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); |
2889 | 2889 |
2890 __ bind(&miss); | 2890 __ bind(&miss); |
2891 __ DecrementCounter(counters->keyed_load_field(), 1); | 2891 __ DecrementCounter(counters->keyed_load_field(), 1); |
2892 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2892 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2893 | 2893 |
2894 // Return the generated code. | 2894 // Return the generated code. |
2895 return GetCode(FIELD, name); | 2895 return GetCode(FIELD, name); |
2896 } | 2896 } |
2897 | 2897 |
2898 | 2898 |
2899 Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback( | 2899 Handle<Code> KeyedLoadStubCompiler::CompileLoadCallback( |
2900 Handle<String> name, | 2900 Handle<String> name, |
2901 Handle<JSObject> receiver, | 2901 Handle<JSObject> receiver, |
2902 Handle<JSObject> holder, | 2902 Handle<JSObject> holder, |
2903 Handle<AccessorInfo> callback) { | 2903 Handle<AccessorInfo> callback) { |
2904 // ----------- S t a t e ------------- | 2904 // ----------- S t a t e ------------- |
2905 // -- eax : key | 2905 // -- ecx : key |
2906 // -- edx : receiver | 2906 // -- edx : receiver |
2907 // -- esp[0] : return address | 2907 // -- esp[0] : return address |
2908 // ----------------------------------- | 2908 // ----------------------------------- |
2909 Label miss; | 2909 Label miss; |
2910 | 2910 |
2911 Counters* counters = isolate()->counters(); | 2911 Counters* counters = isolate()->counters(); |
2912 __ IncrementCounter(counters->keyed_load_callback(), 1); | 2912 __ IncrementCounter(counters->keyed_load_callback(), 1); |
2913 | 2913 |
2914 // Check that the name has not changed. | 2914 // Check that the name has not changed. |
2915 __ cmp(eax, Immediate(name)); | 2915 __ cmp(ecx, Immediate(name)); |
2916 __ j(not_equal, &miss); | 2916 __ j(not_equal, &miss); |
2917 | 2917 |
2918 GenerateLoadCallback(receiver, holder, edx, eax, ebx, ecx, edi, callback, | 2918 GenerateLoadCallback(receiver, holder, edx, ecx, ebx, eax, edi, callback, |
2919 name, &miss); | 2919 name, &miss); |
2920 | 2920 |
2921 __ bind(&miss); | 2921 __ bind(&miss); |
2922 __ DecrementCounter(counters->keyed_load_callback(), 1); | 2922 __ DecrementCounter(counters->keyed_load_callback(), 1); |
2923 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2923 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2924 | 2924 |
2925 // Return the generated code. | 2925 // Return the generated code. |
2926 return GetCode(CALLBACKS, name); | 2926 return GetCode(CALLBACKS, name); |
2927 } | 2927 } |
2928 | 2928 |
2929 | 2929 |
2930 Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant( | 2930 Handle<Code> KeyedLoadStubCompiler::CompileLoadConstant( |
2931 Handle<String> name, | 2931 Handle<String> name, |
2932 Handle<JSObject> receiver, | 2932 Handle<JSObject> receiver, |
2933 Handle<JSObject> holder, | 2933 Handle<JSObject> holder, |
2934 Handle<JSFunction> value) { | 2934 Handle<JSFunction> value) { |
2935 // ----------- S t a t e ------------- | 2935 // ----------- S t a t e ------------- |
2936 // -- eax : key | 2936 // -- ecx : key |
2937 // -- edx : receiver | 2937 // -- edx : receiver |
2938 // -- esp[0] : return address | 2938 // -- esp[0] : return address |
2939 // ----------------------------------- | 2939 // ----------------------------------- |
2940 Label miss; | 2940 Label miss; |
2941 | 2941 |
2942 Counters* counters = isolate()->counters(); | 2942 Counters* counters = isolate()->counters(); |
2943 __ IncrementCounter(counters->keyed_load_constant_function(), 1); | 2943 __ IncrementCounter(counters->keyed_load_constant_function(), 1); |
2944 | 2944 |
2945 // Check that the name has not changed. | 2945 // Check that the name has not changed. |
2946 __ cmp(eax, Immediate(name)); | 2946 __ cmp(ecx, Immediate(name)); |
2947 __ j(not_equal, &miss); | 2947 __ j(not_equal, &miss); |
2948 | 2948 |
2949 GenerateLoadConstant( | 2949 GenerateLoadConstant( |
2950 receiver, holder, edx, ebx, ecx, edi, value, name, &miss); | 2950 receiver, holder, edx, ebx, eax, edi, value, name, &miss); |
2951 __ bind(&miss); | 2951 __ bind(&miss); |
2952 __ DecrementCounter(counters->keyed_load_constant_function(), 1); | 2952 __ DecrementCounter(counters->keyed_load_constant_function(), 1); |
2953 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2953 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2954 | 2954 |
2955 // Return the generated code. | 2955 // Return the generated code. |
2956 return GetCode(CONSTANT_FUNCTION, name); | 2956 return GetCode(CONSTANT_FUNCTION, name); |
2957 } | 2957 } |
2958 | 2958 |
2959 | 2959 |
2960 Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor( | 2960 Handle<Code> KeyedLoadStubCompiler::CompileLoadInterceptor( |
2961 Handle<JSObject> receiver, | 2961 Handle<JSObject> receiver, |
2962 Handle<JSObject> holder, | 2962 Handle<JSObject> holder, |
2963 Handle<String> name) { | 2963 Handle<String> name) { |
2964 // ----------- S t a t e ------------- | 2964 // ----------- S t a t e ------------- |
2965 // -- eax : key | 2965 // -- ecx : key |
2966 // -- edx : receiver | 2966 // -- edx : receiver |
2967 // -- esp[0] : return address | 2967 // -- esp[0] : return address |
2968 // ----------------------------------- | 2968 // ----------------------------------- |
2969 Label miss; | 2969 Label miss; |
2970 | 2970 |
2971 Counters* counters = isolate()->counters(); | 2971 Counters* counters = isolate()->counters(); |
2972 __ IncrementCounter(counters->keyed_load_interceptor(), 1); | 2972 __ IncrementCounter(counters->keyed_load_interceptor(), 1); |
2973 | 2973 |
2974 // Check that the name has not changed. | 2974 // Check that the name has not changed. |
2975 __ cmp(eax, Immediate(name)); | 2975 __ cmp(ecx, Immediate(name)); |
2976 __ j(not_equal, &miss); | 2976 __ j(not_equal, &miss); |
2977 | 2977 |
2978 LookupResult lookup(isolate()); | 2978 LookupResult lookup(isolate()); |
2979 LookupPostInterceptor(holder, name, &lookup); | 2979 LookupPostInterceptor(holder, name, &lookup); |
2980 GenerateLoadInterceptor(receiver, holder, &lookup, edx, eax, ecx, ebx, edi, | 2980 GenerateLoadInterceptor(receiver, holder, &lookup, edx, ecx, eax, ebx, edi, |
2981 name, &miss); | 2981 name, &miss); |
2982 __ bind(&miss); | 2982 __ bind(&miss); |
2983 __ DecrementCounter(counters->keyed_load_interceptor(), 1); | 2983 __ DecrementCounter(counters->keyed_load_interceptor(), 1); |
2984 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 2984 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
2985 | 2985 |
2986 // Return the generated code. | 2986 // Return the generated code. |
2987 return GetCode(INTERCEPTOR, name); | 2987 return GetCode(INTERCEPTOR, name); |
2988 } | 2988 } |
2989 | 2989 |
2990 | 2990 |
2991 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength( | 2991 Handle<Code> KeyedLoadStubCompiler::CompileLoadArrayLength( |
2992 Handle<String> name) { | 2992 Handle<String> name) { |
2993 // ----------- S t a t e ------------- | 2993 // ----------- S t a t e ------------- |
2994 // -- eax : key | 2994 // -- ecx : key |
2995 // -- edx : receiver | 2995 // -- edx : receiver |
2996 // -- esp[0] : return address | 2996 // -- esp[0] : return address |
2997 // ----------------------------------- | 2997 // ----------------------------------- |
2998 Label miss; | 2998 Label miss; |
2999 | 2999 |
3000 Counters* counters = isolate()->counters(); | 3000 Counters* counters = isolate()->counters(); |
3001 __ IncrementCounter(counters->keyed_load_array_length(), 1); | 3001 __ IncrementCounter(counters->keyed_load_array_length(), 1); |
3002 | 3002 |
3003 // Check that the name has not changed. | 3003 // Check that the name has not changed. |
3004 __ cmp(eax, Immediate(name)); | 3004 __ cmp(ecx, Immediate(name)); |
3005 __ j(not_equal, &miss); | 3005 __ j(not_equal, &miss); |
3006 | 3006 |
3007 GenerateLoadArrayLength(masm(), edx, ecx, &miss); | 3007 GenerateLoadArrayLength(masm(), edx, eax, &miss); |
3008 __ bind(&miss); | 3008 __ bind(&miss); |
3009 __ DecrementCounter(counters->keyed_load_array_length(), 1); | 3009 __ DecrementCounter(counters->keyed_load_array_length(), 1); |
3010 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3010 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3011 | 3011 |
3012 // Return the generated code. | 3012 // Return the generated code. |
3013 return GetCode(CALLBACKS, name); | 3013 return GetCode(CALLBACKS, name); |
3014 } | 3014 } |
3015 | 3015 |
3016 | 3016 |
3017 Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength( | 3017 Handle<Code> KeyedLoadStubCompiler::CompileLoadStringLength( |
3018 Handle<String> name) { | 3018 Handle<String> name) { |
3019 // ----------- S t a t e ------------- | 3019 // ----------- S t a t e ------------- |
3020 // -- eax : key | 3020 // -- ecx : key |
3021 // -- edx : receiver | 3021 // -- edx : receiver |
3022 // -- esp[0] : return address | 3022 // -- esp[0] : return address |
3023 // ----------------------------------- | 3023 // ----------------------------------- |
3024 Label miss; | 3024 Label miss; |
3025 | 3025 |
3026 Counters* counters = isolate()->counters(); | 3026 Counters* counters = isolate()->counters(); |
3027 __ IncrementCounter(counters->keyed_load_string_length(), 1); | 3027 __ IncrementCounter(counters->keyed_load_string_length(), 1); |
3028 | 3028 |
3029 // Check that the name has not changed. | 3029 // Check that the name has not changed. |
3030 __ cmp(eax, Immediate(name)); | 3030 __ cmp(ecx, Immediate(name)); |
3031 __ j(not_equal, &miss); | 3031 __ j(not_equal, &miss); |
3032 | 3032 |
3033 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); | 3033 GenerateLoadStringLength(masm(), edx, eax, ebx, &miss, true); |
3034 __ bind(&miss); | 3034 __ bind(&miss); |
3035 __ DecrementCounter(counters->keyed_load_string_length(), 1); | 3035 __ DecrementCounter(counters->keyed_load_string_length(), 1); |
3036 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3036 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3037 | 3037 |
3038 // Return the generated code. | 3038 // Return the generated code. |
3039 return GetCode(CALLBACKS, name); | 3039 return GetCode(CALLBACKS, name); |
3040 } | 3040 } |
3041 | 3041 |
3042 | 3042 |
3043 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype( | 3043 Handle<Code> KeyedLoadStubCompiler::CompileLoadFunctionPrototype( |
3044 Handle<String> name) { | 3044 Handle<String> name) { |
3045 // ----------- S t a t e ------------- | 3045 // ----------- S t a t e ------------- |
3046 // -- eax : key | 3046 // -- ecx : key |
3047 // -- edx : receiver | 3047 // -- edx : receiver |
3048 // -- esp[0] : return address | 3048 // -- esp[0] : return address |
3049 // ----------------------------------- | 3049 // ----------------------------------- |
3050 Label miss; | 3050 Label miss; |
3051 | 3051 |
3052 Counters* counters = isolate()->counters(); | 3052 Counters* counters = isolate()->counters(); |
3053 __ IncrementCounter(counters->keyed_load_function_prototype(), 1); | 3053 __ IncrementCounter(counters->keyed_load_function_prototype(), 1); |
3054 | 3054 |
3055 // Check that the name has not changed. | 3055 // Check that the name has not changed. |
3056 __ cmp(eax, Immediate(name)); | 3056 __ cmp(ecx, Immediate(name)); |
3057 __ j(not_equal, &miss); | 3057 __ j(not_equal, &miss); |
3058 | 3058 |
3059 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); | 3059 GenerateLoadFunctionPrototype(masm(), edx, eax, ebx, &miss); |
3060 __ bind(&miss); | 3060 __ bind(&miss); |
3061 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); | 3061 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); |
3062 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3062 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3063 | 3063 |
3064 // Return the generated code. | 3064 // Return the generated code. |
3065 return GetCode(CALLBACKS, name); | 3065 return GetCode(CALLBACKS, name); |
3066 } | 3066 } |
3067 | 3067 |
3068 | 3068 |
3069 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( | 3069 Handle<Code> KeyedLoadStubCompiler::CompileLoadElement( |
3070 Handle<Map> receiver_map) { | 3070 Handle<Map> receiver_map) { |
3071 // ----------- S t a t e ------------- | 3071 // ----------- S t a t e ------------- |
3072 // -- eax : key | 3072 // -- ecx : key |
3073 // -- edx : receiver | 3073 // -- edx : receiver |
3074 // -- esp[0] : return address | 3074 // -- esp[0] : return address |
3075 // ----------------------------------- | 3075 // ----------------------------------- |
3076 | 3076 |
3077 ElementsKind elements_kind = receiver_map->elements_kind(); | 3077 ElementsKind elements_kind = receiver_map->elements_kind(); |
3078 Handle<Code> stub = KeyedLoadElementStub(elements_kind).GetCode(); | 3078 Handle<Code> stub = KeyedLoadElementStub(elements_kind).GetCode(); |
3079 | 3079 |
3080 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); | 3080 __ DispatchMap(edx, receiver_map, stub, DO_SMI_CHECK); |
3081 | 3081 |
3082 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 3082 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
3083 | 3083 |
3084 // Return the generated code. | 3084 // Return the generated code. |
3085 return GetCode(NORMAL, factory()->empty_string()); | 3085 return GetCode(NORMAL, factory()->empty_string()); |
3086 } | 3086 } |
3087 | 3087 |
3088 | 3088 |
3089 Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic( | 3089 Handle<Code> KeyedLoadStubCompiler::CompileLoadPolymorphic( |
3090 MapHandleList* receiver_maps, | 3090 MapHandleList* receiver_maps, |
3091 CodeHandleList* handler_ics) { | 3091 CodeHandleList* handler_ics) { |
3092 // ----------- S t a t e ------------- | 3092 // ----------- S t a t e ------------- |
3093 // -- eax : key | 3093 // -- ecx : key |
3094 // -- edx : receiver | 3094 // -- edx : receiver |
3095 // -- esp[0] : return address | 3095 // -- esp[0] : return address |
3096 // ----------------------------------- | 3096 // ----------------------------------- |
3097 Label miss; | 3097 Label miss; |
3098 __ JumpIfSmi(edx, &miss); | 3098 __ JumpIfSmi(edx, &miss); |
3099 | 3099 |
3100 Register map_reg = ebx; | 3100 Register map_reg = ebx; |
3101 __ mov(map_reg, FieldOperand(edx, HeapObject::kMapOffset)); | 3101 __ mov(map_reg, FieldOperand(edx, HeapObject::kMapOffset)); |
3102 int receiver_count = receiver_maps->length(); | 3102 int receiver_count = receiver_maps->length(); |
3103 for (int current = 0; current < receiver_count; ++current) { | 3103 for (int current = 0; current < receiver_count; ++current) { |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3247 } | 3247 } |
3248 | 3248 |
3249 | 3249 |
3250 #undef __ | 3250 #undef __ |
3251 #define __ ACCESS_MASM(masm) | 3251 #define __ ACCESS_MASM(masm) |
3252 | 3252 |
3253 | 3253 |
3254 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( | 3254 void KeyedLoadStubCompiler::GenerateLoadDictionaryElement( |
3255 MacroAssembler* masm) { | 3255 MacroAssembler* masm) { |
3256 // ----------- S t a t e ------------- | 3256 // ----------- S t a t e ------------- |
3257 // -- eax : key | 3257 // -- ecx : key |
3258 // -- edx : receiver | 3258 // -- edx : receiver |
3259 // -- esp[0] : return address | 3259 // -- esp[0] : return address |
3260 // ----------------------------------- | 3260 // ----------------------------------- |
3261 Label slow, miss_force_generic; | 3261 Label slow, miss_force_generic; |
3262 | 3262 |
3263 // This stub is meant to be tail-jumped to, the receiver must already | 3263 // This stub is meant to be tail-jumped to, the receiver must already |
3264 // have been verified by the caller to not be a smi. | 3264 // have been verified by the caller to not be a smi. |
3265 __ JumpIfNotSmi(eax, &miss_force_generic); | 3265 __ JumpIfNotSmi(ecx, &miss_force_generic); |
3266 __ mov(ebx, eax); | 3266 __ mov(ebx, ecx); |
3267 __ SmiUntag(ebx); | 3267 __ SmiUntag(ebx); |
3268 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); | 3268 __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset)); |
3269 | 3269 |
3270 // Push receiver on the stack to free up a register for the dictionary | 3270 // Push receiver on the stack to free up a register for the dictionary |
3271 // probing. | 3271 // probing. |
3272 __ push(edx); | 3272 __ push(edx); |
3273 __ LoadFromNumberDictionary(&slow, | 3273 __ LoadFromNumberDictionary(&slow, eax, ecx, ebx, edx, edi, eax); |
3274 ecx, | |
3275 eax, | |
3276 ebx, | |
3277 edx, | |
3278 edi, | |
3279 eax); | |
3280 // Pop receiver before returning. | 3274 // Pop receiver before returning. |
3281 __ pop(edx); | 3275 __ pop(edx); |
3282 __ ret(0); | 3276 __ ret(0); |
3283 | 3277 |
3284 __ bind(&slow); | 3278 __ bind(&slow); |
3285 __ pop(edx); | 3279 __ pop(edx); |
3286 | 3280 |
3287 // ----------- S t a t e ------------- | 3281 // ----------- S t a t e ------------- |
3288 // -- eax : value | |
3289 // -- ecx : key | 3282 // -- ecx : key |
3290 // -- edx : receiver | 3283 // -- edx : receiver |
3291 // -- esp[0] : return address | 3284 // -- esp[0] : return address |
3292 // ----------------------------------- | 3285 // ----------------------------------- |
3293 | 3286 |
3294 Handle<Code> slow_ic = | 3287 Handle<Code> slow_ic = |
3295 masm->isolate()->builtins()->KeyedLoadIC_Slow(); | 3288 masm->isolate()->builtins()->KeyedLoadIC_Slow(); |
3296 __ jmp(slow_ic, RelocInfo::CODE_TARGET); | 3289 __ jmp(slow_ic, RelocInfo::CODE_TARGET); |
3297 | 3290 |
3298 __ bind(&miss_force_generic); | 3291 __ bind(&miss_force_generic); |
3299 // ----------- S t a t e ------------- | 3292 // ----------- S t a t e ------------- |
3300 // -- eax : value | |
3301 // -- ecx : key | 3293 // -- ecx : key |
3302 // -- edx : receiver | 3294 // -- edx : receiver |
3303 // -- esp[0] : return address | 3295 // -- esp[0] : return address |
3304 // ----------------------------------- | 3296 // ----------------------------------- |
3305 | 3297 |
3306 Handle<Code> miss_force_generic_ic = | 3298 Handle<Code> miss_force_generic_ic = |
3307 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); | 3299 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); |
3308 __ jmp(miss_force_generic_ic, RelocInfo::CODE_TARGET); | 3300 __ jmp(miss_force_generic_ic, RelocInfo::CODE_TARGET); |
3309 } | 3301 } |
3310 | 3302 |
(...skipping 28 matching lines...) Expand all Loading... |
3339 } else { | 3331 } else { |
3340 __ JumpIfNotSmi(key, fail); | 3332 __ JumpIfNotSmi(key, fail); |
3341 } | 3333 } |
3342 } | 3334 } |
3343 | 3335 |
3344 | 3336 |
3345 void KeyedLoadStubCompiler::GenerateLoadExternalArray( | 3337 void KeyedLoadStubCompiler::GenerateLoadExternalArray( |
3346 MacroAssembler* masm, | 3338 MacroAssembler* masm, |
3347 ElementsKind elements_kind) { | 3339 ElementsKind elements_kind) { |
3348 // ----------- S t a t e ------------- | 3340 // ----------- S t a t e ------------- |
3349 // -- eax : key | 3341 // -- ecx : key |
3350 // -- edx : receiver | 3342 // -- edx : receiver |
3351 // -- esp[0] : return address | 3343 // -- esp[0] : return address |
3352 // ----------------------------------- | 3344 // ----------------------------------- |
3353 Label miss_force_generic, failed_allocation, slow; | 3345 Label miss_force_generic, failed_allocation, slow; |
3354 | 3346 |
3355 // This stub is meant to be tail-jumped to, the receiver must already | 3347 // This stub is meant to be tail-jumped to, the receiver must already |
3356 // have been verified by the caller to not be a smi. | 3348 // have been verified by the caller to not be a smi. |
3357 | 3349 |
3358 // Check that the key is a smi or a heap number convertible to a smi. | 3350 // Check that the key is a smi or a heap number convertible to a smi. |
3359 GenerateSmiKeyCheck(masm, eax, ecx, xmm0, xmm1, &miss_force_generic); | 3351 GenerateSmiKeyCheck(masm, ecx, eax, xmm0, xmm1, &miss_force_generic); |
3360 | 3352 |
3361 // Check that the index is in range. | 3353 // Check that the index is in range. |
3362 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); | 3354 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); |
3363 __ cmp(eax, FieldOperand(ebx, ExternalArray::kLengthOffset)); | 3355 __ cmp(ecx, FieldOperand(ebx, ExternalArray::kLengthOffset)); |
3364 // Unsigned comparison catches both negative and too-large values. | 3356 // Unsigned comparison catches both negative and too-large values. |
3365 __ j(above_equal, &miss_force_generic); | 3357 __ j(above_equal, &miss_force_generic); |
3366 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); | 3358 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); |
3367 // ebx: base pointer of external storage | 3359 // ebx: base pointer of external storage |
3368 switch (elements_kind) { | 3360 switch (elements_kind) { |
3369 case EXTERNAL_BYTE_ELEMENTS: | 3361 case EXTERNAL_BYTE_ELEMENTS: |
3370 __ SmiUntag(eax); // Untag the index. | 3362 __ SmiUntag(ecx); // Untag the index. |
3371 __ movsx_b(eax, Operand(ebx, eax, times_1, 0)); | 3363 __ movsx_b(eax, Operand(ebx, ecx, times_1, 0)); |
3372 break; | 3364 break; |
3373 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3365 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3374 case EXTERNAL_PIXEL_ELEMENTS: | 3366 case EXTERNAL_PIXEL_ELEMENTS: |
3375 __ SmiUntag(eax); // Untag the index. | 3367 __ SmiUntag(ecx); // Untag the index. |
3376 __ movzx_b(eax, Operand(ebx, eax, times_1, 0)); | 3368 __ movzx_b(eax, Operand(ebx, ecx, times_1, 0)); |
3377 break; | 3369 break; |
3378 case EXTERNAL_SHORT_ELEMENTS: | 3370 case EXTERNAL_SHORT_ELEMENTS: |
3379 __ movsx_w(eax, Operand(ebx, eax, times_1, 0)); | 3371 __ movsx_w(eax, Operand(ebx, ecx, times_1, 0)); |
3380 break; | 3372 break; |
3381 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3373 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3382 __ movzx_w(eax, Operand(ebx, eax, times_1, 0)); | 3374 __ movzx_w(eax, Operand(ebx, ecx, times_1, 0)); |
3383 break; | 3375 break; |
3384 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3376 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3385 case EXTERNAL_INT_ELEMENTS: | 3377 case EXTERNAL_INT_ELEMENTS: |
3386 __ mov(ecx, Operand(ebx, eax, times_2, 0)); | 3378 __ mov(eax, Operand(ebx, ecx, times_2, 0)); |
3387 break; | 3379 break; |
3388 case EXTERNAL_FLOAT_ELEMENTS: | 3380 case EXTERNAL_FLOAT_ELEMENTS: |
3389 __ fld_s(Operand(ebx, eax, times_2, 0)); | 3381 __ fld_s(Operand(ebx, ecx, times_2, 0)); |
3390 break; | 3382 break; |
3391 case EXTERNAL_DOUBLE_ELEMENTS: | 3383 case EXTERNAL_DOUBLE_ELEMENTS: |
3392 __ fld_d(Operand(ebx, eax, times_4, 0)); | 3384 __ fld_d(Operand(ebx, ecx, times_4, 0)); |
3393 break; | 3385 break; |
3394 default: | 3386 default: |
3395 UNREACHABLE(); | 3387 UNREACHABLE(); |
3396 break; | 3388 break; |
3397 } | 3389 } |
3398 | 3390 |
3399 // For integer array types: | 3391 // For integer array types: |
3400 // ecx: value | 3392 // eax: value |
3401 // For floating-point array type: | 3393 // For floating-point array type: |
3402 // FP(0): value | 3394 // FP(0): value |
3403 | 3395 |
3404 if (elements_kind == EXTERNAL_INT_ELEMENTS || | 3396 if (elements_kind == EXTERNAL_INT_ELEMENTS || |
3405 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { | 3397 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
3406 // For the Int and UnsignedInt array types, we need to see whether | 3398 // For the Int and UnsignedInt array types, we need to see whether |
3407 // the value can be represented in a Smi. If not, we need to convert | 3399 // the value can be represented in a Smi. If not, we need to convert |
3408 // it to a HeapNumber. | 3400 // it to a HeapNumber. |
3409 Label box_int; | 3401 Label box_int; |
3410 if (elements_kind == EXTERNAL_INT_ELEMENTS) { | 3402 if (elements_kind == EXTERNAL_INT_ELEMENTS) { |
3411 __ cmp(ecx, 0xc0000000); | 3403 __ cmp(eax, 0xc0000000); |
3412 __ j(sign, &box_int); | 3404 __ j(sign, &box_int); |
3413 } else { | 3405 } else { |
3414 ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); | 3406 ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); |
3415 // The test is different for unsigned int values. Since we need | 3407 // The test is different for unsigned int values. Since we need |
3416 // the value to be in the range of a positive smi, we can't | 3408 // the value to be in the range of a positive smi, we can't |
3417 // handle either of the top two bits being set in the value. | 3409 // handle either of the top two bits being set in the value. |
3418 __ test(ecx, Immediate(0xc0000000)); | 3410 __ test(eax, Immediate(0xc0000000)); |
3419 __ j(not_zero, &box_int); | 3411 __ j(not_zero, &box_int); |
3420 } | 3412 } |
3421 | 3413 |
3422 __ mov(eax, ecx); | |
3423 __ SmiTag(eax); | 3414 __ SmiTag(eax); |
3424 __ ret(0); | 3415 __ ret(0); |
3425 | 3416 |
3426 __ bind(&box_int); | 3417 __ bind(&box_int); |
3427 | 3418 |
3428 // Allocate a HeapNumber for the int and perform int-to-double | 3419 // Allocate a HeapNumber for the int and perform int-to-double |
3429 // conversion. | 3420 // conversion. |
3430 if (elements_kind == EXTERNAL_INT_ELEMENTS) { | 3421 if (elements_kind == EXTERNAL_INT_ELEMENTS) { |
3431 __ push(ecx); | 3422 __ push(eax); |
3432 __ fild_s(Operand(esp, 0)); | 3423 __ fild_s(Operand(esp, 0)); |
3433 __ pop(ecx); | 3424 __ pop(eax); |
3434 } else { | 3425 } else { |
3435 ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); | 3426 ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); |
3436 // Need to zero-extend the value. | 3427 // Need to zero-extend the value. |
3437 // There's no fild variant for unsigned values, so zero-extend | 3428 // There's no fild variant for unsigned values, so zero-extend |
3438 // to a 64-bit int manually. | 3429 // to a 64-bit int manually. |
3439 __ push(Immediate(0)); | 3430 __ push(Immediate(0)); |
3440 __ push(ecx); | 3431 __ push(eax); |
3441 __ fild_d(Operand(esp, 0)); | 3432 __ fild_d(Operand(esp, 0)); |
3442 __ pop(ecx); | 3433 __ pop(eax); |
3443 __ pop(ecx); | 3434 __ pop(eax); |
3444 } | 3435 } |
3445 // FP(0): value | 3436 // FP(0): value |
3446 __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); | 3437 __ AllocateHeapNumber(eax, ebx, edi, &failed_allocation); |
3447 // Set the value. | 3438 // Set the value. |
3448 __ mov(eax, ecx); | |
3449 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 3439 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
3450 __ ret(0); | 3440 __ ret(0); |
3451 } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || | 3441 } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS || |
3452 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3442 elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
3453 // For the floating-point array type, we need to always allocate a | 3443 // For the floating-point array type, we need to always allocate a |
3454 // HeapNumber. | 3444 // HeapNumber. |
3455 __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); | 3445 __ AllocateHeapNumber(eax, ebx, edi, &failed_allocation); |
3456 // Set the value. | 3446 // Set the value. |
3457 __ mov(eax, ecx); | |
3458 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); | 3447 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
3459 __ ret(0); | 3448 __ ret(0); |
3460 } else { | 3449 } else { |
3461 __ SmiTag(eax); | 3450 __ SmiTag(eax); |
3462 __ ret(0); | 3451 __ ret(0); |
3463 } | 3452 } |
3464 | 3453 |
3465 // If we fail allocation of the HeapNumber, we still have a value on | 3454 // If we fail allocation of the HeapNumber, we still have a value on |
3466 // top of the FPU stack. Remove it. | 3455 // top of the FPU stack. Remove it. |
3467 __ bind(&failed_allocation); | 3456 __ bind(&failed_allocation); |
3468 __ fstp(0); | 3457 __ fstp(0); |
3469 // Fall through to slow case. | 3458 // Fall through to slow case. |
3470 | 3459 |
3471 // Slow case: Jump to runtime. | 3460 // Slow case: Jump to runtime. |
3472 __ bind(&slow); | 3461 __ bind(&slow); |
3473 Counters* counters = masm->isolate()->counters(); | 3462 Counters* counters = masm->isolate()->counters(); |
3474 __ IncrementCounter(counters->keyed_load_external_array_slow(), 1); | 3463 __ IncrementCounter(counters->keyed_load_external_array_slow(), 1); |
3475 | 3464 |
3476 // ----------- S t a t e ------------- | 3465 // ----------- S t a t e ------------- |
3477 // -- eax : key | 3466 // -- ecx : key |
3478 // -- edx : receiver | 3467 // -- edx : receiver |
3479 // -- esp[0] : return address | 3468 // -- esp[0] : return address |
3480 // ----------------------------------- | 3469 // ----------------------------------- |
3481 | 3470 |
3482 Handle<Code> ic = masm->isolate()->builtins()->KeyedLoadIC_Slow(); | 3471 Handle<Code> ic = masm->isolate()->builtins()->KeyedLoadIC_Slow(); |
3483 __ jmp(ic, RelocInfo::CODE_TARGET); | 3472 __ jmp(ic, RelocInfo::CODE_TARGET); |
3484 | 3473 |
3485 // ----------- S t a t e ------------- | 3474 // ----------- S t a t e ------------- |
3486 // -- eax : key | 3475 // -- ecx : key |
3487 // -- edx : receiver | 3476 // -- edx : receiver |
3488 // -- esp[0] : return address | 3477 // -- esp[0] : return address |
3489 // ----------------------------------- | 3478 // ----------------------------------- |
3490 | 3479 |
3491 // Miss case: Jump to runtime. | 3480 // Miss case: Jump to runtime. |
3492 __ bind(&miss_force_generic); | 3481 __ bind(&miss_force_generic); |
3493 Handle<Code> miss_ic = | 3482 Handle<Code> miss_ic = |
3494 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); | 3483 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); |
3495 __ jmp(miss_ic, RelocInfo::CODE_TARGET); | 3484 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
3496 } | 3485 } |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3690 | 3679 |
3691 __ bind(&miss_force_generic); | 3680 __ bind(&miss_force_generic); |
3692 Handle<Code> miss_ic = | 3681 Handle<Code> miss_ic = |
3693 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 3682 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
3694 __ jmp(miss_ic, RelocInfo::CODE_TARGET); | 3683 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
3695 } | 3684 } |
3696 | 3685 |
3697 | 3686 |
3698 void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) { | 3687 void KeyedLoadStubCompiler::GenerateLoadFastElement(MacroAssembler* masm) { |
3699 // ----------- S t a t e ------------- | 3688 // ----------- S t a t e ------------- |
3700 // -- eax : key | 3689 // -- ecx : key |
3701 // -- edx : receiver | 3690 // -- edx : receiver |
3702 // -- esp[0] : return address | 3691 // -- esp[0] : return address |
3703 // ----------------------------------- | 3692 // ----------------------------------- |
3704 Label miss_force_generic; | 3693 Label miss_force_generic; |
3705 | 3694 |
3706 // This stub is meant to be tail-jumped to, the receiver must already | 3695 // This stub is meant to be tail-jumped to, the receiver must already |
3707 // have been verified by the caller to not be a smi. | 3696 // have been verified by the caller to not be a smi. |
3708 | 3697 |
3709 // Check that the key is a smi or a heap number convertible to a smi. | 3698 // Check that the key is a smi or a heap number convertible to a smi. |
3710 GenerateSmiKeyCheck(masm, eax, ecx, xmm0, xmm1, &miss_force_generic); | 3699 GenerateSmiKeyCheck(masm, ecx, eax, xmm0, xmm1, &miss_force_generic); |
3711 | 3700 |
3712 // Get the elements array. | 3701 // Get the elements array. |
3713 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); | 3702 __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset)); |
3714 __ AssertFastElements(ecx); | 3703 __ AssertFastElements(eax); |
3715 | 3704 |
3716 // Check that the key is within bounds. | 3705 // Check that the key is within bounds. |
3717 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset)); | 3706 __ cmp(ecx, FieldOperand(eax, FixedArray::kLengthOffset)); |
3718 __ j(above_equal, &miss_force_generic); | 3707 __ j(above_equal, &miss_force_generic); |
3719 | 3708 |
3720 // Load the result and make sure it's not the hole. | 3709 // Load the result and make sure it's not the hole. |
3721 __ mov(ebx, Operand(ecx, eax, times_2, | 3710 __ mov(ebx, Operand(eax, ecx, times_2, |
3722 FixedArray::kHeaderSize - kHeapObjectTag)); | 3711 FixedArray::kHeaderSize - kHeapObjectTag)); |
3723 __ cmp(ebx, masm->isolate()->factory()->the_hole_value()); | 3712 __ cmp(ebx, masm->isolate()->factory()->the_hole_value()); |
3724 __ j(equal, &miss_force_generic); | 3713 __ j(equal, &miss_force_generic); |
3725 __ mov(eax, ebx); | 3714 __ mov(eax, ebx); |
3726 __ ret(0); | 3715 __ ret(0); |
3727 | 3716 |
3728 __ bind(&miss_force_generic); | 3717 __ bind(&miss_force_generic); |
3729 Handle<Code> miss_ic = | 3718 Handle<Code> miss_ic = |
3730 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); | 3719 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); |
3731 __ jmp(miss_ic, RelocInfo::CODE_TARGET); | 3720 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
3732 } | 3721 } |
3733 | 3722 |
3734 | 3723 |
3735 void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement( | 3724 void KeyedLoadStubCompiler::GenerateLoadFastDoubleElement( |
3736 MacroAssembler* masm) { | 3725 MacroAssembler* masm) { |
3737 // ----------- S t a t e ------------- | 3726 // ----------- S t a t e ------------- |
3738 // -- eax : key | 3727 // -- ecx : key |
3739 // -- edx : receiver | 3728 // -- edx : receiver |
3740 // -- esp[0] : return address | 3729 // -- esp[0] : return address |
3741 // ----------------------------------- | 3730 // ----------------------------------- |
3742 Label miss_force_generic, slow_allocate_heapnumber; | 3731 Label miss_force_generic, slow_allocate_heapnumber; |
3743 | 3732 |
3744 // This stub is meant to be tail-jumped to, the receiver must already | 3733 // This stub is meant to be tail-jumped to, the receiver must already |
3745 // have been verified by the caller to not be a smi. | 3734 // have been verified by the caller to not be a smi. |
3746 | 3735 |
3747 // Check that the key is a smi or a heap number convertible to a smi. | 3736 // Check that the key is a smi or a heap number convertible to a smi. |
3748 GenerateSmiKeyCheck(masm, eax, ecx, xmm0, xmm1, &miss_force_generic); | 3737 GenerateSmiKeyCheck(masm, ecx, eax, xmm0, xmm1, &miss_force_generic); |
3749 | 3738 |
3750 // Get the elements array. | 3739 // Get the elements array. |
3751 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); | 3740 __ mov(eax, FieldOperand(edx, JSObject::kElementsOffset)); |
3752 __ AssertFastElements(ecx); | 3741 __ AssertFastElements(eax); |
3753 | 3742 |
3754 // Check that the key is within bounds. | 3743 // Check that the key is within bounds. |
3755 __ cmp(eax, FieldOperand(ecx, FixedDoubleArray::kLengthOffset)); | 3744 __ cmp(ecx, FieldOperand(eax, FixedDoubleArray::kLengthOffset)); |
3756 __ j(above_equal, &miss_force_generic); | 3745 __ j(above_equal, &miss_force_generic); |
3757 | 3746 |
3758 // Check for the hole | 3747 // Check for the hole |
3759 uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); | 3748 uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); |
3760 __ cmp(FieldOperand(ecx, eax, times_4, offset), Immediate(kHoleNanUpper32)); | 3749 __ cmp(FieldOperand(eax, ecx, times_4, offset), Immediate(kHoleNanUpper32)); |
3761 __ j(equal, &miss_force_generic); | 3750 __ j(equal, &miss_force_generic); |
3762 | 3751 |
3763 // Always allocate a heap number for the result. | 3752 // Always allocate a heap number for the result. |
3764 if (CpuFeatures::IsSupported(SSE2)) { | 3753 if (CpuFeatures::IsSupported(SSE2)) { |
3765 CpuFeatures::Scope use_sse2(SSE2); | 3754 CpuFeatures::Scope use_sse2(SSE2); |
3766 __ movdbl(xmm0, FieldOperand(ecx, eax, times_4, | 3755 __ movdbl(xmm0, FieldOperand(eax, ecx, times_4, |
3767 FixedDoubleArray::kHeaderSize)); | 3756 FixedDoubleArray::kHeaderSize)); |
3768 } else { | 3757 } else { |
3769 __ fld_d(FieldOperand(ecx, eax, times_4, FixedDoubleArray::kHeaderSize)); | 3758 __ fld_d(FieldOperand(eax, ecx, times_4, FixedDoubleArray::kHeaderSize)); |
3770 } | 3759 } |
3771 __ AllocateHeapNumber(ecx, ebx, edi, &slow_allocate_heapnumber); | 3760 __ AllocateHeapNumber(eax, ebx, edi, &slow_allocate_heapnumber); |
3772 // Set the value. | 3761 // Set the value. |
3773 if (CpuFeatures::IsSupported(SSE2)) { | 3762 if (CpuFeatures::IsSupported(SSE2)) { |
3774 CpuFeatures::Scope use_sse2(SSE2); | 3763 CpuFeatures::Scope use_sse2(SSE2); |
3775 __ movdbl(FieldOperand(ecx, HeapNumber::kValueOffset), xmm0); | 3764 __ movdbl(FieldOperand(eax, HeapNumber::kValueOffset), xmm0); |
3776 } else { | 3765 } else { |
3777 __ fstp_d(FieldOperand(ecx, HeapNumber::kValueOffset)); | 3766 __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); |
3778 } | 3767 } |
3779 __ mov(eax, ecx); | |
3780 __ ret(0); | 3768 __ ret(0); |
3781 | 3769 |
3782 __ bind(&slow_allocate_heapnumber); | 3770 __ bind(&slow_allocate_heapnumber); |
3783 // A value was pushed on the floating point stack before the allocation, if | 3771 // A value was pushed on the floating point stack before the allocation, if |
3784 // the allocation fails it needs to be removed. | 3772 // the allocation fails it needs to be removed. |
3785 if (!CpuFeatures::IsSupported(SSE2)) { | 3773 if (!CpuFeatures::IsSupported(SSE2)) { |
3786 __ fstp(0); | 3774 __ fstp(0); |
3787 } | 3775 } |
3788 Handle<Code> slow_ic = | 3776 Handle<Code> slow_ic = |
3789 masm->isolate()->builtins()->KeyedLoadIC_Slow(); | 3777 masm->isolate()->builtins()->KeyedLoadIC_Slow(); |
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4079 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | 4067 __ jmp(ic_slow, RelocInfo::CODE_TARGET); |
4080 } | 4068 } |
4081 } | 4069 } |
4082 | 4070 |
4083 | 4071 |
4084 #undef __ | 4072 #undef __ |
4085 | 4073 |
4086 } } // namespace v8::internal | 4074 } } // namespace v8::internal |
4087 | 4075 |
4088 #endif // V8_TARGET_ARCH_IA32 | 4076 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |