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 2687 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2698 // -- rcx : key | 2698 // -- rcx : key |
2699 // -- rdx : receiver | 2699 // -- rdx : receiver |
2700 // -- rsp[0] : return address | 2700 // -- rsp[0] : return address |
2701 // ----------------------------------- | 2701 // ----------------------------------- |
2702 | 2702 |
2703 ElementsKind elements_kind = receiver_map->elements_kind(); | 2703 ElementsKind elements_kind = receiver_map->elements_kind(); |
2704 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; | 2704 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; |
2705 Handle<Code> stub = | 2705 Handle<Code> stub = |
2706 KeyedStoreElementStub(is_js_array, | 2706 KeyedStoreElementStub(is_js_array, |
2707 elements_kind, | 2707 elements_kind, |
2708 grow_mode_).GetCode(isolate()); | 2708 store_mode_).GetCode(isolate()); |
2709 | 2709 |
2710 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK); | 2710 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK); |
2711 | 2711 |
2712 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); | 2712 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); |
2713 __ jmp(ic, RelocInfo::CODE_TARGET); | 2713 __ jmp(ic, RelocInfo::CODE_TARGET); |
2714 | 2714 |
2715 // Return the generated code. | 2715 // Return the generated code. |
2716 return GetCode(Code::NORMAL, factory()->empty_string()); | 2716 return GetCode(Code::NORMAL, factory()->empty_string()); |
2717 } | 2717 } |
2718 | 2718 |
(...skipping 609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3328 Handle<Code> miss_ic = | 3328 Handle<Code> miss_ic = |
3329 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 3329 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
3330 __ jmp(miss_ic, RelocInfo::CODE_TARGET); | 3330 __ jmp(miss_ic, RelocInfo::CODE_TARGET); |
3331 } | 3331 } |
3332 | 3332 |
3333 | 3333 |
3334 void KeyedStoreStubCompiler::GenerateStoreFastElement( | 3334 void KeyedStoreStubCompiler::GenerateStoreFastElement( |
3335 MacroAssembler* masm, | 3335 MacroAssembler* masm, |
3336 bool is_js_array, | 3336 bool is_js_array, |
3337 ElementsKind elements_kind, | 3337 ElementsKind elements_kind, |
3338 KeyedAccessGrowMode grow_mode) { | 3338 KeyedAccessStoreMode store_mode) { |
3339 // ----------- S t a t e ------------- | 3339 // ----------- S t a t e ------------- |
3340 // -- rax : value | 3340 // -- rax : value |
3341 // -- rcx : key | 3341 // -- rcx : key |
3342 // -- rdx : receiver | 3342 // -- rdx : receiver |
3343 // -- rsp[0] : return address | 3343 // -- rsp[0] : return address |
3344 // ----------------------------------- | 3344 // ----------------------------------- |
3345 Label miss_force_generic, transition_elements_kind, finish_store, grow; | 3345 Label miss_force_generic, transition_elements_kind, finish_store, grow; |
3346 Label check_capacity, slow; | 3346 Label check_capacity, slow; |
3347 | 3347 |
3348 // This stub is meant to be tail-jumped to, the receiver must already | 3348 // This stub is meant to be tail-jumped to, the receiver must already |
3349 // have been verified by the caller to not be a smi. | 3349 // have been verified by the caller to not be a smi. |
3350 | 3350 |
3351 // Check that the key is a smi or a heap number convertible to a smi. | 3351 // Check that the key is a smi or a heap number convertible to a smi. |
3352 GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic); | 3352 GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic); |
3353 | 3353 |
3354 if (IsFastSmiElementsKind(elements_kind)) { | 3354 if (IsFastSmiElementsKind(elements_kind)) { |
3355 __ JumpIfNotSmi(rax, &transition_elements_kind); | 3355 __ JumpIfNotSmi(rax, &transition_elements_kind); |
3356 } | 3356 } |
3357 | 3357 |
3358 // Get the elements array and make sure it is a fast element array, not 'cow'. | 3358 // Get the elements array and make sure it is a fast element array, not 'cow'. |
3359 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); | 3359 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); |
3360 // Check that the key is within bounds. | 3360 // Check that the key is within bounds. |
3361 if (is_js_array) { | 3361 if (is_js_array) { |
3362 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); | 3362 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); |
3363 if (grow_mode == ALLOW_JSARRAY_GROWTH) { | 3363 if (IsGrowStoreMode(store_mode)) { |
3364 __ j(above_equal, &grow); | 3364 __ j(above_equal, &grow); |
3365 } else { | 3365 } else { |
3366 __ j(above_equal, &miss_force_generic); | 3366 __ j(above_equal, &miss_force_generic); |
3367 } | 3367 } |
3368 } else { | 3368 } else { |
3369 __ SmiCompare(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); | 3369 __ SmiCompare(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); |
3370 __ j(above_equal, &miss_force_generic); | 3370 __ j(above_equal, &miss_force_generic); |
3371 } | 3371 } |
3372 | 3372 |
3373 __ CompareRoot(FieldOperand(rdi, HeapObject::kMapOffset), | 3373 __ CompareRoot(FieldOperand(rdi, HeapObject::kMapOffset), |
(...skipping 23 matching lines...) Expand all Loading... |
3397 // Handle store cache miss. | 3397 // Handle store cache miss. |
3398 __ bind(&miss_force_generic); | 3398 __ bind(&miss_force_generic); |
3399 Handle<Code> ic_force_generic = | 3399 Handle<Code> ic_force_generic = |
3400 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 3400 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
3401 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); | 3401 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); |
3402 | 3402 |
3403 __ bind(&transition_elements_kind); | 3403 __ bind(&transition_elements_kind); |
3404 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 3404 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
3405 __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 3405 __ jmp(ic_miss, RelocInfo::CODE_TARGET); |
3406 | 3406 |
3407 if (is_js_array && grow_mode == ALLOW_JSARRAY_GROWTH) { | 3407 if (is_js_array && IsGrowStoreMode(store_mode)) { |
3408 // Grow the array by a single element if possible. | 3408 // Grow the array by a single element if possible. |
3409 __ bind(&grow); | 3409 __ bind(&grow); |
3410 | 3410 |
3411 // Make sure the array is only growing by a single element, anything else | 3411 // Make sure the array is only growing by a single element, anything else |
3412 // must be handled by the runtime. Flags are already set by previous | 3412 // must be handled by the runtime. Flags are already set by previous |
3413 // compare. | 3413 // compare. |
3414 __ j(not_equal, &miss_force_generic); | 3414 __ j(not_equal, &miss_force_generic); |
3415 | 3415 |
3416 // Check for the empty array, and preallocate a small backing store if | 3416 // Check for the empty array, and preallocate a small backing store if |
3417 // possible. | 3417 // possible. |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3470 __ bind(&slow); | 3470 __ bind(&slow); |
3471 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); | 3471 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); |
3472 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | 3472 __ jmp(ic_slow, RelocInfo::CODE_TARGET); |
3473 } | 3473 } |
3474 } | 3474 } |
3475 | 3475 |
3476 | 3476 |
3477 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( | 3477 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( |
3478 MacroAssembler* masm, | 3478 MacroAssembler* masm, |
3479 bool is_js_array, | 3479 bool is_js_array, |
3480 KeyedAccessGrowMode grow_mode) { | 3480 KeyedAccessStoreMode store_mode) { |
3481 // ----------- S t a t e ------------- | 3481 // ----------- S t a t e ------------- |
3482 // -- rax : value | 3482 // -- rax : value |
3483 // -- rcx : key | 3483 // -- rcx : key |
3484 // -- rdx : receiver | 3484 // -- rdx : receiver |
3485 // -- rsp[0] : return address | 3485 // -- rsp[0] : return address |
3486 // ----------------------------------- | 3486 // ----------------------------------- |
3487 Label miss_force_generic, transition_elements_kind, finish_store; | 3487 Label miss_force_generic, transition_elements_kind, finish_store; |
3488 Label grow, slow, check_capacity, restore_key_transition_elements_kind; | 3488 Label grow, slow, check_capacity, restore_key_transition_elements_kind; |
3489 | 3489 |
3490 // This stub is meant to be tail-jumped to, the receiver must already | 3490 // This stub is meant to be tail-jumped to, the receiver must already |
3491 // have been verified by the caller to not be a smi. | 3491 // have been verified by the caller to not be a smi. |
3492 | 3492 |
3493 // Check that the key is a smi or a heap number convertible to a smi. | 3493 // Check that the key is a smi or a heap number convertible to a smi. |
3494 GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic); | 3494 GenerateSmiKeyCheck(masm, rcx, rbx, xmm0, xmm1, &miss_force_generic); |
3495 | 3495 |
3496 // Get the elements array. | 3496 // Get the elements array. |
3497 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); | 3497 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); |
3498 __ AssertFastElements(rdi); | 3498 __ AssertFastElements(rdi); |
3499 | 3499 |
3500 // Check that the key is within bounds. | 3500 // Check that the key is within bounds. |
3501 if (is_js_array) { | 3501 if (is_js_array) { |
3502 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); | 3502 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); |
3503 if (grow_mode == ALLOW_JSARRAY_GROWTH) { | 3503 if (IsGrowStoreMode(store_mode)) { |
3504 __ j(above_equal, &grow); | 3504 __ j(above_equal, &grow); |
3505 } else { | 3505 } else { |
3506 __ j(above_equal, &miss_force_generic); | 3506 __ j(above_equal, &miss_force_generic); |
3507 } | 3507 } |
3508 } else { | 3508 } else { |
3509 __ SmiCompare(rcx, FieldOperand(rdi, FixedDoubleArray::kLengthOffset)); | 3509 __ SmiCompare(rcx, FieldOperand(rdi, FixedDoubleArray::kLengthOffset)); |
3510 __ j(above_equal, &miss_force_generic); | 3510 __ j(above_equal, &miss_force_generic); |
3511 } | 3511 } |
3512 | 3512 |
3513 // Handle smi values specially | 3513 // Handle smi values specially |
3514 __ bind(&finish_store); | 3514 __ bind(&finish_store); |
3515 __ SmiToInteger32(rcx, rcx); | 3515 __ SmiToInteger32(rcx, rcx); |
3516 __ StoreNumberToDoubleElements(rax, rdi, rcx, xmm0, | 3516 __ StoreNumberToDoubleElements(rax, rdi, rcx, xmm0, |
3517 &restore_key_transition_elements_kind); | 3517 &restore_key_transition_elements_kind); |
3518 __ ret(0); | 3518 __ ret(0); |
3519 | 3519 |
3520 // Handle store cache miss, replacing the ic with the generic stub. | 3520 // Handle store cache miss, replacing the ic with the generic stub. |
3521 __ bind(&miss_force_generic); | 3521 __ bind(&miss_force_generic); |
3522 Handle<Code> ic_force_generic = | 3522 Handle<Code> ic_force_generic = |
3523 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); | 3523 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); |
3524 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); | 3524 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); |
3525 | 3525 |
3526 __ bind(&restore_key_transition_elements_kind); | 3526 __ bind(&restore_key_transition_elements_kind); |
3527 // Restore smi-tagging of rcx. | 3527 // Restore smi-tagging of rcx. |
3528 __ Integer32ToSmi(rcx, rcx); | 3528 __ Integer32ToSmi(rcx, rcx); |
3529 __ bind(&transition_elements_kind); | 3529 __ bind(&transition_elements_kind); |
3530 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); | 3530 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); |
3531 __ jmp(ic_miss, RelocInfo::CODE_TARGET); | 3531 __ jmp(ic_miss, RelocInfo::CODE_TARGET); |
3532 | 3532 |
3533 if (is_js_array && grow_mode == ALLOW_JSARRAY_GROWTH) { | 3533 if (is_js_array && IsGrowStoreMode(store_mode)) { |
3534 // Grow the array by a single element if possible. | 3534 // Grow the array by a single element if possible. |
3535 __ bind(&grow); | 3535 __ bind(&grow); |
3536 | 3536 |
3537 // Make sure the array is only growing by a single element, anything else | 3537 // Make sure the array is only growing by a single element, anything else |
3538 // must be handled by the runtime. Flags are already set by previous | 3538 // must be handled by the runtime. Flags are already set by previous |
3539 // compare. | 3539 // compare. |
3540 __ j(not_equal, &miss_force_generic); | 3540 __ j(not_equal, &miss_force_generic); |
3541 | 3541 |
3542 // Transition on values that can't be stored in a FixedDoubleArray. | 3542 // Transition on values that can't be stored in a FixedDoubleArray. |
3543 Label value_is_smi; | 3543 Label value_is_smi; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3606 __ jmp(ic_slow, RelocInfo::CODE_TARGET); | 3606 __ jmp(ic_slow, RelocInfo::CODE_TARGET); |
3607 } | 3607 } |
3608 } | 3608 } |
3609 | 3609 |
3610 | 3610 |
3611 #undef __ | 3611 #undef __ |
3612 | 3612 |
3613 } } // namespace v8::internal | 3613 } } // namespace v8::internal |
3614 | 3614 |
3615 #endif // V8_TARGET_ARCH_X64 | 3615 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |