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

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 10254005: ia32: Redefine register usage in LoadIC/KeyedLoadIC to match StoreIC and KeyedStoreIC (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: addressed comments; removed debug code Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2677 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698