OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 4749 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4760 // to ensure the key is a smi must be added. | 4760 // to ensure the key is a smi must be added. |
4761 if (key_not_smi != NULL) { | 4761 if (key_not_smi != NULL) { |
4762 __ JumpIfNotSmi(key, key_not_smi); | 4762 __ JumpIfNotSmi(key, key_not_smi); |
4763 } else { | 4763 } else { |
4764 if (FLAG_debug_code) { | 4764 if (FLAG_debug_code) { |
4765 __ AbortIfNotSmi(key); | 4765 __ AbortIfNotSmi(key); |
4766 } | 4766 } |
4767 } | 4767 } |
4768 __ SmiToInteger32(untagged_key, key); | 4768 __ SmiToInteger32(untagged_key, key); |
4769 | 4769 |
4770 // Verify that the receiver has pixel array elements. | |
4771 __ movq(elements, FieldOperand(receiver, JSObject::kElementsOffset)); | 4770 __ movq(elements, FieldOperand(receiver, JSObject::kElementsOffset)); |
4772 __ CheckMap(elements, Factory::pixel_array_map(), not_pixel_array, true); | 4771 // By passing NULL as not_pixel_array, callers signal that they have already |
| 4772 // verified that the receiver has pixel array elements. |
| 4773 if (not_pixel_array != NULL) { |
| 4774 __ CheckMap(elements, Factory::pixel_array_map(), not_pixel_array, true); |
| 4775 } else { |
| 4776 if (FLAG_debug_code) { |
| 4777 // Map check should have already made sure that elements is a pixel array. |
| 4778 __ Cmp(FieldOperand(elements, HeapObject::kMapOffset), |
| 4779 Factory::pixel_array_map()); |
| 4780 __ Assert(equal, "Elements isn't a pixel array"); |
| 4781 } |
| 4782 } |
4773 | 4783 |
4774 // Check that the smi is in range. | 4784 // Check that the smi is in range. |
4775 __ cmpl(untagged_key, FieldOperand(elements, PixelArray::kLengthOffset)); | 4785 __ cmpl(untagged_key, FieldOperand(elements, PixelArray::kLengthOffset)); |
4776 __ j(above_equal, out_of_range); // unsigned check handles negative keys. | 4786 __ j(above_equal, out_of_range); // unsigned check handles negative keys. |
4777 | 4787 |
4778 // Load and tag the element as a smi. | 4788 // Load and tag the element as a smi. |
4779 __ movq(elements, FieldOperand(elements, PixelArray::kExternalPointerOffset)); | 4789 __ movq(elements, FieldOperand(elements, PixelArray::kExternalPointerOffset)); |
4780 __ movzxbq(result, Operand(elements, untagged_key, times_1, 0)); | 4790 __ movzxbq(result, Operand(elements, untagged_key, times_1, 0)); |
4781 __ Integer32ToSmi(result, result); | 4791 __ Integer32ToSmi(result, result); |
4782 __ ret(0); | 4792 __ ret(0); |
4783 } | 4793 } |
4784 | 4794 |
4785 | 4795 |
| 4796 // Stores an indexed element into a pixel array, clamping the stored value. |
| 4797 void GenerateFastPixelArrayStore(MacroAssembler* masm, |
| 4798 Register receiver, |
| 4799 Register key, |
| 4800 Register value, |
| 4801 Register elements, |
| 4802 Register scratch1, |
| 4803 bool load_elements_from_receiver, |
| 4804 bool key_is_untagged, |
| 4805 Label* key_not_smi, |
| 4806 Label* value_not_smi, |
| 4807 Label* not_pixel_array, |
| 4808 Label* out_of_range) { |
| 4809 // Register use: |
| 4810 // receiver - holds the receiver and is unchanged. |
| 4811 // key - holds the key (must be a smi) and is unchanged. |
| 4812 // value - holds the value (must be a smi) and is unchanged. |
| 4813 // elements - holds the element object of the receiver on entry if |
| 4814 // load_elements_from_receiver is false, otherwise used |
| 4815 // internally to store the pixel arrays elements and |
| 4816 // external array pointer. |
| 4817 // |
| 4818 Register external_pointer = elements; |
| 4819 Register untagged_key = scratch1; |
| 4820 Register untagged_value = receiver; // Only set once success guaranteed. |
| 4821 |
| 4822 // Fetch the receiver's elements if the caller hasn't already done so. |
| 4823 if (load_elements_from_receiver) { |
| 4824 __ movq(elements, FieldOperand(receiver, JSObject::kElementsOffset)); |
| 4825 } |
| 4826 |
| 4827 // By passing NULL as not_pixel_array, callers signal that they have already |
| 4828 // verified that the receiver has pixel array elements. |
| 4829 if (not_pixel_array != NULL) { |
| 4830 __ CheckMap(elements, Factory::pixel_array_map(), not_pixel_array, true); |
| 4831 } else { |
| 4832 if (FLAG_debug_code) { |
| 4833 // Map check should have already made sure that elements is a pixel array. |
| 4834 __ Cmp(FieldOperand(elements, HeapObject::kMapOffset), |
| 4835 Factory::pixel_array_map()); |
| 4836 __ Assert(equal, "Elements isn't a pixel array"); |
| 4837 } |
| 4838 } |
| 4839 |
| 4840 // Some callers already have verified that the key is a smi. key_not_smi is |
| 4841 // set to NULL as a sentinel for that case. Otherwise, add an explicit check |
| 4842 // to ensure the key is a smi must be added. |
| 4843 if (key_not_smi != NULL) { |
| 4844 __ JumpIfNotSmi(key, key_not_smi); |
| 4845 } else { |
| 4846 if (FLAG_debug_code) { |
| 4847 __ AbortIfNotSmi(key); |
| 4848 } |
| 4849 } |
| 4850 |
| 4851 // Key must be a smi and it must be in range. |
| 4852 if (key_is_untagged) { |
| 4853 untagged_key = key; |
| 4854 } else { |
| 4855 __ SmiToInteger32(untagged_key, key); |
| 4856 } |
| 4857 __ cmpl(untagged_key, FieldOperand(elements, PixelArray::kLengthOffset)); |
| 4858 __ j(above_equal, out_of_range); // unsigned check handles negative keys. |
| 4859 |
| 4860 // Value must be a smi. |
| 4861 __ JumpIfNotSmi(value, value_not_smi); |
| 4862 __ SmiToInteger32(untagged_value, value); |
| 4863 |
| 4864 { // Clamp the value to [0..255]. |
| 4865 NearLabel done; |
| 4866 __ testl(untagged_value, Immediate(0xFFFFFF00)); |
| 4867 __ j(zero, &done); |
| 4868 __ setcc(negative, untagged_value); // 1 if negative, 0 if positive. |
| 4869 __ decb(untagged_value); // 0 if negative, 255 if positive. |
| 4870 __ bind(&done); |
| 4871 } |
| 4872 |
| 4873 __ movq(external_pointer, |
| 4874 FieldOperand(elements, PixelArray::kExternalPointerOffset)); |
| 4875 __ movb(Operand(external_pointer, untagged_key, times_1, 0), untagged_value); |
| 4876 __ ret(0); // Return value in eax. |
| 4877 } |
| 4878 |
4786 #undef __ | 4879 #undef __ |
4787 | 4880 |
4788 } } // namespace v8::internal | 4881 } } // namespace v8::internal |
4789 | 4882 |
4790 #endif // V8_TARGET_ARCH_X64 | 4883 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |