OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 2880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2891 // Slow-case: Handle non-smi or out-of-bounds access to arguments | 2891 // Slow-case: Handle non-smi or out-of-bounds access to arguments |
2892 // by calling the runtime system. | 2892 // by calling the runtime system. |
2893 __ bind(&slow); | 2893 __ bind(&slow); |
2894 __ pop(ebx); // Return address. | 2894 __ pop(ebx); // Return address. |
2895 __ push(edx); | 2895 __ push(edx); |
2896 __ push(ebx); | 2896 __ push(ebx); |
2897 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); | 2897 __ TailCallRuntime(Runtime::kGetArgumentsProperty, 1, 1); |
2898 } | 2898 } |
2899 | 2899 |
2900 | 2900 |
2901 void ArgumentsAccessStub::GenerateNewNonStrictSlow(MacroAssembler* masm) { | 2901 void ArgumentsAccessStub::GenerateNewObject(MacroAssembler* masm) { |
2902 // esp[0] : return address | 2902 // esp[0] : return address |
2903 // esp[4] : number of parameters | 2903 // esp[4] : number of parameters |
2904 // esp[8] : receiver displacement | 2904 // esp[8] : receiver displacement |
2905 // esp[12] : function | 2905 // esp[16] : function |
2906 | 2906 |
2907 // Check if the calling frame is an arguments adaptor frame. | 2907 // The displacement is used for skipping the return address and the |
2908 Label runtime; | 2908 // frame pointer on the stack. It is the offset of the last |
2909 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 2909 // parameter (if any) relative to the frame pointer. |
2910 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); | 2910 static const int kDisplacement = 2 * kPointerSize; |
2911 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | |
2912 __ j(not_equal, &runtime, Label::kNear); | |
2913 | |
2914 // Patch the arguments.length and the parameters pointer. | |
2915 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | |
2916 __ mov(Operand(esp, 1 * kPointerSize), ecx); | |
2917 __ lea(edx, Operand(edx, ecx, times_2, | |
2918 StandardFrameConstants::kCallerSPOffset)); | |
2919 __ mov(Operand(esp, 2 * kPointerSize), edx); | |
2920 | |
2921 __ bind(&runtime); | |
2922 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1); | |
2923 } | |
2924 | |
2925 | |
2926 void ArgumentsAccessStub::GenerateNewNonStrictFast(MacroAssembler* masm) { | |
2927 // esp[0] : return address | |
2928 // esp[4] : number of parameters (tagged) | |
2929 // esp[8] : receiver displacement | |
2930 // esp[12] : function | |
2931 | |
2932 // ebx = parameter count (tagged) | |
2933 __ mov(ebx, Operand(esp, 1 * kPointerSize)); | |
2934 | |
2935 // Check if the calling frame is an arguments adaptor frame. | |
2936 // TODO(rossberg): Factor out some of the bits that are shared with the other | |
2937 // Generate* functions. | |
2938 Label runtime; | |
2939 Label adaptor_frame, try_allocate; | |
2940 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | |
2941 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); | |
2942 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | |
2943 __ j(equal, &adaptor_frame, Label::kNear); | |
2944 | |
2945 // No adaptor, parameter count = argument count. | |
2946 __ mov(ecx, ebx); | |
2947 __ jmp(&try_allocate, Label::kNear); | |
2948 | |
2949 // We have an adaptor frame. Patch the parameters pointer. | |
2950 __ bind(&adaptor_frame); | |
2951 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | |
2952 __ lea(edx, Operand(edx, ecx, times_2, | |
2953 StandardFrameConstants::kCallerSPOffset)); | |
2954 __ mov(Operand(esp, 2 * kPointerSize), edx); | |
2955 | |
2956 // ebx = parameter count (tagged) | |
2957 // ecx = argument count (tagged) | |
2958 // esp[4] = parameter count (tagged) | |
2959 // esp[8] = address of receiver argument | |
2960 // Compute the mapped parameter count = min(ebx, ecx) in ebx. | |
2961 __ cmp(ebx, Operand(ecx)); | |
2962 __ j(less_equal, &try_allocate, Label::kNear); | |
2963 __ mov(ebx, ecx); | |
2964 | |
2965 __ bind(&try_allocate); | |
2966 | |
2967 // Save mapped parameter count. | |
2968 __ push(ebx); | |
2969 | |
2970 // Compute the sizes of backing store, parameter map, and arguments object. | |
2971 // 1. Parameter map, has 2 extra words containing context and backing store. | |
2972 const int kParameterMapHeaderSize = | |
2973 FixedArray::kHeaderSize + 2 * kPointerSize; | |
2974 Label no_parameter_map; | |
2975 __ test(ebx, Operand(ebx)); | |
2976 __ j(zero, &no_parameter_map, Label::kNear); | |
2977 __ lea(ebx, Operand(ebx, times_2, kParameterMapHeaderSize)); | |
2978 __ bind(&no_parameter_map); | |
2979 | |
2980 // 2. Backing store. | |
2981 __ lea(ebx, Operand(ebx, ecx, times_2, FixedArray::kHeaderSize)); | |
2982 | |
2983 // 3. Arguments object. | |
2984 __ add(Operand(ebx), Immediate(Heap::kArgumentsObjectSize)); | |
2985 | |
2986 // Do the allocation of all three objects in one go. | |
2987 __ AllocateInNewSpace(ebx, eax, edx, edi, &runtime, TAG_OBJECT); | |
2988 | |
2989 // eax = address of new object(s) (tagged) | |
2990 // ecx = argument count (tagged) | |
2991 // esp[0] = mapped parameter count (tagged) | |
2992 // esp[8] = parameter count (tagged) | |
2993 // esp[12] = address of receiver argument | |
2994 // Get the arguments boilerplate from the current (global) context into edi. | |
2995 Label has_mapped_parameters, copy; | |
2996 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); | |
2997 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset)); | |
2998 __ mov(ebx, Operand(esp, 0 * kPointerSize)); | |
2999 __ test(ebx, Operand(ebx)); | |
3000 __ j(not_zero, &has_mapped_parameters, Label::kNear); | |
3001 __ mov(edi, Operand(edi, | |
3002 Context::SlotOffset(Context::ARGUMENTS_BOILERPLATE_INDEX))); | |
3003 __ jmp(©, Label::kNear); | |
3004 | |
3005 __ bind(&has_mapped_parameters); | |
3006 __ mov(edi, Operand(edi, | |
3007 Context::SlotOffset(Context::ALIASED_ARGUMENTS_BOILERPLATE_INDEX))); | |
3008 __ bind(©); | |
3009 | |
3010 // eax = address of new object (tagged) | |
3011 // ebx = mapped parameter count (tagged) | |
3012 // ecx = argument count (tagged) | |
3013 // edi = address of boilerplate object (tagged) | |
3014 // esp[0] = mapped parameter count (tagged) | |
3015 // esp[8] = parameter count (tagged) | |
3016 // esp[12] = address of receiver argument | |
3017 // Copy the JS object part. | |
3018 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { | |
3019 __ mov(edx, FieldOperand(edi, i)); | |
3020 __ mov(FieldOperand(eax, i), edx); | |
3021 } | |
3022 | |
3023 // Setup the callee in-object property. | |
3024 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); | |
3025 __ mov(edx, Operand(esp, 4 * kPointerSize)); | |
3026 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | |
3027 Heap::kArgumentsCalleeIndex * kPointerSize), | |
3028 edx); | |
3029 | |
3030 // Use the length (smi tagged) and set that as an in-object property too. | |
3031 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | |
3032 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | |
3033 Heap::kArgumentsLengthIndex * kPointerSize), | |
3034 ecx); | |
3035 | |
3036 // Setup the elements pointer in the allocated arguments object. | |
3037 // If we allocated a parameter map, edi will point there, otherwise to the | |
3038 // backing store. | |
3039 __ lea(edi, Operand(eax, Heap::kArgumentsObjectSize)); | |
3040 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); | |
3041 | |
3042 // eax = address of new object (tagged) | |
3043 // ebx = mapped parameter count (tagged) | |
3044 // ecx = argument count (tagged) | |
3045 // edi = address of parameter map or backing store (tagged) | |
3046 // esp[0] = mapped parameter count (tagged) | |
3047 // esp[8] = parameter count (tagged) | |
3048 // esp[12] = address of receiver argument | |
3049 // Free a register. | |
3050 __ push(eax); | |
3051 | |
3052 // Initialize parameter map. If there are no mapped arguments, we're done. | |
3053 Label skip_parameter_map; | |
3054 __ test(ebx, Operand(ebx)); | |
3055 __ j(zero, &skip_parameter_map); | |
3056 | |
3057 __ mov(FieldOperand(edi, FixedArray::kMapOffset), | |
3058 Immediate(FACTORY->non_strict_arguments_elements_map())); | |
3059 __ lea(eax, Operand(ebx, reinterpret_cast<intptr_t>(Smi::FromInt(2)))); | |
3060 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), eax); | |
3061 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 0 * kPointerSize), esi); | |
3062 __ lea(eax, Operand(edi, ebx, times_2, kParameterMapHeaderSize)); | |
3063 __ mov(FieldOperand(edi, FixedArray::kHeaderSize + 1 * kPointerSize), eax); | |
3064 | |
3065 // Copy the parameter slots and the holes in the arguments. | |
3066 // We need to fill in mapped_parameter_count slots. They index the context, | |
3067 // where parameters are stored in reverse order, at | |
3068 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1 | |
3069 // The mapped parameter thus need to get indices | |
3070 // MIN_CONTEXT_SLOTS+parameter_count-1 .. | |
3071 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count | |
3072 // We loop from right to left. | |
3073 Label parameters_loop, parameters_test; | |
3074 __ push(ecx); | |
3075 __ mov(eax, Operand(esp, 2 * kPointerSize)); | |
3076 __ mov(ebx, Immediate(Smi::FromInt(Context::MIN_CONTEXT_SLOTS))); | |
3077 __ add(ebx, Operand(esp, 4 * kPointerSize)); | |
3078 __ sub(ebx, Operand(eax)); | |
3079 __ mov(ecx, FACTORY->the_hole_value()); | |
3080 __ mov(edx, edi); | |
3081 __ lea(edi, Operand(edi, eax, times_2, kParameterMapHeaderSize)); | |
3082 // eax = loop variable (tagged) | |
3083 // ebx = mapping index (tagged) | |
3084 // ecx = the hole value | |
3085 // edx = address of parameter map (tagged) | |
3086 // edi = address of backing store (tagged) | |
3087 // esp[0] = argument count (tagged) | |
3088 // esp[4] = address of new object (tagged) | |
3089 // esp[8] = mapped parameter count (tagged) | |
3090 // esp[16] = parameter count (tagged) | |
3091 // esp[20] = address of receiver argument | |
3092 __ jmp(¶meters_test, Label::kNear); | |
3093 | |
3094 __ bind(¶meters_loop); | |
3095 __ sub(Operand(eax), Immediate(Smi::FromInt(1))); | |
3096 __ mov(FieldOperand(edx, eax, times_2, kParameterMapHeaderSize), ebx); | |
3097 __ mov(FieldOperand(edi, eax, times_2, FixedArray::kHeaderSize), ecx); | |
3098 __ add(Operand(ebx), Immediate(Smi::FromInt(1))); | |
3099 __ bind(¶meters_test); | |
3100 __ test(eax, Operand(eax)); | |
3101 __ j(not_zero, ¶meters_loop, Label::kNear); | |
3102 __ pop(ecx); | |
3103 | |
3104 __ bind(&skip_parameter_map); | |
3105 | |
3106 // ecx = argument count (tagged) | |
3107 // edi = address of backing store (tagged) | |
3108 // esp[0] = address of new object (tagged) | |
3109 // esp[4] = mapped parameter count (tagged) | |
3110 // esp[12] = parameter count (tagged) | |
3111 // esp[16] = address of receiver argument | |
3112 // Copy arguments header and remaining slots (if there are any). | |
3113 __ mov(FieldOperand(edi, FixedArray::kMapOffset), | |
3114 Immediate(FACTORY->fixed_array_map())); | |
3115 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); | |
3116 | |
3117 Label arguments_loop, arguments_test; | |
3118 __ mov(ebx, Operand(esp, 1 * kPointerSize)); | |
3119 __ mov(edx, Operand(esp, 4 * kPointerSize)); | |
3120 __ sub(Operand(edx), ebx); // Is there a smarter way to do negative scaling? | |
3121 __ sub(Operand(edx), ebx); | |
3122 __ jmp(&arguments_test, Label::kNear); | |
3123 | |
3124 __ bind(&arguments_loop); | |
3125 __ sub(Operand(edx), Immediate(kPointerSize)); | |
3126 __ mov(eax, Operand(edx, 0)); | |
3127 __ mov(FieldOperand(edi, ebx, times_2, FixedArray::kHeaderSize), eax); | |
3128 __ add(Operand(ebx), Immediate(Smi::FromInt(1))); | |
3129 | |
3130 __ bind(&arguments_test); | |
3131 __ cmp(ebx, Operand(ecx)); | |
3132 __ j(less, &arguments_loop, Label::kNear); | |
3133 | |
3134 // Restore. | |
3135 __ pop(eax); // Address of arguments object. | |
3136 __ pop(ebx); // Parameter count. | |
3137 | |
3138 // Return and remove the on-stack parameters. | |
3139 __ ret(3 * kPointerSize); | |
3140 | |
3141 // Do the runtime call to allocate the arguments object. | |
3142 __ bind(&runtime); | |
3143 __ pop(eax); // Remove saved parameter count. | |
3144 __ mov(Operand(esp, 1 * kPointerSize), ecx); // Patch argument count. | |
3145 __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1); | |
3146 } | |
3147 | |
3148 | |
3149 void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) { | |
3150 // esp[0] : return address | |
3151 // esp[4] : number of parameters | |
3152 // esp[8] : receiver displacement | |
3153 // esp[12] : function | |
3154 | 2911 |
3155 // Check if the calling frame is an arguments adaptor frame. | 2912 // Check if the calling frame is an arguments adaptor frame. |
3156 Label adaptor_frame, try_allocate, runtime; | 2913 Label adaptor_frame, try_allocate, runtime; |
3157 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 2914 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
3158 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); | 2915 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
3159 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 2916 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
3160 __ j(equal, &adaptor_frame); | 2917 __ j(equal, &adaptor_frame); |
3161 | 2918 |
3162 // Get the length from the frame. | 2919 // Get the length from the frame. |
3163 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 2920 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
3164 __ jmp(&try_allocate); | 2921 __ jmp(&try_allocate); |
3165 | 2922 |
3166 // Patch the arguments.length and the parameters pointer. | 2923 // Patch the arguments.length and the parameters pointer. |
3167 __ bind(&adaptor_frame); | 2924 __ bind(&adaptor_frame); |
3168 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 2925 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
3169 __ mov(Operand(esp, 1 * kPointerSize), ecx); | 2926 __ mov(Operand(esp, 1 * kPointerSize), ecx); |
3170 __ lea(edx, Operand(edx, ecx, times_2, | 2927 __ lea(edx, Operand(edx, ecx, times_2, kDisplacement)); |
3171 StandardFrameConstants::kCallerSPOffset)); | |
3172 __ mov(Operand(esp, 2 * kPointerSize), edx); | 2928 __ mov(Operand(esp, 2 * kPointerSize), edx); |
3173 | 2929 |
3174 // Try the new space allocation. Start out with computing the size of | 2930 // Try the new space allocation. Start out with computing the size of |
3175 // the arguments object and the elements array. | 2931 // the arguments object and the elements array. |
3176 Label add_arguments_object; | 2932 Label add_arguments_object; |
3177 __ bind(&try_allocate); | 2933 __ bind(&try_allocate); |
3178 __ test(ecx, Operand(ecx)); | 2934 __ test(ecx, Operand(ecx)); |
3179 __ j(zero, &add_arguments_object, Label::kNear); | 2935 __ j(zero, &add_arguments_object, Label::kNear); |
3180 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); | 2936 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); |
3181 __ bind(&add_arguments_object); | 2937 __ bind(&add_arguments_object); |
3182 __ add(Operand(ecx), Immediate(Heap::kArgumentsObjectSizeStrict)); | 2938 __ add(Operand(ecx), Immediate(GetArgumentsObjectSize())); |
3183 | 2939 |
3184 // Do the allocation of both objects in one go. | 2940 // Do the allocation of both objects in one go. |
3185 __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); | 2941 __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); |
3186 | 2942 |
3187 // Get the arguments boilerplate from the current (global) context. | 2943 // Get the arguments boilerplate from the current (global) context. |
3188 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); | 2944 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
3189 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset)); | 2945 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset)); |
3190 const int offset = | 2946 __ mov(edi, Operand(edi, |
3191 Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX); | 2947 Context::SlotOffset(GetArgumentsBoilerplateIndex()))); |
3192 __ mov(edi, Operand(edi, offset)); | |
3193 | 2948 |
3194 // Copy the JS object part. | 2949 // Copy the JS object part. |
3195 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { | 2950 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { |
3196 __ mov(ebx, FieldOperand(edi, i)); | 2951 __ mov(ebx, FieldOperand(edi, i)); |
3197 __ mov(FieldOperand(eax, i), ebx); | 2952 __ mov(FieldOperand(eax, i), ebx); |
3198 } | 2953 } |
3199 | 2954 |
| 2955 if (type_ == NEW_NON_STRICT) { |
| 2956 // Setup the callee in-object property. |
| 2957 STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1); |
| 2958 __ mov(ebx, Operand(esp, 3 * kPointerSize)); |
| 2959 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
| 2960 Heap::kArgumentsCalleeIndex * kPointerSize), |
| 2961 ebx); |
| 2962 } |
| 2963 |
3200 // Get the length (smi tagged) and set that as an in-object property too. | 2964 // Get the length (smi tagged) and set that as an in-object property too. |
3201 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 2965 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
3202 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 2966 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
3203 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | 2967 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
3204 Heap::kArgumentsLengthIndex * kPointerSize), | 2968 Heap::kArgumentsLengthIndex * kPointerSize), |
3205 ecx); | 2969 ecx); |
3206 | 2970 |
3207 // If there are no actual arguments, we're done. | 2971 // If there are no actual arguments, we're done. |
3208 Label done; | 2972 Label done; |
3209 __ test(ecx, Operand(ecx)); | 2973 __ test(ecx, Operand(ecx)); |
3210 __ j(zero, &done); | 2974 __ j(zero, &done); |
3211 | 2975 |
3212 // Get the parameters pointer from the stack. | 2976 // Get the parameters pointer from the stack. |
3213 __ mov(edx, Operand(esp, 2 * kPointerSize)); | 2977 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
3214 | 2978 |
3215 // Setup the elements pointer in the allocated arguments object and | 2979 // Setup the elements pointer in the allocated arguments object and |
3216 // initialize the header in the elements fixed array. | 2980 // initialize the header in the elements fixed array. |
3217 __ lea(edi, Operand(eax, Heap::kArgumentsObjectSizeStrict)); | 2981 __ lea(edi, Operand(eax, GetArgumentsObjectSize())); |
3218 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); | 2982 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); |
3219 __ mov(FieldOperand(edi, FixedArray::kMapOffset), | 2983 __ mov(FieldOperand(edi, FixedArray::kMapOffset), |
3220 Immediate(FACTORY->fixed_array_map())); | 2984 Immediate(masm->isolate()->factory()->fixed_array_map())); |
3221 | 2985 |
3222 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); | 2986 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); |
3223 // Untag the length for the loop below. | 2987 // Untag the length for the loop below. |
3224 __ SmiUntag(ecx); | 2988 __ SmiUntag(ecx); |
3225 | 2989 |
3226 // Copy the fixed array slots. | 2990 // Copy the fixed array slots. |
3227 Label loop; | 2991 Label loop; |
3228 __ bind(&loop); | 2992 __ bind(&loop); |
3229 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver. | 2993 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver. |
3230 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx); | 2994 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx); |
3231 __ add(Operand(edi), Immediate(kPointerSize)); | 2995 __ add(Operand(edi), Immediate(kPointerSize)); |
3232 __ sub(Operand(edx), Immediate(kPointerSize)); | 2996 __ sub(Operand(edx), Immediate(kPointerSize)); |
3233 __ dec(ecx); | 2997 __ dec(ecx); |
3234 __ j(not_zero, &loop); | 2998 __ j(not_zero, &loop); |
3235 | 2999 |
3236 // Return and remove the on-stack parameters. | 3000 // Return and remove the on-stack parameters. |
3237 __ bind(&done); | 3001 __ bind(&done); |
3238 __ ret(3 * kPointerSize); | 3002 __ ret(3 * kPointerSize); |
3239 | 3003 |
3240 // Do the runtime call to allocate the arguments object. | 3004 // Do the runtime call to allocate the arguments object. |
3241 __ bind(&runtime); | 3005 __ bind(&runtime); |
3242 __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1); | 3006 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1); |
3243 } | 3007 } |
3244 | 3008 |
3245 | 3009 |
3246 void RegExpExecStub::Generate(MacroAssembler* masm) { | 3010 void RegExpExecStub::Generate(MacroAssembler* masm) { |
3247 // Just jump directly to runtime if native RegExp is not selected at compile | 3011 // Just jump directly to runtime if native RegExp is not selected at compile |
3248 // time or if regexp entry in generated code is turned off runtime switch or | 3012 // time or if regexp entry in generated code is turned off runtime switch or |
3249 // at compilation. | 3013 // at compilation. |
3250 #ifdef V8_INTERPRETED_REGEXP | 3014 #ifdef V8_INTERPRETED_REGEXP |
3251 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); | 3015 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); |
3252 #else // V8_INTERPRETED_REGEXP | 3016 #else // V8_INTERPRETED_REGEXP |
(...skipping 3159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6412 __ Drop(1); | 6176 __ Drop(1); |
6413 __ ret(2 * kPointerSize); | 6177 __ ret(2 * kPointerSize); |
6414 } | 6178 } |
6415 | 6179 |
6416 | 6180 |
6417 #undef __ | 6181 #undef __ |
6418 | 6182 |
6419 } } // namespace v8::internal | 6183 } } // namespace v8::internal |
6420 | 6184 |
6421 #endif // V8_TARGET_ARCH_IA32 | 6185 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |