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::GenerateNewObject(MacroAssembler* masm) { | 2901 void ArgumentsAccessStub::GenerateNewNonStrictSlow(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[16] : function | 2905 // esp[12] : function |
2906 | 2906 |
2907 // The displacement is used for skipping the return address and the | 2907 // Check if the calling frame is an arguments adaptor frame. |
2908 // frame pointer on the stack. It is the offset of the last | 2908 Label runtime; |
2909 // parameter (if any) relative to the frame pointer. | 2909 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
2910 static const int kDisplacement = 2 * kPointerSize; | 2910 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
| 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 |
2911 | 3154 |
2912 // Check if the calling frame is an arguments adaptor frame. | 3155 // Check if the calling frame is an arguments adaptor frame. |
2913 Label adaptor_frame, try_allocate, runtime; | 3156 Label adaptor_frame, try_allocate, runtime; |
2914 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); | 3157 __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerFPOffset)); |
2915 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); | 3158 __ mov(ecx, Operand(edx, StandardFrameConstants::kContextOffset)); |
2916 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); | 3159 __ cmp(Operand(ecx), Immediate(Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR))); |
2917 __ j(equal, &adaptor_frame); | 3160 __ j(equal, &adaptor_frame); |
2918 | 3161 |
2919 // Get the length from the frame. | 3162 // Get the length from the frame. |
2920 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 3163 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
2921 __ jmp(&try_allocate); | 3164 __ jmp(&try_allocate); |
2922 | 3165 |
2923 // Patch the arguments.length and the parameters pointer. | 3166 // Patch the arguments.length and the parameters pointer. |
2924 __ bind(&adaptor_frame); | 3167 __ bind(&adaptor_frame); |
2925 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); | 3168 __ mov(ecx, Operand(edx, ArgumentsAdaptorFrameConstants::kLengthOffset)); |
2926 __ mov(Operand(esp, 1 * kPointerSize), ecx); | 3169 __ mov(Operand(esp, 1 * kPointerSize), ecx); |
2927 __ lea(edx, Operand(edx, ecx, times_2, kDisplacement)); | 3170 __ lea(edx, Operand(edx, ecx, times_2, |
| 3171 StandardFrameConstants::kCallerSPOffset)); |
2928 __ mov(Operand(esp, 2 * kPointerSize), edx); | 3172 __ mov(Operand(esp, 2 * kPointerSize), edx); |
2929 | 3173 |
2930 // Try the new space allocation. Start out with computing the size of | 3174 // Try the new space allocation. Start out with computing the size of |
2931 // the arguments object and the elements array. | 3175 // the arguments object and the elements array. |
2932 Label add_arguments_object; | 3176 Label add_arguments_object; |
2933 __ bind(&try_allocate); | 3177 __ bind(&try_allocate); |
2934 __ test(ecx, Operand(ecx)); | 3178 __ test(ecx, Operand(ecx)); |
2935 __ j(zero, &add_arguments_object, Label::kNear); | 3179 __ j(zero, &add_arguments_object, Label::kNear); |
2936 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); | 3180 __ lea(ecx, Operand(ecx, times_2, FixedArray::kHeaderSize)); |
2937 __ bind(&add_arguments_object); | 3181 __ bind(&add_arguments_object); |
2938 __ add(Operand(ecx), Immediate(GetArgumentsObjectSize())); | 3182 __ add(Operand(ecx), Immediate(Heap::kArgumentsObjectSizeStrict)); |
2939 | 3183 |
2940 // Do the allocation of both objects in one go. | 3184 // Do the allocation of both objects in one go. |
2941 __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); | 3185 __ AllocateInNewSpace(ecx, eax, edx, ebx, &runtime, TAG_OBJECT); |
2942 | 3186 |
2943 // Get the arguments boilerplate from the current (global) context. | 3187 // Get the arguments boilerplate from the current (global) context. |
2944 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); | 3188 __ mov(edi, Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
2945 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset)); | 3189 __ mov(edi, FieldOperand(edi, GlobalObject::kGlobalContextOffset)); |
2946 __ mov(edi, Operand(edi, | 3190 const int offset = |
2947 Context::SlotOffset(GetArgumentsBoilerplateIndex()))); | 3191 Context::SlotOffset(Context::STRICT_MODE_ARGUMENTS_BOILERPLATE_INDEX); |
| 3192 __ mov(edi, Operand(edi, offset)); |
2948 | 3193 |
2949 // Copy the JS object part. | 3194 // Copy the JS object part. |
2950 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { | 3195 for (int i = 0; i < JSObject::kHeaderSize; i += kPointerSize) { |
2951 __ mov(ebx, FieldOperand(edi, i)); | 3196 __ mov(ebx, FieldOperand(edi, i)); |
2952 __ mov(FieldOperand(eax, i), ebx); | 3197 __ mov(FieldOperand(eax, i), ebx); |
2953 } | 3198 } |
2954 | 3199 |
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 | |
2964 // Get the length (smi tagged) and set that as an in-object property too. | 3200 // Get the length (smi tagged) and set that as an in-object property too. |
2965 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); | 3201 STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0); |
2966 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 3202 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
2967 __ mov(FieldOperand(eax, JSObject::kHeaderSize + | 3203 __ mov(FieldOperand(eax, JSObject::kHeaderSize + |
2968 Heap::kArgumentsLengthIndex * kPointerSize), | 3204 Heap::kArgumentsLengthIndex * kPointerSize), |
2969 ecx); | 3205 ecx); |
2970 | 3206 |
2971 // If there are no actual arguments, we're done. | 3207 // If there are no actual arguments, we're done. |
2972 Label done; | 3208 Label done; |
2973 __ test(ecx, Operand(ecx)); | 3209 __ test(ecx, Operand(ecx)); |
2974 __ j(zero, &done); | 3210 __ j(zero, &done); |
2975 | 3211 |
2976 // Get the parameters pointer from the stack. | 3212 // Get the parameters pointer from the stack. |
2977 __ mov(edx, Operand(esp, 2 * kPointerSize)); | 3213 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
2978 | 3214 |
2979 // Setup the elements pointer in the allocated arguments object and | 3215 // Setup the elements pointer in the allocated arguments object and |
2980 // initialize the header in the elements fixed array. | 3216 // initialize the header in the elements fixed array. |
2981 __ lea(edi, Operand(eax, GetArgumentsObjectSize())); | 3217 __ lea(edi, Operand(eax, Heap::kArgumentsObjectSizeStrict)); |
2982 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); | 3218 __ mov(FieldOperand(eax, JSObject::kElementsOffset), edi); |
2983 __ mov(FieldOperand(edi, FixedArray::kMapOffset), | 3219 __ mov(FieldOperand(edi, FixedArray::kMapOffset), |
2984 Immediate(masm->isolate()->factory()->fixed_array_map())); | 3220 Immediate(FACTORY->fixed_array_map())); |
2985 | 3221 |
2986 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); | 3222 __ mov(FieldOperand(edi, FixedArray::kLengthOffset), ecx); |
2987 // Untag the length for the loop below. | 3223 // Untag the length for the loop below. |
2988 __ SmiUntag(ecx); | 3224 __ SmiUntag(ecx); |
2989 | 3225 |
2990 // Copy the fixed array slots. | 3226 // Copy the fixed array slots. |
2991 Label loop; | 3227 Label loop; |
2992 __ bind(&loop); | 3228 __ bind(&loop); |
2993 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver. | 3229 __ mov(ebx, Operand(edx, -1 * kPointerSize)); // Skip receiver. |
2994 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx); | 3230 __ mov(FieldOperand(edi, FixedArray::kHeaderSize), ebx); |
2995 __ add(Operand(edi), Immediate(kPointerSize)); | 3231 __ add(Operand(edi), Immediate(kPointerSize)); |
2996 __ sub(Operand(edx), Immediate(kPointerSize)); | 3232 __ sub(Operand(edx), Immediate(kPointerSize)); |
2997 __ dec(ecx); | 3233 __ dec(ecx); |
2998 __ j(not_zero, &loop); | 3234 __ j(not_zero, &loop); |
2999 | 3235 |
3000 // Return and remove the on-stack parameters. | 3236 // Return and remove the on-stack parameters. |
3001 __ bind(&done); | 3237 __ bind(&done); |
3002 __ ret(3 * kPointerSize); | 3238 __ ret(3 * kPointerSize); |
3003 | 3239 |
3004 // Do the runtime call to allocate the arguments object. | 3240 // Do the runtime call to allocate the arguments object. |
3005 __ bind(&runtime); | 3241 __ bind(&runtime); |
3006 __ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1); | 3242 __ TailCallRuntime(Runtime::kNewStrictArgumentsFast, 3, 1); |
3007 } | 3243 } |
3008 | 3244 |
3009 | 3245 |
3010 void RegExpExecStub::Generate(MacroAssembler* masm) { | 3246 void RegExpExecStub::Generate(MacroAssembler* masm) { |
3011 // Just jump directly to runtime if native RegExp is not selected at compile | 3247 // Just jump directly to runtime if native RegExp is not selected at compile |
3012 // time or if regexp entry in generated code is turned off runtime switch or | 3248 // time or if regexp entry in generated code is turned off runtime switch or |
3013 // at compilation. | 3249 // at compilation. |
3014 #ifdef V8_INTERPRETED_REGEXP | 3250 #ifdef V8_INTERPRETED_REGEXP |
3015 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); | 3251 __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); |
3016 #else // V8_INTERPRETED_REGEXP | 3252 #else // V8_INTERPRETED_REGEXP |
(...skipping 3159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6176 __ Drop(1); | 6412 __ Drop(1); |
6177 __ ret(2 * kPointerSize); | 6413 __ ret(2 * kPointerSize); |
6178 } | 6414 } |
6179 | 6415 |
6180 | 6416 |
6181 #undef __ | 6417 #undef __ |
6182 | 6418 |
6183 } } // namespace v8::internal | 6419 } } // namespace v8::internal |
6184 | 6420 |
6185 #endif // V8_TARGET_ARCH_IA32 | 6421 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |