| 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 |