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

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

Issue 9837109: Improve performance of keyed loads/stores which have a HeapNumber index. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 8 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/arm/stub-cache-arm.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 3283 matching lines...) Expand 10 before | Expand all | Expand 10 after
3294 // -- edx : receiver 3294 // -- edx : receiver
3295 // -- esp[0] : return address 3295 // -- esp[0] : return address
3296 // ----------------------------------- 3296 // -----------------------------------
3297 3297
3298 Handle<Code> miss_force_generic_ic = 3298 Handle<Code> miss_force_generic_ic =
3299 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); 3299 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
3300 __ jmp(miss_force_generic_ic, RelocInfo::CODE_TARGET); 3300 __ jmp(miss_force_generic_ic, RelocInfo::CODE_TARGET);
3301 } 3301 }
3302 3302
3303 3303
3304 static void GenerateSmiKeyCheck(MacroAssembler* masm,
3305 Register key,
3306 Register scratch,
3307 XMMRegister xmm_scratch0,
3308 XMMRegister xmm_scratch1,
3309 Label* fail) {
3310 // Check that key is a smi and if SSE2 is available a heap number
3311 // containing a smi and branch if the check fails.
3312 if (CpuFeatures::IsSupported(SSE2)) {
3313 CpuFeatures::Scope use_sse2(SSE2);
3314 Label key_ok;
3315 __ JumpIfSmi(key, &key_ok);
3316 __ cmp(FieldOperand(key, HeapObject::kMapOffset),
3317 Immediate(Handle<Map>(masm->isolate()->heap()->heap_number_map())));
3318 __ j(not_equal, fail);
3319 __ movdbl(xmm_scratch0, FieldOperand(key, HeapNumber::kValueOffset));
3320 __ cvttsd2si(scratch, Operand(xmm_scratch0));
3321 __ cvtsi2sd(xmm_scratch1, scratch);
3322 __ ucomisd(xmm_scratch1, xmm_scratch0);
3323 __ j(not_equal, fail);
3324 __ j(parity_even, fail); // NaN.
3325 // Check if the key fits in the smi range.
3326 __ cmp(scratch, 0xc0000000);
3327 __ j(sign, fail);
3328 __ SmiTag(scratch);
3329 __ mov(key, scratch);
3330 __ bind(&key_ok);
3331 } else {
3332 __ JumpIfNotSmi(key, fail);
3333 }
3334 }
3335
3336
3304 void KeyedLoadStubCompiler::GenerateLoadExternalArray( 3337 void KeyedLoadStubCompiler::GenerateLoadExternalArray(
3305 MacroAssembler* masm, 3338 MacroAssembler* masm,
3306 ElementsKind elements_kind) { 3339 ElementsKind elements_kind) {
3307 // ----------- S t a t e ------------- 3340 // ----------- S t a t e -------------
3308 // -- eax : key 3341 // -- eax : key
3309 // -- edx : receiver 3342 // -- edx : receiver
3310 // -- esp[0] : return address 3343 // -- esp[0] : return address
3311 // ----------------------------------- 3344 // -----------------------------------
3312 Label miss_force_generic, failed_allocation, slow; 3345 Label miss_force_generic, failed_allocation, slow;
3313 3346
3314 // This stub is meant to be tail-jumped to, the receiver must already 3347 // This stub is meant to be tail-jumped to, the receiver must already
3315 // have been verified by the caller to not be a smi. 3348 // have been verified by the caller to not be a smi.
3316 3349
3317 // Check that the key is a smi. 3350 // Check that the key is a smi or a heap number convertible to a smi.
3318 __ JumpIfNotSmi(eax, &miss_force_generic); 3351 GenerateSmiKeyCheck(masm, eax, ecx, xmm0, xmm1, &miss_force_generic);
3319 3352
3320 // Check that the index is in range. 3353 // Check that the index is in range.
3321 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); 3354 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset));
3322 __ cmp(eax, FieldOperand(ebx, ExternalArray::kLengthOffset)); 3355 __ cmp(eax, FieldOperand(ebx, ExternalArray::kLengthOffset));
3323 // Unsigned comparison catches both negative and too-large values. 3356 // Unsigned comparison catches both negative and too-large values.
3324 __ j(above_equal, &miss_force_generic); 3357 __ j(above_equal, &miss_force_generic);
3325 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); 3358 __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
3326 // ebx: base pointer of external storage 3359 // ebx: base pointer of external storage
3327 switch (elements_kind) { 3360 switch (elements_kind) {
3328 case EXTERNAL_BYTE_ELEMENTS: 3361 case EXTERNAL_BYTE_ELEMENTS:
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3360 // For floating-point array type: 3393 // For floating-point array type:
3361 // FP(0): value 3394 // FP(0): value
3362 3395
3363 if (elements_kind == EXTERNAL_INT_ELEMENTS || 3396 if (elements_kind == EXTERNAL_INT_ELEMENTS ||
3364 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { 3397 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
3365 // For the Int and UnsignedInt array types, we need to see whether 3398 // For the Int and UnsignedInt array types, we need to see whether
3366 // the value can be represented in a Smi. If not, we need to convert 3399 // the value can be represented in a Smi. If not, we need to convert
3367 // it to a HeapNumber. 3400 // it to a HeapNumber.
3368 Label box_int; 3401 Label box_int;
3369 if (elements_kind == EXTERNAL_INT_ELEMENTS) { 3402 if (elements_kind == EXTERNAL_INT_ELEMENTS) {
3370 __ cmp(ecx, 0xC0000000); 3403 __ cmp(ecx, 0xc0000000);
3371 __ j(sign, &box_int); 3404 __ j(sign, &box_int);
3372 } else { 3405 } else {
3373 ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); 3406 ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind);
3374 // The test is different for unsigned int values. Since we need 3407 // The test is different for unsigned int values. Since we need
3375 // the value to be in the range of a positive smi, we can't 3408 // the value to be in the range of a positive smi, we can't
3376 // handle either of the top two bits being set in the value. 3409 // handle either of the top two bits being set in the value.
3377 __ test(ecx, Immediate(0xC0000000)); 3410 __ test(ecx, Immediate(0xc0000000));
3378 __ j(not_zero, &box_int); 3411 __ j(not_zero, &box_int);
3379 } 3412 }
3380 3413
3381 __ mov(eax, ecx); 3414 __ mov(eax, ecx);
3382 __ SmiTag(eax); 3415 __ SmiTag(eax);
3383 __ ret(0); 3416 __ ret(0);
3384 3417
3385 __ bind(&box_int); 3418 __ bind(&box_int);
3386 3419
3387 // Allocate a HeapNumber for the int and perform int-to-double 3420 // Allocate a HeapNumber for the int and perform int-to-double
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
3452 Handle<Code> miss_ic = 3485 Handle<Code> miss_ic =
3453 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric(); 3486 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
3454 __ jmp(miss_ic, RelocInfo::CODE_TARGET); 3487 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
3455 } 3488 }
3456 3489
3457 3490
3458 void KeyedStoreStubCompiler::GenerateStoreExternalArray( 3491 void KeyedStoreStubCompiler::GenerateStoreExternalArray(
3459 MacroAssembler* masm, 3492 MacroAssembler* masm,
3460 ElementsKind elements_kind) { 3493 ElementsKind elements_kind) {
3461 // ----------- S t a t e ------------- 3494 // ----------- S t a t e -------------
3462 // -- eax : key 3495 // -- eax : value
3496 // -- ecx : key
3463 // -- edx : receiver 3497 // -- edx : receiver
3464 // -- esp[0] : return address 3498 // -- esp[0] : return address
3465 // ----------------------------------- 3499 // -----------------------------------
3466 Label miss_force_generic, slow, check_heap_number; 3500 Label miss_force_generic, slow, check_heap_number;
3467 3501
3468 // This stub is meant to be tail-jumped to, the receiver must already 3502 // This stub is meant to be tail-jumped to, the receiver must already
3469 // have been verified by the caller to not be a smi. 3503 // have been verified by the caller to not be a smi.
3470 3504
3471 // Check that the key is a smi. 3505 // Check that the key is a smi or a heap number convertible to a smi.
3472 __ JumpIfNotSmi(ecx, &miss_force_generic); 3506 GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic);
3473 3507
3474 // Check that the index is in range. 3508 // Check that the index is in range.
3475 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 3509 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3476 __ cmp(ecx, FieldOperand(edi, ExternalArray::kLengthOffset)); 3510 __ cmp(ecx, FieldOperand(edi, ExternalArray::kLengthOffset));
3477 // Unsigned comparison catches both negative and too-large values. 3511 // Unsigned comparison catches both negative and too-large values.
3478 __ j(above_equal, &slow); 3512 __ j(above_equal, &slow);
3479 3513
3480 // Handle both smis and HeapNumbers in the fast path. Go to the 3514 // Handle both smis and HeapNumbers in the fast path. Go to the
3481 // runtime for all other kinds of values. 3515 // runtime for all other kinds of values.
3482 // eax: value 3516 // eax: value
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
3657 // ----------- S t a t e ------------- 3691 // ----------- S t a t e -------------
3658 // -- eax : key 3692 // -- eax : key
3659 // -- edx : receiver 3693 // -- edx : receiver
3660 // -- esp[0] : return address 3694 // -- esp[0] : return address
3661 // ----------------------------------- 3695 // -----------------------------------
3662 Label miss_force_generic; 3696 Label miss_force_generic;
3663 3697
3664 // This stub is meant to be tail-jumped to, the receiver must already 3698 // This stub is meant to be tail-jumped to, the receiver must already
3665 // have been verified by the caller to not be a smi. 3699 // have been verified by the caller to not be a smi.
3666 3700
3667 // Check that the key is a smi. 3701 // Check that the key is a smi or a heap number convertible to a smi.
3668 __ JumpIfNotSmi(eax, &miss_force_generic); 3702 GenerateSmiKeyCheck(masm, eax, ecx, xmm0, xmm1, &miss_force_generic);
3669 3703
3670 // Get the elements array. 3704 // Get the elements array.
3671 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 3705 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
3672 __ AssertFastElements(ecx); 3706 __ AssertFastElements(ecx);
3673 3707
3674 // Check that the key is within bounds. 3708 // Check that the key is within bounds.
3675 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset)); 3709 __ cmp(eax, FieldOperand(ecx, FixedArray::kLengthOffset));
3676 __ j(above_equal, &miss_force_generic); 3710 __ j(above_equal, &miss_force_generic);
3677 3711
3678 // Load the result and make sure it's not the hole. 3712 // Load the result and make sure it's not the hole.
(...skipping 16 matching lines...) Expand all
3695 // ----------- S t a t e ------------- 3729 // ----------- S t a t e -------------
3696 // -- eax : key 3730 // -- eax : key
3697 // -- edx : receiver 3731 // -- edx : receiver
3698 // -- esp[0] : return address 3732 // -- esp[0] : return address
3699 // ----------------------------------- 3733 // -----------------------------------
3700 Label miss_force_generic, slow_allocate_heapnumber; 3734 Label miss_force_generic, slow_allocate_heapnumber;
3701 3735
3702 // This stub is meant to be tail-jumped to, the receiver must already 3736 // This stub is meant to be tail-jumped to, the receiver must already
3703 // have been verified by the caller to not be a smi. 3737 // have been verified by the caller to not be a smi.
3704 3738
3705 // Check that the key is a smi. 3739 // Check that the key is a smi or a heap number convertible to a smi.
3706 __ JumpIfNotSmi(eax, &miss_force_generic); 3740 GenerateSmiKeyCheck(masm, eax, ecx, xmm0, xmm1, &miss_force_generic);
3707 3741
3708 // Get the elements array. 3742 // Get the elements array.
3709 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset)); 3743 __ mov(ecx, FieldOperand(edx, JSObject::kElementsOffset));
3710 __ AssertFastElements(ecx); 3744 __ AssertFastElements(ecx);
3711 3745
3712 // Check that the key is within bounds. 3746 // Check that the key is within bounds.
3713 __ cmp(eax, FieldOperand(ecx, FixedDoubleArray::kLengthOffset)); 3747 __ cmp(eax, FieldOperand(ecx, FixedDoubleArray::kLengthOffset));
3714 __ j(above_equal, &miss_force_generic); 3748 __ j(above_equal, &miss_force_generic);
3715 3749
3716 // Check for the hole 3750 // Check for the hole
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
3764 // -- ecx : key 3798 // -- ecx : key
3765 // -- edx : receiver 3799 // -- edx : receiver
3766 // -- esp[0] : return address 3800 // -- esp[0] : return address
3767 // ----------------------------------- 3801 // -----------------------------------
3768 Label miss_force_generic, grow, slow, transition_elements_kind; 3802 Label miss_force_generic, grow, slow, transition_elements_kind;
3769 Label check_capacity, prepare_slow, finish_store, commit_backing_store; 3803 Label check_capacity, prepare_slow, finish_store, commit_backing_store;
3770 3804
3771 // This stub is meant to be tail-jumped to, the receiver must already 3805 // This stub is meant to be tail-jumped to, the receiver must already
3772 // have been verified by the caller to not be a smi. 3806 // have been verified by the caller to not be a smi.
3773 3807
3774 // Check that the key is a smi. 3808 // Check that the key is a smi or a heap number convertible to a smi.
3775 __ JumpIfNotSmi(ecx, &miss_force_generic); 3809 GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic);
3776 3810
3777 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { 3811 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
3778 __ JumpIfNotSmi(eax, &transition_elements_kind); 3812 __ JumpIfNotSmi(eax, &transition_elements_kind);
3779 } 3813 }
3780 3814
3781 // Get the elements array and make sure it is a fast element array, not 'cow'. 3815 // Get the elements array and make sure it is a fast element array, not 'cow'.
3782 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 3816 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3783 if (is_js_array) { 3817 if (is_js_array) {
3784 // Check that the key is within bounds. 3818 // Check that the key is within bounds.
3785 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. 3819 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis.
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
3919 // -- ecx : key 3953 // -- ecx : key
3920 // -- edx : receiver 3954 // -- edx : receiver
3921 // -- esp[0] : return address 3955 // -- esp[0] : return address
3922 // ----------------------------------- 3956 // -----------------------------------
3923 Label miss_force_generic, transition_elements_kind, grow, slow; 3957 Label miss_force_generic, transition_elements_kind, grow, slow;
3924 Label check_capacity, prepare_slow, finish_store, commit_backing_store; 3958 Label check_capacity, prepare_slow, finish_store, commit_backing_store;
3925 3959
3926 // This stub is meant to be tail-jumped to, the receiver must already 3960 // This stub is meant to be tail-jumped to, the receiver must already
3927 // have been verified by the caller to not be a smi. 3961 // have been verified by the caller to not be a smi.
3928 3962
3929 // Check that the key is a smi. 3963 // Check that the key is a smi or a heap number convertible to a smi.
3930 __ JumpIfNotSmi(ecx, &miss_force_generic); 3964 GenerateSmiKeyCheck(masm, ecx, ebx, xmm0, xmm1, &miss_force_generic);
3931 3965
3932 // Get the elements array. 3966 // Get the elements array.
3933 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset)); 3967 __ mov(edi, FieldOperand(edx, JSObject::kElementsOffset));
3934 __ AssertFastElements(edi); 3968 __ AssertFastElements(edi);
3935 3969
3936 if (is_js_array) { 3970 if (is_js_array) {
3937 // Check that the key is within bounds. 3971 // Check that the key is within bounds.
3938 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis. 3972 __ cmp(ecx, FieldOperand(edx, JSArray::kLengthOffset)); // smis.
3939 if (grow_mode == ALLOW_JSARRAY_GROWTH) { 3973 if (grow_mode == ALLOW_JSARRAY_GROWTH) {
3940 __ j(above_equal, &grow); 3974 __ j(above_equal, &grow);
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
4036 __ jmp(ic_slow, RelocInfo::CODE_TARGET); 4070 __ jmp(ic_slow, RelocInfo::CODE_TARGET);
4037 } 4071 }
4038 } 4072 }
4039 4073
4040 4074
4041 #undef __ 4075 #undef __
4042 4076
4043 } } // namespace v8::internal 4077 } } // namespace v8::internal
4044 4078
4045 #endif // V8_TARGET_ARCH_IA32 4079 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/arm/stub-cache-arm.cc ('k') | src/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698