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

Side by Side Diff: src/x64/code-stubs-x64.cc

Issue 2645743002: [builtins] Port parameter and argument-related code stubs to CSA (Closed)
Patch Set: Review feedback Created 3 years, 10 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
« no previous file with comments | « src/v8.gyp ('k') | src/x64/interface-descriptors-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_X64 5 #if V8_TARGET_ARCH_X64
6 6
7 #include "src/code-stubs.h" 7 #include "src/code-stubs.h"
8 #include "src/api-arguments.h" 8 #include "src/api-arguments.h"
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 3004 matching lines...) Expand 10 before | Expand all | Expand 10 after
3015 3015
3016 Label fast_elements_case; 3016 Label fast_elements_case;
3017 __ cmpl(rcx, Immediate(FAST_ELEMENTS)); 3017 __ cmpl(rcx, Immediate(FAST_ELEMENTS));
3018 __ j(equal, &fast_elements_case); 3018 __ j(equal, &fast_elements_case);
3019 GenerateCase(masm, FAST_HOLEY_ELEMENTS); 3019 GenerateCase(masm, FAST_HOLEY_ELEMENTS);
3020 3020
3021 __ bind(&fast_elements_case); 3021 __ bind(&fast_elements_case);
3022 GenerateCase(masm, FAST_ELEMENTS); 3022 GenerateCase(masm, FAST_ELEMENTS);
3023 } 3023 }
3024 3024
3025 void FastNewRestParameterStub::Generate(MacroAssembler* masm) {
3026 // ----------- S t a t e -------------
3027 // -- rdi : function
3028 // -- rsi : context
3029 // -- rbp : frame pointer
3030 // -- rsp[0] : return address
3031 // -----------------------------------
3032 __ AssertFunction(rdi);
3033
3034 // Make rdx point to the JavaScript frame.
3035 __ movp(rdx, rbp);
3036 if (skip_stub_frame()) {
3037 // For Ignition we need to skip the handler/stub frame to reach the
3038 // JavaScript frame for the function.
3039 __ movp(rdx, Operand(rdx, StandardFrameConstants::kCallerFPOffset));
3040 }
3041 if (FLAG_debug_code) {
3042 Label ok;
3043 __ cmpp(rdi, Operand(rdx, StandardFrameConstants::kFunctionOffset));
3044 __ j(equal, &ok);
3045 __ Abort(kInvalidFrameForFastNewRestArgumentsStub);
3046 __ bind(&ok);
3047 }
3048
3049 // Check if we have rest parameters (only possible if we have an
3050 // arguments adaptor frame below the function frame).
3051 Label no_rest_parameters;
3052 __ movp(rbx, Operand(rdx, StandardFrameConstants::kCallerFPOffset));
3053 __ Cmp(Operand(rbx, CommonFrameConstants::kContextOrFrameTypeOffset),
3054 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
3055 __ j(not_equal, &no_rest_parameters, Label::kNear);
3056
3057 // Check if the arguments adaptor frame contains more arguments than
3058 // specified by the function's internal formal parameter count.
3059 Label rest_parameters;
3060 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
3061 __ LoadSharedFunctionInfoSpecialField(
3062 rcx, rcx, SharedFunctionInfo::kFormalParameterCountOffset);
3063 __ SmiToInteger32(
3064 rax, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
3065 __ subl(rax, rcx);
3066 __ j(greater, &rest_parameters);
3067
3068 // Return an empty rest parameter array.
3069 __ bind(&no_rest_parameters);
3070 {
3071 // ----------- S t a t e -------------
3072 // -- rsi : context
3073 // -- rsp[0] : return address
3074 // -----------------------------------
3075
3076 // Allocate an empty rest parameter array.
3077 Label allocate, done_allocate;
3078 __ Allocate(JSArray::kSize, rax, rdx, rcx, &allocate, NO_ALLOCATION_FLAGS);
3079 __ bind(&done_allocate);
3080
3081 // Setup the rest parameter array in rax.
3082 __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, rcx);
3083 __ movp(FieldOperand(rax, JSArray::kMapOffset), rcx);
3084 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex);
3085 __ movp(FieldOperand(rax, JSArray::kPropertiesOffset), rcx);
3086 __ movp(FieldOperand(rax, JSArray::kElementsOffset), rcx);
3087 __ movp(FieldOperand(rax, JSArray::kLengthOffset), Immediate(0));
3088 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
3089 __ Ret();
3090
3091 // Fall back to %AllocateInNewSpace.
3092 __ bind(&allocate);
3093 {
3094 FrameScope scope(masm, StackFrame::INTERNAL);
3095 __ Push(Smi::FromInt(JSArray::kSize));
3096 __ CallRuntime(Runtime::kAllocateInNewSpace);
3097 }
3098 __ jmp(&done_allocate);
3099 }
3100
3101 __ bind(&rest_parameters);
3102 {
3103 // Compute the pointer to the first rest parameter (skippping the receiver).
3104 __ leap(rbx, Operand(rbx, rax, times_pointer_size,
3105 StandardFrameConstants::kCallerSPOffset -
3106 1 * kPointerSize));
3107
3108 // ----------- S t a t e -------------
3109 // -- rdi : function
3110 // -- rsi : context
3111 // -- rax : number of rest parameters
3112 // -- rbx : pointer to first rest parameters
3113 // -- rsp[0] : return address
3114 // -----------------------------------
3115
3116 // Allocate space for the rest parameter array plus the backing store.
3117 Label allocate, done_allocate;
3118 __ leal(rcx, Operand(rax, times_pointer_size,
3119 JSArray::kSize + FixedArray::kHeaderSize));
3120 __ Allocate(rcx, rdx, r8, no_reg, &allocate, NO_ALLOCATION_FLAGS);
3121 __ bind(&done_allocate);
3122
3123 // Compute the arguments.length in rdi.
3124 __ Integer32ToSmi(rdi, rax);
3125
3126 // Setup the elements array in rdx.
3127 __ LoadRoot(rcx, Heap::kFixedArrayMapRootIndex);
3128 __ movp(FieldOperand(rdx, FixedArray::kMapOffset), rcx);
3129 __ movp(FieldOperand(rdx, FixedArray::kLengthOffset), rdi);
3130 {
3131 Label loop, done_loop;
3132 __ Set(rcx, 0);
3133 __ bind(&loop);
3134 __ cmpl(rcx, rax);
3135 __ j(equal, &done_loop, Label::kNear);
3136 __ movp(kScratchRegister, Operand(rbx, 0 * kPointerSize));
3137 __ movp(
3138 FieldOperand(rdx, rcx, times_pointer_size, FixedArray::kHeaderSize),
3139 kScratchRegister);
3140 __ subp(rbx, Immediate(1 * kPointerSize));
3141 __ addl(rcx, Immediate(1));
3142 __ jmp(&loop);
3143 __ bind(&done_loop);
3144 }
3145
3146 // Setup the rest parameter array in rax.
3147 __ leap(rax,
3148 Operand(rdx, rax, times_pointer_size, FixedArray::kHeaderSize));
3149 __ LoadNativeContextSlot(Context::JS_ARRAY_FAST_ELEMENTS_MAP_INDEX, rcx);
3150 __ movp(FieldOperand(rax, JSArray::kMapOffset), rcx);
3151 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex);
3152 __ movp(FieldOperand(rax, JSArray::kPropertiesOffset), rcx);
3153 __ movp(FieldOperand(rax, JSArray::kElementsOffset), rdx);
3154 __ movp(FieldOperand(rax, JSArray::kLengthOffset), rdi);
3155 STATIC_ASSERT(JSArray::kSize == 4 * kPointerSize);
3156 __ Ret();
3157
3158 // Fall back to %AllocateInNewSpace (if not too big).
3159 Label too_big_for_new_space;
3160 __ bind(&allocate);
3161 __ cmpl(rcx, Immediate(kMaxRegularHeapObjectSize));
3162 __ j(greater, &too_big_for_new_space);
3163 {
3164 FrameScope scope(masm, StackFrame::INTERNAL);
3165 __ Integer32ToSmi(rax, rax);
3166 __ Integer32ToSmi(rcx, rcx);
3167 __ Push(rax);
3168 __ Push(rbx);
3169 __ Push(rcx);
3170 __ CallRuntime(Runtime::kAllocateInNewSpace);
3171 __ movp(rdx, rax);
3172 __ Pop(rbx);
3173 __ Pop(rax);
3174 __ SmiToInteger32(rax, rax);
3175 }
3176 __ jmp(&done_allocate);
3177
3178 // Fall back to %NewRestParameter.
3179 __ bind(&too_big_for_new_space);
3180 __ PopReturnAddressTo(kScratchRegister);
3181 __ Push(rdi);
3182 __ PushReturnAddressFrom(kScratchRegister);
3183 __ TailCallRuntime(Runtime::kNewRestParameter);
3184 }
3185 }
3186
3187
3188 void FastNewSloppyArgumentsStub::Generate(MacroAssembler* masm) {
3189 // ----------- S t a t e -------------
3190 // -- rdi : function
3191 // -- rsi : context
3192 // -- rbp : frame pointer
3193 // -- rsp[0] : return address
3194 // -----------------------------------
3195 __ AssertFunction(rdi);
3196
3197 // Make r9 point to the JavaScript frame.
3198 __ movp(r9, rbp);
3199 if (skip_stub_frame()) {
3200 // For Ignition we need to skip the handler/stub frame to reach the
3201 // JavaScript frame for the function.
3202 __ movp(r9, Operand(r9, StandardFrameConstants::kCallerFPOffset));
3203 }
3204 if (FLAG_debug_code) {
3205 Label ok;
3206 __ cmpp(rdi, Operand(r9, StandardFrameConstants::kFunctionOffset));
3207 __ j(equal, &ok);
3208 __ Abort(kInvalidFrameForFastNewRestArgumentsStub);
3209 __ bind(&ok);
3210 }
3211
3212 // TODO(bmeurer): Cleanup to match the FastNewStrictArgumentsStub.
3213 __ movp(rcx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
3214 __ LoadSharedFunctionInfoSpecialField(
3215 rcx, rcx, SharedFunctionInfo::kFormalParameterCountOffset);
3216 __ leap(rdx, Operand(r9, rcx, times_pointer_size,
3217 StandardFrameConstants::kCallerSPOffset));
3218 __ Integer32ToSmi(rcx, rcx);
3219
3220 // rcx : number of parameters (tagged)
3221 // rdx : parameters pointer
3222 // rdi : function
3223 // rsp[0] : return address
3224 // r9 : JavaScript frame pointer.
3225 // Registers used over the whole function:
3226 // rbx: the mapped parameter count (untagged)
3227 // rax: the allocated object (tagged).
3228 Factory* factory = isolate()->factory();
3229
3230 __ SmiToInteger64(rbx, rcx);
3231 // rbx = parameter count (untagged)
3232
3233 // Check if the calling frame is an arguments adaptor frame.
3234 Label adaptor_frame, try_allocate, runtime;
3235 __ movp(rax, Operand(r9, StandardFrameConstants::kCallerFPOffset));
3236 __ movp(r8, Operand(rax, CommonFrameConstants::kContextOrFrameTypeOffset));
3237 __ Cmp(r8, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
3238 __ j(equal, &adaptor_frame);
3239
3240 // No adaptor, parameter count = argument count.
3241 __ movp(r11, rbx);
3242 __ jmp(&try_allocate, Label::kNear);
3243
3244 // We have an adaptor frame. Patch the parameters pointer.
3245 __ bind(&adaptor_frame);
3246 __ SmiToInteger64(
3247 r11, Operand(rax, ArgumentsAdaptorFrameConstants::kLengthOffset));
3248 __ leap(rdx, Operand(rax, r11, times_pointer_size,
3249 StandardFrameConstants::kCallerSPOffset));
3250
3251 // rbx = parameter count (untagged)
3252 // r11 = argument count (untagged)
3253 // Compute the mapped parameter count = min(rbx, r11) in rbx.
3254 __ cmpp(rbx, r11);
3255 __ j(less_equal, &try_allocate, Label::kNear);
3256 __ movp(rbx, r11);
3257
3258 __ bind(&try_allocate);
3259
3260 // Compute the sizes of backing store, parameter map, and arguments object.
3261 // 1. Parameter map, has 2 extra words containing context and backing store.
3262 const int kParameterMapHeaderSize =
3263 FixedArray::kHeaderSize + 2 * kPointerSize;
3264 Label no_parameter_map;
3265 __ xorp(r8, r8);
3266 __ testp(rbx, rbx);
3267 __ j(zero, &no_parameter_map, Label::kNear);
3268 __ leap(r8, Operand(rbx, times_pointer_size, kParameterMapHeaderSize));
3269 __ bind(&no_parameter_map);
3270
3271 // 2. Backing store.
3272 __ leap(r8, Operand(r8, r11, times_pointer_size, FixedArray::kHeaderSize));
3273
3274 // 3. Arguments object.
3275 __ addp(r8, Immediate(JSSloppyArgumentsObject::kSize));
3276
3277 // Do the allocation of all three objects in one go.
3278 __ Allocate(r8, rax, r9, no_reg, &runtime, NO_ALLOCATION_FLAGS);
3279
3280 // rax = address of new object(s) (tagged)
3281 // r11 = argument count (untagged)
3282 // Get the arguments map from the current native context into r9.
3283 Label has_mapped_parameters, instantiate;
3284 __ movp(r9, NativeContextOperand());
3285 __ testp(rbx, rbx);
3286 __ j(not_zero, &has_mapped_parameters, Label::kNear);
3287
3288 const int kIndex = Context::SLOPPY_ARGUMENTS_MAP_INDEX;
3289 __ movp(r9, Operand(r9, Context::SlotOffset(kIndex)));
3290 __ jmp(&instantiate, Label::kNear);
3291
3292 const int kAliasedIndex = Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX;
3293 __ bind(&has_mapped_parameters);
3294 __ movp(r9, Operand(r9, Context::SlotOffset(kAliasedIndex)));
3295 __ bind(&instantiate);
3296
3297 // rax = address of new object (tagged)
3298 // rbx = mapped parameter count (untagged)
3299 // r11 = argument count (untagged)
3300 // r9 = address of arguments map (tagged)
3301 __ movp(FieldOperand(rax, JSObject::kMapOffset), r9);
3302 __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex);
3303 __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister);
3304 __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister);
3305
3306 // Set up the callee in-object property.
3307 __ AssertNotSmi(rdi);
3308 __ movp(FieldOperand(rax, JSSloppyArgumentsObject::kCalleeOffset), rdi);
3309
3310 // Use the length (smi tagged) and set that as an in-object property too.
3311 // Note: r11 is tagged from here on.
3312 __ Integer32ToSmi(r11, r11);
3313 __ movp(FieldOperand(rax, JSSloppyArgumentsObject::kLengthOffset), r11);
3314
3315 // Set up the elements pointer in the allocated arguments object.
3316 // If we allocated a parameter map, rdi will point there, otherwise to the
3317 // backing store.
3318 __ leap(rdi, Operand(rax, JSSloppyArgumentsObject::kSize));
3319 __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi);
3320
3321 // rax = address of new object (tagged)
3322 // rbx = mapped parameter count (untagged)
3323 // r11 = argument count (tagged)
3324 // rdi = address of parameter map or backing store (tagged)
3325
3326 // Initialize parameter map. If there are no mapped arguments, we're done.
3327 Label skip_parameter_map;
3328 __ testp(rbx, rbx);
3329 __ j(zero, &skip_parameter_map);
3330
3331 __ LoadRoot(kScratchRegister, Heap::kSloppyArgumentsElementsMapRootIndex);
3332 // rbx contains the untagged argument count. Add 2 and tag to write.
3333 __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
3334 __ Integer64PlusConstantToSmi(r9, rbx, 2);
3335 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r9);
3336 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 0 * kPointerSize), rsi);
3337 __ leap(r9, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize));
3338 __ movp(FieldOperand(rdi, FixedArray::kHeaderSize + 1 * kPointerSize), r9);
3339
3340 // Copy the parameter slots and the holes in the arguments.
3341 // We need to fill in mapped_parameter_count slots. They index the context,
3342 // where parameters are stored in reverse order, at
3343 // MIN_CONTEXT_SLOTS .. MIN_CONTEXT_SLOTS+parameter_count-1
3344 // The mapped parameter thus need to get indices
3345 // MIN_CONTEXT_SLOTS+parameter_count-1 ..
3346 // MIN_CONTEXT_SLOTS+parameter_count-mapped_parameter_count
3347 // We loop from right to left.
3348 Label parameters_loop, parameters_test;
3349
3350 // Load tagged parameter count into r9.
3351 __ Integer32ToSmi(r9, rbx);
3352 __ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS));
3353 __ addp(r8, rcx);
3354 __ subp(r8, r9);
3355 __ movp(rcx, rdi);
3356 __ leap(rdi, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize));
3357 __ SmiToInteger64(r9, r9);
3358 // r9 = loop variable (untagged)
3359 // r8 = mapping index (tagged)
3360 // rcx = address of parameter map (tagged)
3361 // rdi = address of backing store (tagged)
3362 __ jmp(&parameters_test, Label::kNear);
3363
3364 __ bind(&parameters_loop);
3365 __ subp(r9, Immediate(1));
3366 __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
3367 __ movp(FieldOperand(rcx, r9, times_pointer_size, kParameterMapHeaderSize),
3368 r8);
3369 __ movp(FieldOperand(rdi, r9, times_pointer_size, FixedArray::kHeaderSize),
3370 kScratchRegister);
3371 __ SmiAddConstant(r8, r8, Smi::FromInt(1));
3372 __ bind(&parameters_test);
3373 __ testp(r9, r9);
3374 __ j(not_zero, &parameters_loop, Label::kNear);
3375
3376 __ bind(&skip_parameter_map);
3377
3378 // r11 = argument count (tagged)
3379 // rdi = address of backing store (tagged)
3380 // Copy arguments header and remaining slots (if there are any).
3381 __ Move(FieldOperand(rdi, FixedArray::kMapOffset),
3382 factory->fixed_array_map());
3383 __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r11);
3384
3385 Label arguments_loop, arguments_test;
3386 __ movp(r8, rbx);
3387 // Untag r11 for the loop below.
3388 __ SmiToInteger64(r11, r11);
3389 __ leap(kScratchRegister, Operand(r8, times_pointer_size, 0));
3390 __ subp(rdx, kScratchRegister);
3391 __ jmp(&arguments_test, Label::kNear);
3392
3393 __ bind(&arguments_loop);
3394 __ subp(rdx, Immediate(kPointerSize));
3395 __ movp(r9, Operand(rdx, 0));
3396 __ movp(FieldOperand(rdi, r8,
3397 times_pointer_size,
3398 FixedArray::kHeaderSize),
3399 r9);
3400 __ addp(r8, Immediate(1));
3401
3402 __ bind(&arguments_test);
3403 __ cmpp(r8, r11);
3404 __ j(less, &arguments_loop, Label::kNear);
3405
3406 // Return.
3407 __ ret(0);
3408
3409 // Do the runtime call to allocate the arguments object.
3410 // r11 = argument count (untagged)
3411 __ bind(&runtime);
3412 __ Integer32ToSmi(r11, r11);
3413 __ PopReturnAddressTo(rax);
3414 __ Push(rdi); // Push function.
3415 __ Push(rdx); // Push parameters pointer.
3416 __ Push(r11); // Push parameter count.
3417 __ PushReturnAddressFrom(rax);
3418 __ TailCallRuntime(Runtime::kNewSloppyArguments);
3419 }
3420
3421
3422 void FastNewStrictArgumentsStub::Generate(MacroAssembler* masm) {
3423 // ----------- S t a t e -------------
3424 // -- rdi : function
3425 // -- rsi : context
3426 // -- rbp : frame pointer
3427 // -- rsp[0] : return address
3428 // -----------------------------------
3429 __ AssertFunction(rdi);
3430
3431 // Make rdx point to the JavaScript frame.
3432 __ movp(rdx, rbp);
3433 if (skip_stub_frame()) {
3434 // For Ignition we need to skip the handler/stub frame to reach the
3435 // JavaScript frame for the function.
3436 __ movp(rdx, Operand(rdx, StandardFrameConstants::kCallerFPOffset));
3437 }
3438 if (FLAG_debug_code) {
3439 Label ok;
3440 __ cmpp(rdi, Operand(rdx, StandardFrameConstants::kFunctionOffset));
3441 __ j(equal, &ok);
3442 __ Abort(kInvalidFrameForFastNewRestArgumentsStub);
3443 __ bind(&ok);
3444 }
3445
3446 // Check if we have an arguments adaptor frame below the function frame.
3447 Label arguments_adaptor, arguments_done;
3448 __ movp(rbx, Operand(rdx, StandardFrameConstants::kCallerFPOffset));
3449 __ Cmp(Operand(rbx, CommonFrameConstants::kContextOrFrameTypeOffset),
3450 Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
3451 __ j(equal, &arguments_adaptor, Label::kNear);
3452 {
3453 __ movp(rax, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
3454 __ LoadSharedFunctionInfoSpecialField(
3455 rax, rax, SharedFunctionInfo::kFormalParameterCountOffset);
3456 __ leap(rbx, Operand(rdx, rax, times_pointer_size,
3457 StandardFrameConstants::kCallerSPOffset -
3458 1 * kPointerSize));
3459 }
3460 __ jmp(&arguments_done, Label::kNear);
3461 __ bind(&arguments_adaptor);
3462 {
3463 __ SmiToInteger32(
3464 rax, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
3465 __ leap(rbx, Operand(rbx, rax, times_pointer_size,
3466 StandardFrameConstants::kCallerSPOffset -
3467 1 * kPointerSize));
3468 }
3469 __ bind(&arguments_done);
3470
3471 // ----------- S t a t e -------------
3472 // -- rax : number of arguments
3473 // -- rbx : pointer to the first argument
3474 // -- rdi : function
3475 // -- rsi : context
3476 // -- rsp[0] : return address
3477 // -----------------------------------
3478
3479 // Allocate space for the strict arguments object plus the backing store.
3480 Label allocate, done_allocate;
3481 __ leal(rcx, Operand(rax, times_pointer_size, JSStrictArgumentsObject::kSize +
3482 FixedArray::kHeaderSize));
3483 __ Allocate(rcx, rdx, r8, no_reg, &allocate, NO_ALLOCATION_FLAGS);
3484 __ bind(&done_allocate);
3485
3486 // Compute the arguments.length in rdi.
3487 __ Integer32ToSmi(rdi, rax);
3488
3489 // Setup the elements array in rdx.
3490 __ LoadRoot(rcx, Heap::kFixedArrayMapRootIndex);
3491 __ movp(FieldOperand(rdx, FixedArray::kMapOffset), rcx);
3492 __ movp(FieldOperand(rdx, FixedArray::kLengthOffset), rdi);
3493 {
3494 Label loop, done_loop;
3495 __ Set(rcx, 0);
3496 __ bind(&loop);
3497 __ cmpl(rcx, rax);
3498 __ j(equal, &done_loop, Label::kNear);
3499 __ movp(kScratchRegister, Operand(rbx, 0 * kPointerSize));
3500 __ movp(
3501 FieldOperand(rdx, rcx, times_pointer_size, FixedArray::kHeaderSize),
3502 kScratchRegister);
3503 __ subp(rbx, Immediate(1 * kPointerSize));
3504 __ addl(rcx, Immediate(1));
3505 __ jmp(&loop);
3506 __ bind(&done_loop);
3507 }
3508
3509 // Setup the strict arguments object in rax.
3510 __ leap(rax,
3511 Operand(rdx, rax, times_pointer_size, FixedArray::kHeaderSize));
3512 __ LoadNativeContextSlot(Context::STRICT_ARGUMENTS_MAP_INDEX, rcx);
3513 __ movp(FieldOperand(rax, JSStrictArgumentsObject::kMapOffset), rcx);
3514 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex);
3515 __ movp(FieldOperand(rax, JSStrictArgumentsObject::kPropertiesOffset), rcx);
3516 __ movp(FieldOperand(rax, JSStrictArgumentsObject::kElementsOffset), rdx);
3517 __ movp(FieldOperand(rax, JSStrictArgumentsObject::kLengthOffset), rdi);
3518 STATIC_ASSERT(JSStrictArgumentsObject::kSize == 4 * kPointerSize);
3519 __ Ret();
3520
3521 // Fall back to %AllocateInNewSpace (if not too big).
3522 Label too_big_for_new_space;
3523 __ bind(&allocate);
3524 __ cmpl(rcx, Immediate(kMaxRegularHeapObjectSize));
3525 __ j(greater, &too_big_for_new_space);
3526 {
3527 FrameScope scope(masm, StackFrame::INTERNAL);
3528 __ Integer32ToSmi(rax, rax);
3529 __ Integer32ToSmi(rcx, rcx);
3530 __ Push(rax);
3531 __ Push(rbx);
3532 __ Push(rcx);
3533 __ CallRuntime(Runtime::kAllocateInNewSpace);
3534 __ movp(rdx, rax);
3535 __ Pop(rbx);
3536 __ Pop(rax);
3537 __ SmiToInteger32(rax, rax);
3538 }
3539 __ jmp(&done_allocate);
3540
3541 // Fall back to %NewStrictArguments.
3542 __ bind(&too_big_for_new_space);
3543 __ PopReturnAddressTo(kScratchRegister);
3544 __ Push(rdi);
3545 __ PushReturnAddressFrom(kScratchRegister);
3546 __ TailCallRuntime(Runtime::kNewStrictArguments);
3547 }
3548
3549
3550 static int Offset(ExternalReference ref0, ExternalReference ref1) { 3025 static int Offset(ExternalReference ref0, ExternalReference ref1) {
3551 int64_t offset = (ref0.address() - ref1.address()); 3026 int64_t offset = (ref0.address() - ref1.address());
3552 // Check that fits into int. 3027 // Check that fits into int.
3553 DCHECK(static_cast<int>(offset) == offset); 3028 DCHECK(static_cast<int>(offset) == offset);
3554 return static_cast<int>(offset); 3029 return static_cast<int>(offset);
3555 } 3030 }
3556 3031
3557
3558 // Prepares stack to put arguments (aligns and so on). WIN64 calling 3032 // Prepares stack to put arguments (aligns and so on). WIN64 calling
3559 // convention requires to put the pointer to the return value slot into 3033 // convention requires to put the pointer to the return value slot into
3560 // rcx (rcx must be preserverd until CallApiFunctionAndReturn). Saves 3034 // rcx (rcx must be preserverd until CallApiFunctionAndReturn). Saves
3561 // context (rsi). Clobbers rax. Allocates arg_stack_space * kPointerSize 3035 // context (rsi). Clobbers rax. Allocates arg_stack_space * kPointerSize
3562 // inside the exit frame (not GCed) accessible via StackSpaceOperand. 3036 // inside the exit frame (not GCed) accessible via StackSpaceOperand.
3563 static void PrepareCallApiFunction(MacroAssembler* masm, int arg_stack_space) { 3037 static void PrepareCallApiFunction(MacroAssembler* masm, int arg_stack_space) {
3564 __ EnterApiExitFrame(arg_stack_space); 3038 __ EnterApiExitFrame(arg_stack_space);
3565 } 3039 }
3566 3040
3567 3041
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
3931 kStackUnwindSpace, nullptr, return_value_operand, 3405 kStackUnwindSpace, nullptr, return_value_operand,
3932 NULL); 3406 NULL);
3933 } 3407 }
3934 3408
3935 #undef __ 3409 #undef __
3936 3410
3937 } // namespace internal 3411 } // namespace internal
3938 } // namespace v8 3412 } // namespace v8
3939 3413
3940 #endif // V8_TARGET_ARCH_X64 3414 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/v8.gyp ('k') | src/x64/interface-descriptors-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698