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 3677 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3688 } | 3688 } |
3689 return false; | 3689 return false; |
3690 } | 3690 } |
3691 | 3691 |
3692 | 3692 |
3693 static void GenerateSmiKeyCheck(MacroAssembler* masm, | 3693 static void GenerateSmiKeyCheck(MacroAssembler* masm, |
3694 Register key, | 3694 Register key, |
3695 Register scratch0, | 3695 Register scratch0, |
3696 Register scratch1, | 3696 Register scratch1, |
3697 FPURegister double_scratch0, | 3697 FPURegister double_scratch0, |
| 3698 FPURegister double_scratch1, |
3698 Label* fail) { | 3699 Label* fail) { |
3699 if (CpuFeatures::IsSupported(FPU)) { | 3700 if (CpuFeatures::IsSupported(FPU)) { |
3700 CpuFeatures::Scope scope(FPU); | 3701 CpuFeatures::Scope scope(FPU); |
3701 Label key_ok; | 3702 Label key_ok; |
3702 // Check for smi or a smi inside a heap number. We convert the heap | 3703 // Check for smi or a smi inside a heap number. We convert the heap |
3703 // number and check if the conversion is exact and fits into the smi | 3704 // number and check if the conversion is exact and fits into the smi |
3704 // range. | 3705 // range. |
3705 __ JumpIfSmi(key, &key_ok); | 3706 __ JumpIfSmi(key, &key_ok); |
3706 __ CheckMap(key, | 3707 __ CheckMap(key, |
3707 scratch0, | 3708 scratch0, |
3708 Heap::kHeapNumberMapRootIndex, | 3709 Heap::kHeapNumberMapRootIndex, |
3709 fail, | 3710 fail, |
3710 DONT_DO_SMI_CHECK); | 3711 DONT_DO_SMI_CHECK); |
3711 __ ldc1(double_scratch0, FieldMemOperand(key, HeapNumber::kValueOffset)); | 3712 __ ldc1(double_scratch0, FieldMemOperand(key, HeapNumber::kValueOffset)); |
3712 __ EmitFPUTruncate(kRoundToZero, | 3713 __ EmitFPUTruncate(kRoundToZero, |
| 3714 scratch0, |
3713 double_scratch0, | 3715 double_scratch0, |
3714 double_scratch0, | 3716 at, |
3715 scratch0, | 3717 double_scratch1, |
3716 scratch1, | 3718 scratch1, |
3717 kCheckForInexactConversion); | 3719 kCheckForInexactConversion); |
3718 | 3720 |
3719 __ Branch(fail, ne, scratch1, Operand(zero_reg)); | 3721 __ Branch(fail, ne, scratch1, Operand(zero_reg)); |
3720 | 3722 |
3721 __ mfc1(scratch0, double_scratch0); | |
3722 __ SmiTagCheckOverflow(key, scratch0, scratch1); | 3723 __ SmiTagCheckOverflow(key, scratch0, scratch1); |
3723 __ BranchOnOverflow(fail, scratch1); | 3724 __ BranchOnOverflow(fail, scratch1); |
3724 __ bind(&key_ok); | 3725 __ bind(&key_ok); |
3725 } else { | 3726 } else { |
3726 // Check that the key is a smi. | 3727 // Check that the key is a smi. |
3727 __ JumpIfNotSmi(key, fail); | 3728 __ JumpIfNotSmi(key, fail); |
3728 } | 3729 } |
3729 } | 3730 } |
3730 | 3731 |
3731 | 3732 |
3732 void KeyedLoadStubCompiler::GenerateLoadExternalArray( | 3733 void KeyedLoadStubCompiler::GenerateLoadExternalArray( |
3733 MacroAssembler* masm, | 3734 MacroAssembler* masm, |
3734 ElementsKind elements_kind) { | 3735 ElementsKind elements_kind) { |
3735 // ---------- S t a t e -------------- | 3736 // ---------- S t a t e -------------- |
3736 // -- ra : return address | 3737 // -- ra : return address |
3737 // -- a0 : key | 3738 // -- a0 : key |
3738 // -- a1 : receiver | 3739 // -- a1 : receiver |
3739 // ----------------------------------- | 3740 // ----------------------------------- |
3740 Label miss_force_generic, slow, failed_allocation; | 3741 Label miss_force_generic, slow, failed_allocation; |
3741 | 3742 |
3742 Register key = a0; | 3743 Register key = a0; |
3743 Register receiver = a1; | 3744 Register receiver = a1; |
3744 | 3745 |
3745 // This stub is meant to be tail-jumped to, the receiver must already | 3746 // This stub is meant to be tail-jumped to, the receiver must already |
3746 // have been verified by the caller to not be a smi. | 3747 // have been verified by the caller to not be a smi. |
3747 | 3748 |
3748 // Check that the key is a smi or a heap number convertible to a smi. | 3749 // Check that the key is a smi or a heap number convertible to a smi. |
3749 GenerateSmiKeyCheck(masm, key, t0, t1, f2, &miss_force_generic); | 3750 GenerateSmiKeyCheck(masm, key, t0, t1, f2, f4, &miss_force_generic); |
3750 | 3751 |
3751 __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 3752 __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
3752 // a3: elements array | 3753 // a3: elements array |
3753 | 3754 |
3754 // Check that the index is in range. | 3755 // Check that the index is in range. |
3755 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset)); | 3756 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset)); |
3756 __ sra(t2, key, kSmiTagSize); | 3757 __ sra(t2, key, kSmiTagSize); |
3757 // Unsigned comparison catches both negative and too-large values. | 3758 // Unsigned comparison catches both negative and too-large values. |
3758 __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1)); | 3759 __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1)); |
3759 | 3760 |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4081 // Register usage. | 4082 // Register usage. |
4082 Register value = a0; | 4083 Register value = a0; |
4083 Register key = a1; | 4084 Register key = a1; |
4084 Register receiver = a2; | 4085 Register receiver = a2; |
4085 // a3 mostly holds the elements array or the destination external array. | 4086 // a3 mostly holds the elements array or the destination external array. |
4086 | 4087 |
4087 // This stub is meant to be tail-jumped to, the receiver must already | 4088 // This stub is meant to be tail-jumped to, the receiver must already |
4088 // have been verified by the caller to not be a smi. | 4089 // have been verified by the caller to not be a smi. |
4089 | 4090 |
4090 // Check that the key is a smi or a heap number convertible to a smi. | 4091 // Check that the key is a smi or a heap number convertible to a smi. |
4091 GenerateSmiKeyCheck(masm, key, t0, t1, f2, &miss_force_generic); | 4092 GenerateSmiKeyCheck(masm, key, t0, t1, f2, f4, &miss_force_generic); |
4092 | 4093 |
4093 __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset)); | 4094 __ lw(a3, FieldMemOperand(receiver, JSObject::kElementsOffset)); |
4094 | 4095 |
4095 // Check that the index is in range. | 4096 // Check that the index is in range. |
4096 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset)); | 4097 __ lw(t1, FieldMemOperand(a3, ExternalArray::kLengthOffset)); |
4097 // Unsigned comparison catches both negative and too-large values. | 4098 // Unsigned comparison catches both negative and too-large values. |
4098 __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1)); | 4099 __ Branch(&miss_force_generic, Ugreater_equal, key, Operand(t1)); |
4099 | 4100 |
4100 // Handle both smis and HeapNumbers in the fast path. Go to the | 4101 // Handle both smis and HeapNumbers in the fast path. Go to the |
4101 // runtime for all other kinds of values. | 4102 // runtime for all other kinds of values. |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4470 // -- ra : return address | 4471 // -- ra : return address |
4471 // -- a0 : key | 4472 // -- a0 : key |
4472 // -- a1 : receiver | 4473 // -- a1 : receiver |
4473 // ----------------------------------- | 4474 // ----------------------------------- |
4474 Label miss_force_generic; | 4475 Label miss_force_generic; |
4475 | 4476 |
4476 // This stub is meant to be tail-jumped to, the receiver must already | 4477 // This stub is meant to be tail-jumped to, the receiver must already |
4477 // have been verified by the caller to not be a smi. | 4478 // have been verified by the caller to not be a smi. |
4478 | 4479 |
4479 // Check that the key is a smi or a heap number convertible to a smi. | 4480 // Check that the key is a smi or a heap number convertible to a smi. |
4480 GenerateSmiKeyCheck(masm, a0, t0, t1, f2, &miss_force_generic); | 4481 GenerateSmiKeyCheck(masm, a0, t0, t1, f2, f4, &miss_force_generic); |
4481 | 4482 |
4482 // Get the elements array. | 4483 // Get the elements array. |
4483 __ lw(a2, FieldMemOperand(a1, JSObject::kElementsOffset)); | 4484 __ lw(a2, FieldMemOperand(a1, JSObject::kElementsOffset)); |
4484 __ AssertFastElements(a2); | 4485 __ AssertFastElements(a2); |
4485 | 4486 |
4486 // Check that the key is within bounds. | 4487 // Check that the key is within bounds. |
4487 __ lw(a3, FieldMemOperand(a2, FixedArray::kLengthOffset)); | 4488 __ lw(a3, FieldMemOperand(a2, FixedArray::kLengthOffset)); |
4488 __ Branch(USE_DELAY_SLOT, &miss_force_generic, hs, a0, Operand(a3)); | 4489 __ Branch(USE_DELAY_SLOT, &miss_force_generic, hs, a0, Operand(a3)); |
4489 | 4490 |
4490 // Load the result and make sure it's not the hole. | 4491 // Load the result and make sure it's not the hole. |
(...skipping 30 matching lines...) Expand all Loading... |
4521 Register indexed_double_offset = a3; | 4522 Register indexed_double_offset = a3; |
4522 Register scratch = t0; | 4523 Register scratch = t0; |
4523 Register scratch2 = t1; | 4524 Register scratch2 = t1; |
4524 Register scratch3 = t2; | 4525 Register scratch3 = t2; |
4525 Register heap_number_map = t3; | 4526 Register heap_number_map = t3; |
4526 | 4527 |
4527 // This stub is meant to be tail-jumped to, the receiver must already | 4528 // This stub is meant to be tail-jumped to, the receiver must already |
4528 // have been verified by the caller to not be a smi. | 4529 // have been verified by the caller to not be a smi. |
4529 | 4530 |
4530 // Check that the key is a smi or a heap number convertible to a smi. | 4531 // Check that the key is a smi or a heap number convertible to a smi. |
4531 GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic); | 4532 GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, f4, &miss_force_generic); |
4532 | 4533 |
4533 // Get the elements array. | 4534 // Get the elements array. |
4534 __ lw(elements_reg, | 4535 __ lw(elements_reg, |
4535 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); | 4536 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
4536 | 4537 |
4537 // Check that the key is within bounds. | 4538 // Check that the key is within bounds. |
4538 __ lw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); | 4539 __ lw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); |
4539 __ Branch(&miss_force_generic, hs, key_reg, Operand(scratch)); | 4540 __ Branch(&miss_force_generic, hs, key_reg, Operand(scratch)); |
4540 | 4541 |
4541 // Load the upper word of the double in the fixed array and test for NaN. | 4542 // Load the upper word of the double in the fixed array and test for NaN. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4595 Register receiver_reg = a2; | 4596 Register receiver_reg = a2; |
4596 Register scratch = t0; | 4597 Register scratch = t0; |
4597 Register elements_reg = a3; | 4598 Register elements_reg = a3; |
4598 Register length_reg = t1; | 4599 Register length_reg = t1; |
4599 Register scratch2 = t2; | 4600 Register scratch2 = t2; |
4600 | 4601 |
4601 // This stub is meant to be tail-jumped to, the receiver must already | 4602 // This stub is meant to be tail-jumped to, the receiver must already |
4602 // have been verified by the caller to not be a smi. | 4603 // have been verified by the caller to not be a smi. |
4603 | 4604 |
4604 // Check that the key is a smi or a heap number convertible to a smi. | 4605 // Check that the key is a smi or a heap number convertible to a smi. |
4605 GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic); | 4606 GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, f4, &miss_force_generic); |
4606 | 4607 |
4607 if (IsFastSmiElementsKind(elements_kind)) { | 4608 if (IsFastSmiElementsKind(elements_kind)) { |
4608 __ JumpIfNotSmi(value_reg, &transition_elements_kind); | 4609 __ JumpIfNotSmi(value_reg, &transition_elements_kind); |
4609 } | 4610 } |
4610 | 4611 |
4611 // Check that the key is within bounds. | 4612 // Check that the key is within bounds. |
4612 __ lw(elements_reg, | 4613 __ lw(elements_reg, |
4613 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); | 4614 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
4614 if (is_js_array) { | 4615 if (is_js_array) { |
4615 __ lw(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); | 4616 __ lw(scratch, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4762 Register scratch1 = t0; | 4763 Register scratch1 = t0; |
4763 Register scratch2 = t1; | 4764 Register scratch2 = t1; |
4764 Register scratch3 = t2; | 4765 Register scratch3 = t2; |
4765 Register scratch4 = t3; | 4766 Register scratch4 = t3; |
4766 Register length_reg = t3; | 4767 Register length_reg = t3; |
4767 | 4768 |
4768 // This stub is meant to be tail-jumped to, the receiver must already | 4769 // This stub is meant to be tail-jumped to, the receiver must already |
4769 // have been verified by the caller to not be a smi. | 4770 // have been verified by the caller to not be a smi. |
4770 | 4771 |
4771 // Check that the key is a smi or a heap number convertible to a smi. | 4772 // Check that the key is a smi or a heap number convertible to a smi. |
4772 GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, &miss_force_generic); | 4773 GenerateSmiKeyCheck(masm, key_reg, t0, t1, f2, f4, &miss_force_generic); |
4773 | 4774 |
4774 __ lw(elements_reg, | 4775 __ lw(elements_reg, |
4775 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); | 4776 FieldMemOperand(receiver_reg, JSObject::kElementsOffset)); |
4776 | 4777 |
4777 // Check that the key is within bounds. | 4778 // Check that the key is within bounds. |
4778 if (is_js_array) { | 4779 if (is_js_array) { |
4779 __ lw(scratch1, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); | 4780 __ lw(scratch1, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); |
4780 } else { | 4781 } else { |
4781 __ lw(scratch1, | 4782 __ lw(scratch1, |
4782 FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); | 4783 FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4881 __ Jump(ic_slow, RelocInfo::CODE_TARGET); | 4882 __ Jump(ic_slow, RelocInfo::CODE_TARGET); |
4882 } | 4883 } |
4883 } | 4884 } |
4884 | 4885 |
4885 | 4886 |
4886 #undef __ | 4887 #undef __ |
4887 | 4888 |
4888 } } // namespace v8::internal | 4889 } } // namespace v8::internal |
4889 | 4890 |
4890 #endif // V8_TARGET_ARCH_MIPS | 4891 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |