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

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

Issue 148573005: A64: Synchronize with r16249. (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/a64
Patch Set: Created 6 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 | Annotate | Revision Log
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/ic.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 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 3238 matching lines...) Expand 10 before | Expand all | Expand 10 after
3249 __ bind(&miss_force_generic); 3249 __ bind(&miss_force_generic);
3250 // ----------- S t a t e ------------- 3250 // ----------- S t a t e -------------
3251 // -- ecx : key 3251 // -- ecx : key
3252 // -- edx : receiver 3252 // -- edx : receiver
3253 // -- esp[0] : return address 3253 // -- esp[0] : return address
3254 // ----------------------------------- 3254 // -----------------------------------
3255 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric); 3255 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3256 } 3256 }
3257 3257
3258 3258
3259 static void GenerateSmiKeyCheck(MacroAssembler* masm,
3260 Register key,
3261 Register scratch,
3262 XMMRegister xmm_scratch0,
3263 XMMRegister xmm_scratch1,
3264 Label* fail) {
3265 // Check that key is a smi and if SSE2 is available a heap number
3266 // containing a smi and branch if the check fails.
3267 if (CpuFeatures::IsSupported(SSE2)) {
3268 CpuFeatureScope use_sse2(masm, SSE2);
3269 Label key_ok;
3270 __ JumpIfSmi(key, &key_ok);
3271 __ cmp(FieldOperand(key, HeapObject::kMapOffset),
3272 Immediate(Handle<Map>(masm->isolate()->heap()->heap_number_map())));
3273 __ j(not_equal, fail);
3274 __ movdbl(xmm_scratch0, FieldOperand(key, HeapNumber::kValueOffset));
3275 __ cvttsd2si(scratch, Operand(xmm_scratch0));
3276 __ cvtsi2sd(xmm_scratch1, scratch);
3277 __ ucomisd(xmm_scratch1, xmm_scratch0);
3278 __ j(not_equal, fail);
3279 __ j(parity_even, fail); // NaN.
3280 // Check if the key fits in the smi range.
3281 __ cmp(scratch, 0xc0000000);
3282 __ j(sign, fail);
3283 __ SmiTag(scratch);
3284 __ mov(key, scratch);
3285 __ bind(&key_ok);
3286 } else {
3287 __ JumpIfNotSmi(key, fail);
3288 }
3289 }
3290
3291
3292 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
3293 MacroAssembler* masm,
3294 ElementsKind elements_kind) {
3295 // ----------- S t a t e -------------
3296 // -- eax : value
3297 // -- ecx : key
3298 // -- edx : receiver
3299 // -- esp[0] : return address
3300 // -----------------------------------
3301 Label miss_force_generic, slow, check_heap_number;
3302
3303 // This stub is meant to be tail-jumped to, the receiver must already
3304 // have been verified by the caller to not be a smi.
3305
3306 // Check that the key is a smi or a heap number convertible to a smi.
3307 GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic);
3308
3309 // Check that the index is in range.
3310 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3311 __ cmp(ecx, FieldOperand(edi, ExternalArray::kLengthOffset));
3312 // Unsigned comparison catches both negative and too-large values.
3313 __ j(above_equal, &slow);
3314
3315 // Handle both smis and HeapNumbers in the fast path. Go to the
3316 // runtime for all other kinds of values.
3317 // eax: value
3318 // edx: receiver
3319 // ecx: key
3320 // edi: elements array
3321 if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) {
3322 __ JumpIfNotSmi(eax, &slow);
3323 } else {
3324 __ JumpIfNotSmi(eax, &check_heap_number);
3325 }
3326
3327 // smi case
3328 __ mov(ebx, eax); // Preserve the value in eax as the return value.
3329 __ SmiUntag(ebx);
3330 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3331 // edi: base pointer of external storage
3332 switch (elements_kind) {
3333 case EXTERNAL_PIXEL_ELEMENTS:
3334 __ ClampUint8(ebx);
3335 __ SmiUntag(ecx);
3336 __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
3337 break;
3338 case EXTERNAL_BYTE_ELEMENTS:
3339 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3340 __ SmiUntag(ecx);
3341 __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
3342 break;
3343 case EXTERNAL_SHORT_ELEMENTS:
3344 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3345 __ mov_w(Operand(edi, ecx, times_1, 0), ebx);
3346 break;
3347 case EXTERNAL_INT_ELEMENTS:
3348 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3349 __ mov(Operand(edi, ecx, times_2, 0), ebx);
3350 break;
3351 case EXTERNAL_FLOAT_ELEMENTS:
3352 case EXTERNAL_DOUBLE_ELEMENTS:
3353 // Need to perform int-to-float conversion.
3354 __ push(ebx);
3355 __ fild_s(Operand(esp, 0));
3356 __ pop(ebx);
3357 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3358 __ fstp_s(Operand(edi, ecx, times_2, 0));
3359 } else { // elements_kind == EXTERNAL_DOUBLE_ELEMENTS.
3360 __ fstp_d(Operand(edi, ecx, times_4, 0));
3361 }
3362 break;
3363 default:
3364 UNREACHABLE();
3365 break;
3366 }
3367 __ ret(0); // Return the original value.
3368
3369 // TODO(danno): handle heap number -> pixel array conversion
3370 if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) {
3371 __ bind(&check_heap_number);
3372 // eax: value
3373 // edx: receiver
3374 // ecx: key
3375 // edi: elements array
3376 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3377 Immediate(masm->isolate()->factory()->heap_number_map()));
3378 __ j(not_equal, &slow);
3379
3380 // The WebGL specification leaves the behavior of storing NaN and
3381 // +/-Infinity into integer arrays basically undefined. For more
3382 // reproducible behavior, convert these to zero.
3383 __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
3384 // edi: base pointer of external storage
3385 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
3386 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3387 __ fstp_s(Operand(edi, ecx, times_2, 0));
3388 __ ret(0);
3389 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
3390 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3391 __ fstp_d(Operand(edi, ecx, times_4, 0));
3392 __ ret(0);
3393 } else {
3394 // Perform float-to-int conversion with truncation (round-to-zero)
3395 // behavior.
3396
3397 // For the moment we make the slow call to the runtime on
3398 // processors that don't support SSE2. The code in IntegerConvert
3399 // (code-stubs-ia32.cc) is roughly what is needed here though the
3400 // conversion failure case does not need to be handled.
3401 if (CpuFeatures::IsSupported(SSE2)) {
3402 if ((elements_kind == EXTERNAL_INT_ELEMENTS ||
3403 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) &&
3404 CpuFeatures::IsSupported(SSE3)) {
3405 CpuFeatureScope scope(masm, SSE3);
3406 // fisttp stores values as signed integers. To represent the
3407 // entire range of int and unsigned int arrays, store as a
3408 // 64-bit int and discard the high 32 bits.
3409 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3410 __ sub(esp, Immediate(2 * kPointerSize));
3411 __ fisttp_d(Operand(esp, 0));
3412
3413 // If conversion failed (NaN, infinity, or a number outside
3414 // signed int64 range), the result is 0x8000000000000000, and
3415 // we must handle this case in the runtime.
3416 Label ok;
3417 __ cmp(Operand(esp, kPointerSize), Immediate(0x80000000u));
3418 __ j(not_equal, &ok);
3419 __ cmp(Operand(esp, 0), Immediate(0));
3420 __ j(not_equal, &ok);
3421 __ add(esp, Immediate(2 * kPointerSize)); // Restore the stack.
3422 __ jmp(&slow);
3423
3424 __ bind(&ok);
3425 __ pop(ebx);
3426 __ add(esp, Immediate(kPointerSize));
3427 __ mov(Operand(edi, ecx, times_2, 0), ebx);
3428 } else {
3429 ASSERT(CpuFeatures::IsSupported(SSE2));
3430 CpuFeatureScope scope(masm, SSE2);
3431 __ cvttsd2si(ebx, FieldOperand(eax, HeapNumber::kValueOffset));
3432 __ cmp(ebx, 0x80000000u);
3433 __ j(equal, &slow);
3434 // ebx: untagged integer value
3435 switch (elements_kind) {
3436 case EXTERNAL_PIXEL_ELEMENTS:
3437 __ ClampUint8(ebx);
3438 // Fall through.
3439 case EXTERNAL_BYTE_ELEMENTS:
3440 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
3441 __ SmiUntag(ecx);
3442 __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
3443 break;
3444 case EXTERNAL_SHORT_ELEMENTS:
3445 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
3446 __ mov_w(Operand(edi, ecx, times_1, 0), ebx);
3447 break;
3448 case EXTERNAL_INT_ELEMENTS:
3449 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
3450 __ mov(Operand(edi, ecx, times_2, 0), ebx);
3451 break;
3452 default:
3453 UNREACHABLE();
3454 break;
3455 }
3456 }
3457 __ ret(0); // Return original value.
3458 }
3459 }
3460 }
3461
3462 // Slow case: call runtime.
3463 __ bind(&slow);
3464 Counters* counters = masm->isolate()->counters();
3465 __ IncrementCounter(counters->keyed_store_external_array_slow(), 1);
3466
3467 // ----------- S t a t e -------------
3468 // -- eax : value
3469 // -- ecx : key
3470 // -- edx : receiver
3471 // -- esp[0] : return address
3472 // -----------------------------------
3473 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3474
3475 // ----------- S t a t e -------------
3476 // -- eax : value
3477 // -- ecx : key
3478 // -- edx : receiver
3479 // -- esp[0] : return address
3480 // -----------------------------------
3481
3482 __ bind(&miss_force_generic);
3483 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3484 }
3485
3486
3487 void KeyedStoreStubCompiler::GenerateStoreFastElement(
3488 MacroAssembler* masm,
3489 bool is_js_array,
3490 ElementsKind elements_kind,
3491 KeyedAccessStoreMode store_mode) {
3492 // ----------- S t a t e -------------
3493 // -- eax : value
3494 // -- ecx : key
3495 // -- edx : receiver
3496 // -- esp[0] : return address
3497 // -----------------------------------
3498 Label miss_force_generic, grow, slow, transition_elements_kind;
3499 Label check_capacity, prepare_slow, finish_store, commit_backing_store;
3500
3501 // This stub is meant to be tail-jumped to, the receiver must already
3502 // have been verified by the caller to not be a smi.
3503
3504 // Check that the key is a smi or a heap number convertible to a smi.
3505 GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic);
3506
3507 if (IsFastSmiElementsKind(elements_kind)) {
3508 __ JumpIfNotSmi(eax, &transition_elements_kind);
3509 }
3510
3511 // Get the elements array and make sure it is a fast element array, not 'cow'.
3512 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3513 if (is_js_array) {
3514 // Check that the key is within bounds.
3515 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis.
3516 if (IsGrowStoreMode(store_mode)) {
3517 __ j(above_equal, &grow);
3518 } else {
3519 __ j(above_equal, &miss_force_generic);
3520 }
3521 } else {
3522 // Check that the key is within bounds.
3523 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis.
3524 __ j(above_equal, &miss_force_generic);
3525 }
3526
3527 __ cmp(FieldOperand(edi, HeapObject::kMapOffset),
3528 Immediate(masm->isolate()->factory()->fixed_array_map()));
3529 __ j(not_equal, &miss_force_generic);
3530
3531 __ bind(&finish_store);
3532 if (IsFastSmiElementsKind(elements_kind)) {
3533 // ecx is a smi, use times_half_pointer_size instead of
3534 // times_pointer_size
3535 __ mov(FieldOperand(edi,
3536 ecx,
3537 times_half_pointer_size,
3538 FixedArray::kHeaderSize), eax);
3539 } else {
3540 ASSERT(IsFastObjectElementsKind(elements_kind));
3541 // Do the store and update the write barrier.
3542 // ecx is a smi, use times_half_pointer_size instead of
3543 // times_pointer_size
3544 __ lea(ecx, FieldOperand(edi,
3545 ecx,
3546 times_half_pointer_size,
3547 FixedArray::kHeaderSize));
3548 __ mov(Operand(ecx, 0), eax);
3549 // Make sure to preserve the value in register eax.
3550 __ mov(ebx, eax);
3551 __ RecordWrite(edi, ecx, ebx, kDontSaveFPRegs);
3552 }
3553
3554 // Done.
3555 __ ret(0);
3556
3557 // Handle store cache miss, replacing the ic with the generic stub.
3558 __ bind(&miss_force_generic);
3559 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3560
3561 // Handle transition to other elements kinds without using the generic stub.
3562 __ bind(&transition_elements_kind);
3563 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
3564
3565 if (is_js_array && IsGrowStoreMode(store_mode)) {
3566 // Handle transition requiring the array to grow.
3567 __ bind(&grow);
3568
3569 // Make sure the array is only growing by a single element, anything else
3570 // must be handled by the runtime. Flags are already set by previous
3571 // compare.
3572 __ j(not_equal, &miss_force_generic);
3573
3574 // Check for the empty array, and preallocate a small backing store if
3575 // possible.
3576 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3577 __ cmp(edi, Immediate(masm->isolate()->factory()->empty_fixed_array()));
3578 __ j(not_equal, &check_capacity);
3579
3580 int size = FixedArray::SizeFor(JSArray::kPreallocatedArrayElements);
3581 __ Allocate(size, edi, ebx, ecx, &prepare_slow, TAG_OBJECT);
3582 // Restore the key, which is known to be the array length.
3583
3584 // eax: value
3585 // ecx: key
3586 // edx: receiver
3587 // edi: elements
3588 // Make sure that the backing store can hold additional elements.
3589 __ mov(FieldOperand(edi, JSObject::kMapOffset),
3590 Immediate(masm->isolate()->factory()->fixed_array_map()));
3591 __ mov(FieldOperand(edi, FixedArray::kLengthOffset),
3592 Immediate(Smi::FromInt(JSArray::kPreallocatedArrayElements)));
3593 __ mov(ebx, Immediate(masm->isolate()->factory()->the_hole_value()));
3594 for (int i = 1; i < JSArray::kPreallocatedArrayElements; ++i) {
3595 __ mov(FieldOperand(edi, FixedArray::SizeFor(i)), ebx);
3596 }
3597
3598 // Store the element at index zero.
3599 __ mov(FieldOperand(edi, FixedArray::SizeFor(0)), eax);
3600
3601 // Install the new backing store in the JSArray.
3602 __ mov(FieldOperand(edx, JSObject::kElementsOffset), edi);
3603 __ RecordWriteField(edx, JSObject::kElementsOffset, edi, ebx,
3604 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
3605
3606 // Increment the length of the array.
3607 __ mov(FieldOperand(edx, JSArray::kLengthOffset),
3608 Immediate(Smi::FromInt(1)));
3609 __ ret(0);
3610
3611 __ bind(&check_capacity);
3612 __ cmp(FieldOperand(edi, HeapObject::kMapOffset),
3613 Immediate(masm->isolate()->factory()->fixed_cow_array_map()));
3614 __ j(equal, &miss_force_generic);
3615
3616 // eax: value
3617 // ecx: key
3618 // edx: receiver
3619 // edi: elements
3620 // Make sure that the backing store can hold additional elements.
3621 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset));
3622 __ j(above_equal, &slow);
3623
3624 // Grow the array and finish the store.
3625 __ add(FieldOperand(edx, JSArray::kLengthOffset),
3626 Immediate(Smi::FromInt(1)));
3627 __ jmp(&finish_store);
3628
3629 __ bind(&prepare_slow);
3630 // Restore the key, which is known to be the array length.
3631 __ mov(ecx, Immediate(0));
3632
3633 __ bind(&slow);
3634 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3635 }
3636 }
3637
3638
3639 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
3640 MacroAssembler* masm,
3641 bool is_js_array,
3642 KeyedAccessStoreMode store_mode) {
3643 // ----------- S t a t e -------------
3644 // -- eax : value
3645 // -- ecx : key
3646 // -- edx : receiver
3647 // -- esp[0] : return address
3648 // -----------------------------------
3649 Label miss_force_generic, transition_elements_kind, grow, slow;
3650 Label check_capacity, prepare_slow, finish_store, commit_backing_store;
3651
3652 // This stub is meant to be tail-jumped to, the receiver must already
3653 // have been verified by the caller to not be a smi.
3654
3655 // Check that the key is a smi or a heap number convertible to a smi.
3656 GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic);
3657
3658 // Get the elements array.
3659 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3660 __ AssertFastElements(edi);
3661
3662 if (is_js_array) {
3663 // Check that the key is within bounds.
3664 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis.
3665 if (IsGrowStoreMode(store_mode)) {
3666 __ j(above_equal, &grow);
3667 } else {
3668 __ j(above_equal, &miss_force_generic);
3669 }
3670 } else {
3671 // Check that the key is within bounds.
3672 __ cmp(ecx, FieldOperand(edi, FixedArray::kLengthOffset)); // smis.
3673 __ j(above_equal, &miss_force_generic);
3674 }
3675
3676 __ bind(&finish_store);
3677 __ StoreNumberToDoubleElements(eax, edi, ecx, edx, xmm0,
3678 &transition_elements_kind, true);
3679 __ ret(0);
3680
3681 // Handle store cache miss, replacing the ic with the generic stub.
3682 __ bind(&miss_force_generic);
3683 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3684
3685 // Handle transition to other elements kinds without using the generic stub.
3686 __ bind(&transition_elements_kind);
3687 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
3688
3689 if (is_js_array && IsGrowStoreMode(store_mode)) {
3690 // Handle transition requiring the array to grow.
3691 __ bind(&grow);
3692
3693 // Make sure the array is only growing by a single element, anything else
3694 // must be handled by the runtime. Flags are already set by previous
3695 // compare.
3696 __ j(not_equal, &miss_force_generic);
3697
3698 // Transition on values that can't be stored in a FixedDoubleArray.
3699 Label value_is_smi;
3700 __ JumpIfSmi(eax, &value_is_smi);
3701 __ cmp(FieldOperand(eax, HeapObject::kMapOffset),
3702 Immediate(Handle<Map>(masm->isolate()->heap()->heap_number_map())));
3703 __ j(not_equal, &transition_elements_kind);
3704 __ bind(&value_is_smi);
3705
3706 // Check for the empty array, and preallocate a small backing store if
3707 // possible.
3708 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3709 __ cmp(edi, Immediate(masm->isolate()->factory()->empty_fixed_array()));
3710 __ j(not_equal, &check_capacity);
3711
3712 int size = FixedDoubleArray::SizeFor(JSArray::kPreallocatedArrayElements);
3713 __ Allocate(size, edi, ebx, ecx, &prepare_slow, TAG_OBJECT);
3714
3715 // Restore the key, which is known to be the array length.
3716 __ mov(ecx, Immediate(0));
3717
3718 // eax: value
3719 // ecx: key
3720 // edx: receiver
3721 // edi: elements
3722 // Initialize the new FixedDoubleArray.
3723 __ mov(FieldOperand(edi, JSObject::kMapOffset),
3724 Immediate(masm->isolate()->factory()->fixed_double_array_map()));
3725 __ mov(FieldOperand(edi, FixedDoubleArray::kLengthOffset),
3726 Immediate(Smi::FromInt(JSArray::kPreallocatedArrayElements)));
3727
3728 __ StoreNumberToDoubleElements(eax, edi, ecx, ebx, xmm0,
3729 &transition_elements_kind, true);
3730
3731 for (int i = 1; i < JSArray::kPreallocatedArrayElements; i++) {
3732 int offset = FixedDoubleArray::OffsetOfElementAt(i);
3733 __ mov(FieldOperand(edi, offset), Immediate(kHoleNanLower32));
3734 __ mov(FieldOperand(edi, offset + kPointerSize),
3735 Immediate(kHoleNanUpper32));
3736 }
3737
3738 // Install the new backing store in the JSArray.
3739 __ mov(FieldOperand(edx, JSObject::kElementsOffset), edi);
3740 __ RecordWriteField(edx, JSObject::kElementsOffset, edi, ebx,
3741 kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
3742
3743 // Increment the length of the array.
3744 __ add(FieldOperand(edx, JSArray::kLengthOffset),
3745 Immediate(Smi::FromInt(1)));
3746 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3747 __ ret(0);
3748
3749 __ bind(&check_capacity);
3750 // eax: value
3751 // ecx: key
3752 // edx: receiver
3753 // edi: elements
3754 // Make sure that the backing store can hold additional elements.
3755 __ cmp(ecx, FieldOperand(edi, FixedDoubleArray::kLengthOffset));
3756 __ j(above_equal, &slow);
3757
3758 // Grow the array and finish the store.
3759 __ add(FieldOperand(edx, JSArray::kLengthOffset),
3760 Immediate(Smi::FromInt(1)));
3761 __ jmp(&finish_store);
3762
3763 __ bind(&prepare_slow);
3764 // Restore the key, which is known to be the array length.
3765 __ mov(ecx, Immediate(0));
3766
3767 __ bind(&slow);
3768 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3769 }
3770 }
3771
3772
3773 #undef __ 3259 #undef __
3774 3260
3775 } } // namespace v8::internal 3261 } } // namespace v8::internal
3776 3262
3777 #endif // V8_TARGET_ARCH_IA32 3263 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698