OLD | NEW |
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 3094 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3105 // ----------- S t a t e ------------- | 3105 // ----------- S t a t e ------------- |
3106 // -- rax : key | 3106 // -- rax : key |
3107 // -- rdx : receiver | 3107 // -- rdx : receiver |
3108 // -- rsp[0] : return address | 3108 // -- rsp[0] : return address |
3109 // ----------------------------------- | 3109 // ----------------------------------- |
3110 Handle<Code> miss_ic = | 3110 Handle<Code> miss_ic = |
3111 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); | 3111 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); |
3112 __ jmp(miss_ic, RelocInfo::CODE_TARGET); | 3112 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
3113 } | 3113 } |
3114 | 3114 |
| 3115 |
| 3116 static void GenerateSmiKeyCheck(MacroAssembler* masm, |
| 3117 Register key, |
| 3118 Register scratch, |
| 3119 XMMRegister xmm_scratch0, |
| 3120 XMMRegister xmm_scratch1, |
| 3121 Label* fail) { |
| 3122 // Check that key is a smi or a heap number containing a smi and branch |
| 3123 // if the check fails. |
| 3124 Label key_ok; |
| 3125 __ JumpIfSmi(key, &key_ok); |
| 3126 __ CheckMap(key, |
| 3127 masm->isolate()->factory()->heap_number_map(), |
| 3128 fail, |
| 3129 DONT_DO_SMI_CHECK); |
| 3130 __ movsd(xmm_scratch0, FieldOperand(key, HeapNumber::kValueOffset)); |
| 3131 __ cvttsd2si(scratch, xmm_scratch0); |
| 3132 __ cvtlsi2sd(xmm_scratch1, scratch); |
| 3133 __ ucomisd(xmm_scratch1, xmm_scratch0); |
| 3134 __ j(not_equal, fail); |
| 3135 __ j(parity_even, fail); // NaN. |
| 3136 __ Integer32ToSmi(key, scratch); |
| 3137 __ bind(&key_ok); |
| 3138 } |
| 3139 |
| 3140 |
3115 void KeyedLoadStubCompiler::GenerateLoadExternalArray( | 3141 void KeyedLoadStubCompiler::GenerateLoadExternalArray( |
3116 MacroAssembler* masm, | 3142 MacroAssembler* masm, |
3117 ElementsKind elements_kind) { | 3143 ElementsKind elements_kind) { |
3118 // ----------- S t a t e ------------- | 3144 // ----------- S t a t e ------------- |
3119 // -- rax : key | 3145 // -- rax : key |
3120 // -- rdx : receiver | 3146 // -- rdx : receiver |
3121 // -- rsp[0] : return address | 3147 // -- rsp[0] : return address |
3122 // ----------------------------------- | 3148 // ----------------------------------- |
3123 Label slow, miss_force_generic; | 3149 Label slow, miss_force_generic; |
3124 | 3150 |
3125 // This stub is meant to be tail-jumped to, the receiver must already | 3151 // This stub is meant to be tail-jumped to, the receiver must already |
3126 // have been verified by the caller to not be a smi. | 3152 // have been verified by the caller to not be a smi. |
3127 | 3153 |
3128 // Check that the key is a smi. | 3154 // Check that the key is a smi or a heap number convertible to a smi. |
3129 __ JumpIfNotSmi(rax, &miss_force_generic); | 3155 GenerateSmiKeyCheck(masm, rax, rcx, xmm0, xmm1, &miss_force_generic); |
3130 | 3156 |
3131 // Check that the index is in range. | 3157 // Check that the index is in range. |
3132 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); | 3158 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); |
3133 __ SmiToInteger32(rcx, rax); | 3159 __ SmiToInteger32(rcx, rax); |
3134 __ cmpq(rax, FieldOperand(rbx, ExternalArray::kLengthOffset)); | 3160 __ cmpq(rax, FieldOperand(rbx, ExternalArray::kLengthOffset)); |
3135 // Unsigned comparison catches both negative and too-large values. | 3161 // Unsigned comparison catches both negative and too-large values. |
3136 __ j(above_equal, &miss_force_generic); | 3162 __ j(above_equal, &miss_force_generic); |
3137 | 3163 |
3138 // rax: index (as a smi) | 3164 // rax: index (as a smi) |
3139 // rdx: receiver (JSObject) | 3165 // rdx: receiver (JSObject) |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3253 // -- rax : value | 3279 // -- rax : value |
3254 // -- rcx : key | 3280 // -- rcx : key |
3255 // -- rdx : receiver | 3281 // -- rdx : receiver |
3256 // -- rsp[0] : return address | 3282 // -- rsp[0] : return address |
3257 // ----------------------------------- | 3283 // ----------------------------------- |
3258 Label slow, miss_force_generic; | 3284 Label slow, miss_force_generic; |
3259 | 3285 |
3260 // This stub is meant to be tail-jumped to, the receiver must already | 3286 // This stub is meant to be tail-jumped to, the receiver must already |
3261 // have been verified by the caller to not be a smi. | 3287 // have been verified by the caller to not be a smi. |
3262 | 3288 |
3263 // Check that the key is a smi. | 3289 // Check that the key is a smi or a heap number convertible to a smi. |
3264 __ JumpIfNotSmi(rcx, &miss_force_generic); | 3290 GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic); |
3265 | 3291 |
3266 // Check that the index is in range. | 3292 // Check that the index is in range. |
3267 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); | 3293 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); |
3268 __ SmiToInteger32(rdi, rcx); // Untag the index. | 3294 __ SmiToInteger32(rdi, rcx); // Untag the index. |
3269 __ cmpq(rcx, FieldOperand(rbx, ExternalArray::kLengthOffset)); | 3295 __ cmpq(rcx, FieldOperand(rbx, ExternalArray::kLengthOffset)); |
3270 // Unsigned comparison catches both negative and too-large values. | 3296 // Unsigned comparison catches both negative and too-large values. |
3271 __ j(above_equal, &miss_force_generic); | 3297 __ j(above_equal, &miss_force_generic); |
3272 | 3298 |
3273 // Handle both smis and HeapNumbers in the fast path. Go to the | 3299 // Handle both smis and HeapNumbers in the fast path. Go to the |
3274 // runtime for all other kinds of values. | 3300 // runtime for all other kinds of values. |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3435 // ----------- S t a t e ------------- | 3461 // ----------- S t a t e ------------- |
3436 // -- rax : key | 3462 // -- rax : key |
3437 // -- rdx : receiver | 3463 // -- rdx : receiver |
3438 // -- rsp[0] : return address | 3464 // -- rsp[0] : return address |
3439 // ----------------------------------- | 3465 // ----------------------------------- |
3440 Label miss_force_generic; | 3466 Label miss_force_generic; |
3441 | 3467 |
3442 // This stub is meant to be tail-jumped to, the receiver must already | 3468 // This stub is meant to be tail-jumped to, the receiver must already |
3443 // have been verified by the caller to not be a smi. | 3469 // have been verified by the caller to not be a smi. |
3444 | 3470 |
3445 // Check that the key is a smi. | 3471 // Check that the key is a smi or a heap number convertible to a smi. |
3446 __ JumpIfNotSmi(rax, &miss_force_generic); | 3472 GenerateSmiKeyCheck(masm, rax, rcx, xmm0, xmm1, &miss_force_generic); |
3447 | 3473 |
3448 // Get the elements array. | 3474 // Get the elements array. |
3449 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); | 3475 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); |
3450 __ AssertFastElements(rcx); | 3476 __ AssertFastElements(rcx); |
3451 | 3477 |
3452 // Check that the key is within bounds. | 3478 // Check that the key is within bounds. |
3453 __ SmiCompare(rax, FieldOperand(rcx, FixedArray::kLengthOffset)); | 3479 __ SmiCompare(rax, FieldOperand(rcx, FixedArray::kLengthOffset)); |
3454 __ j(above_equal, &miss_force_generic); | 3480 __ j(above_equal, &miss_force_generic); |
3455 | 3481 |
3456 // Load the result and make sure it's not the hole. | 3482 // Load the result and make sure it's not the hole. |
(...skipping 20 matching lines...) Expand all Loading... |
3477 // ----------- S t a t e ------------- | 3503 // ----------- S t a t e ------------- |
3478 // -- rax : key | 3504 // -- rax : key |
3479 // -- rdx : receiver | 3505 // -- rdx : receiver |
3480 // -- rsp[0] : return address | 3506 // -- rsp[0] : return address |
3481 // ----------------------------------- | 3507 // ----------------------------------- |
3482 Label miss_force_generic, slow_allocate_heapnumber; | 3508 Label miss_force_generic, slow_allocate_heapnumber; |
3483 | 3509 |
3484 // This stub is meant to be tail-jumped to, the receiver must already | 3510 // This stub is meant to be tail-jumped to, the receiver must already |
3485 // have been verified by the caller to not be a smi. | 3511 // have been verified by the caller to not be a smi. |
3486 | 3512 |
3487 // Check that the key is a smi. | 3513 // Check that the key is a smi or a heap number convertible to a smi. |
3488 __ JumpIfNotSmi(rax, &miss_force_generic); | 3514 GenerateSmiKeyCheck(masm, rax, rcx, xmm0, xmm1, &miss_force_generic); |
3489 | 3515 |
3490 // Get the elements array. | 3516 // Get the elements array. |
3491 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); | 3517 __ movq(rcx, FieldOperand(rdx, JSObject::kElementsOffset)); |
3492 __ AssertFastElements(rcx); | 3518 __ AssertFastElements(rcx); |
3493 | 3519 |
3494 // Check that the key is within bounds. | 3520 // Check that the key is within bounds. |
3495 __ SmiCompare(rax, FieldOperand(rcx, FixedArray::kLengthOffset)); | 3521 __ SmiCompare(rax, FieldOperand(rcx, FixedArray::kLengthOffset)); |
3496 __ j(above_equal, &miss_force_generic); | 3522 __ j(above_equal, &miss_force_generic); |
3497 | 3523 |
3498 // Check for the hole | 3524 // Check for the hole |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3533 // -- rcx : key | 3559 // -- rcx : key |
3534 // -- rdx : receiver | 3560 // -- rdx : receiver |
3535 // -- rsp[0] : return address | 3561 // -- rsp[0] : return address |
3536 // ----------------------------------- | 3562 // ----------------------------------- |
3537 Label miss_force_generic, transition_elements_kind, finish_store, grow; | 3563 Label miss_force_generic, transition_elements_kind, finish_store, grow; |
3538 Label check_capacity, slow; | 3564 Label check_capacity, slow; |
3539 | 3565 |
3540 // This stub is meant to be tail-jumped to, the receiver must already | 3566 // This stub is meant to be tail-jumped to, the receiver must already |
3541 // have been verified by the caller to not be a smi. | 3567 // have been verified by the caller to not be a smi. |
3542 | 3568 |
3543 // Check that the key is a smi. | 3569 // Check that the key is a smi or a heap number convertible to a smi. |
3544 __ JumpIfNotSmi(rcx, &miss_force_generic); | 3570 GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic); |
3545 | 3571 |
3546 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { | 3572 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
3547 __ JumpIfNotSmi(rax, &transition_elements_kind); | 3573 __ JumpIfNotSmi(rax, &transition_elements_kind); |
3548 } | 3574 } |
3549 | 3575 |
3550 // Get the elements array and make sure it is a fast element array, not 'cow'. | 3576 // Get the elements array and make sure it is a fast element array, not 'cow'. |
3551 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); | 3577 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); |
3552 // Check that the key is within bounds. | 3578 // Check that the key is within bounds. |
3553 if (is_js_array) { | 3579 if (is_js_array) { |
3554 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); | 3580 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3675 // -- rcx : key | 3701 // -- rcx : key |
3676 // -- rdx : receiver | 3702 // -- rdx : receiver |
3677 // -- rsp[0] : return address | 3703 // -- rsp[0] : return address |
3678 // ----------------------------------- | 3704 // ----------------------------------- |
3679 Label miss_force_generic, transition_elements_kind, finish_store; | 3705 Label miss_force_generic, transition_elements_kind, finish_store; |
3680 Label grow, slow, check_capacity; | 3706 Label grow, slow, check_capacity; |
3681 | 3707 |
3682 // This stub is meant to be tail-jumped to, the receiver must already | 3708 // This stub is meant to be tail-jumped to, the receiver must already |
3683 // have been verified by the caller to not be a smi. | 3709 // have been verified by the caller to not be a smi. |
3684 | 3710 |
3685 // Check that the key is a smi. | 3711 // Check that the key is a smi or a heap number convertible to a smi. |
3686 __ JumpIfNotSmi(rcx, &miss_force_generic); | 3712 GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic); |
3687 | 3713 |
3688 // Get the elements array. | 3714 // Get the elements array. |
3689 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); | 3715 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); |
3690 __ AssertFastElements(rdi); | 3716 __ AssertFastElements(rdi); |
3691 | 3717 |
3692 // Check that the key is within bounds. | 3718 // Check that the key is within bounds. |
3693 if (is_js_array) { | 3719 if (is_js_array) { |
3694 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); | 3720 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); |
3695 if (grow_mode == ALLOW_JSARRAY_GROWTH) { | 3721 if (grow_mode == ALLOW_JSARRAY_GROWTH) { |
3696 __ j(above_equal, &grow); | 3722 __ j(above_equal, &grow); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3786 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | 3812 __ jmp(ic_slow, RelocInfo::CODE_TARGET); |
3787 } | 3813 } |
3788 } | 3814 } |
3789 | 3815 |
3790 | 3816 |
3791 #undef __ | 3817 #undef __ |
3792 | 3818 |
3793 } } // namespace v8::internal | 3819 } } // namespace v8::internal |
3794 | 3820 |
3795 #endif // V8_TARGET_ARCH_X64 | 3821 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |