| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 // | 4 // |
| 5 // The intrinsic code below is executed before a method has built its frame. | 5 // The intrinsic code below is executed before a method has built its frame. |
| 6 // The return address is on the stack and the arguments below it. | 6 // The return address is on the stack and the arguments below it. |
| 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. | 7 // Registers EDX (arguments descriptor) and ECX (function) must be preserved. |
| 8 // Each intrinsification method returns true if the corresponding | 8 // Each intrinsification method returns true if the corresponding |
| 9 // Dart method was intrinsified. | 9 // Dart method was intrinsified. |
| 10 | 10 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 // This snippet of inlined code uses the following registers: | 107 // This snippet of inlined code uses the following registers: |
| 108 // EAX, EBX | 108 // EAX, EBX |
| 109 // and the newly allocated object is returned in EAX. | 109 // and the newly allocated object is returned in EAX. |
| 110 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; | 110 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; |
| 111 const intptr_t kArrayOffset = 1 * kWordSize; | 111 const intptr_t kArrayOffset = 1 * kWordSize; |
| 112 Label fall_through; | 112 Label fall_through; |
| 113 | 113 |
| 114 // Try allocating in new space. | 114 // Try allocating in new space. |
| 115 const Class& cls = Class::Handle( | 115 const Class& cls = Class::Handle( |
| 116 Isolate::Current()->object_store()->growable_object_array_class()); | 116 Isolate::Current()->object_store()->growable_object_array_class()); |
| 117 __ TryAllocate(cls, &fall_through, Assembler::kNearJump, EAX, EBX); | 117 const bool jump_length = VerifiedMemory::enabled() ? |
| 118 Assembler::kFarJump : |
| 119 Assembler::kNearJump; |
| 120 __ TryAllocate(cls, &fall_through, jump_length, EAX, EBX); |
| 118 | 121 |
| 119 // Store backing array object in growable array object. | 122 // Store backing array object in growable array object. |
| 120 __ movl(EBX, Address(ESP, kArrayOffset)); // data argument. | 123 __ movl(EBX, Address(ESP, kArrayOffset)); // data argument. |
| 121 // EAX is new, no barrier needed. | 124 // EAX is new, no barrier needed. |
| 122 __ StoreIntoObjectNoBarrier( | 125 __ StoreIntoObjectNoBarrier( |
| 123 EAX, | 126 EAX, |
| 124 FieldAddress(EAX, GrowableObjectArray::data_offset()), | 127 FieldAddress(EAX, GrowableObjectArray::data_offset()), |
| 125 EBX); | 128 EBX); |
| 126 | 129 |
| 127 // EAX: new growable array object start as a tagged pointer. | 130 // EAX: new growable array object start as a tagged pointer. |
| 128 // Store the type argument field in the growable array object. | 131 // Store the type argument field in the growable array object. |
| 129 __ movl(EBX, Address(ESP, kTypeArgumentsOffset)); // type argument. | 132 __ movl(EBX, Address(ESP, kTypeArgumentsOffset)); // type argument. |
| 130 __ StoreIntoObjectNoBarrier( | 133 __ StoreIntoObjectNoBarrier( |
| 131 EAX, | 134 EAX, |
| 132 FieldAddress(EAX, GrowableObjectArray::type_arguments_offset()), | 135 FieldAddress(EAX, GrowableObjectArray::type_arguments_offset()), |
| 133 EBX); | 136 EBX); |
| 134 | 137 |
| 135 // Set the length field in the growable array object to 0. | 138 __ ZeroSmiField(FieldAddress(EAX, GrowableObjectArray::length_offset())); |
| 136 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), | |
| 137 Immediate(0)); | |
| 138 __ ret(); // returns the newly allocated object in EAX. | 139 __ ret(); // returns the newly allocated object in EAX. |
| 139 | 140 |
| 140 __ Bind(&fall_through); | 141 __ Bind(&fall_through); |
| 141 } | 142 } |
| 142 | 143 |
| 143 | 144 |
| 144 // Access growable object array at specified index. | 145 // Access growable object array at specified index. |
| 145 // On stack: growable array (+2), index (+1), return-address (+0). | 146 // On stack: growable array (+2), index (+1), return-address (+0). |
| 146 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) { | 147 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) { |
| 147 Label fall_through; | 148 Label fall_through; |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 | 193 |
| 193 // Set length of growable object array. The length cannot | 194 // Set length of growable object array. The length cannot |
| 194 // be greater than the length of the data container. | 195 // be greater than the length of the data container. |
| 195 // On stack: growable array (+2), length (+1), return-address (+0). | 196 // On stack: growable array (+2), length (+1), return-address (+0). |
| 196 void Intrinsifier::GrowableArraySetLength(Assembler* assembler) { | 197 void Intrinsifier::GrowableArraySetLength(Assembler* assembler) { |
| 197 Label fall_through; | 198 Label fall_through; |
| 198 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array. | 199 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Growable array. |
| 199 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Length value. | 200 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Length value. |
| 200 __ testl(EBX, Immediate(kSmiTagMask)); | 201 __ testl(EBX, Immediate(kSmiTagMask)); |
| 201 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi length. | 202 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi length. |
| 202 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), EBX); | 203 FieldAddress length_field(EAX, GrowableObjectArray::length_offset()); |
| 204 __ StoreIntoSmiField(length_field, EBX); |
| 203 __ ret(); | 205 __ ret(); |
| 204 __ Bind(&fall_through); | 206 __ Bind(&fall_through); |
| 205 } | 207 } |
| 206 | 208 |
| 207 | 209 |
| 208 // Set data of growable object array. | 210 // Set data of growable object array. |
| 209 // On stack: growable array (+2), data (+1), return-address (+0). | 211 // On stack: growable array (+2), data (+1), return-address (+0). |
| 210 void Intrinsifier::GrowableArraySetData(Assembler* assembler) { | 212 void Intrinsifier::GrowableArraySetData(Assembler* assembler) { |
| 211 if (FLAG_enable_type_checks) { | 213 if (FLAG_enable_type_checks) { |
| 212 return; | 214 return; |
| (...skipping 1608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1821 // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1); | 1823 // hash_ = hash_ & ((static_cast<intptr_t>(1) << bits) - 1); |
| 1822 __ andl(EAX, | 1824 __ andl(EAX, |
| 1823 Immediate(((static_cast<intptr_t>(1) << String::kHashBits) - 1))); | 1825 Immediate(((static_cast<intptr_t>(1) << String::kHashBits) - 1))); |
| 1824 | 1826 |
| 1825 // return hash_ == 0 ? 1 : hash_; | 1827 // return hash_ == 0 ? 1 : hash_; |
| 1826 __ cmpl(EAX, Immediate(0)); | 1828 __ cmpl(EAX, Immediate(0)); |
| 1827 __ j(NOT_EQUAL, &set_hash_code, Assembler::kNearJump); | 1829 __ j(NOT_EQUAL, &set_hash_code, Assembler::kNearJump); |
| 1828 __ incl(EAX); | 1830 __ incl(EAX); |
| 1829 __ Bind(&set_hash_code); | 1831 __ Bind(&set_hash_code); |
| 1830 __ SmiTag(EAX); | 1832 __ SmiTag(EAX); |
| 1831 __ movl(FieldAddress(EBX, String::hash_offset()), EAX); | 1833 __ StoreIntoSmiField(FieldAddress(EBX, String::hash_offset()), EAX); |
| 1832 __ ret(); | 1834 __ ret(); |
| 1833 } | 1835 } |
| 1834 | 1836 |
| 1835 | 1837 |
| 1836 // Allocates one-byte string of length 'end - start'. The content is not | 1838 // Allocates one-byte string of length 'end - start'. The content is not |
| 1837 // initialized. 'length-reg' contains tagged length. | 1839 // initialized. 'length-reg' contains tagged length. |
| 1838 // Returns new string as tagged pointer in EAX. | 1840 // Returns new string as tagged pointer in EAX. |
| 1839 static void TryAllocateOnebyteString(Assembler* assembler, | 1841 static void TryAllocateOnebyteString(Assembler* assembler, |
| 1840 Label* ok, | 1842 Label* ok, |
| 1841 Label* failure, | 1843 Label* failure, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1894 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cid))); | 1896 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cid))); |
| 1895 __ movl(FieldAddress(EAX, String::tags_offset()), EDI); // Tags. | 1897 __ movl(FieldAddress(EAX, String::tags_offset()), EDI); // Tags. |
| 1896 } | 1898 } |
| 1897 | 1899 |
| 1898 // Set the length field. | 1900 // Set the length field. |
| 1899 __ popl(EDI); | 1901 __ popl(EDI); |
| 1900 __ StoreIntoObjectNoBarrier(EAX, | 1902 __ StoreIntoObjectNoBarrier(EAX, |
| 1901 FieldAddress(EAX, String::length_offset()), | 1903 FieldAddress(EAX, String::length_offset()), |
| 1902 EDI); | 1904 EDI); |
| 1903 // Clear hash. | 1905 // Clear hash. |
| 1904 __ movl(FieldAddress(EAX, String::hash_offset()), Immediate(0)); | 1906 __ ZeroSmiField(FieldAddress(EAX, String::hash_offset())); |
| 1905 __ jmp(ok, Assembler::kNearJump); | 1907 __ jmp(ok, Assembler::kNearJump); |
| 1906 | 1908 |
| 1907 __ Bind(&pop_and_fail); | 1909 __ Bind(&pop_and_fail); |
| 1908 __ popl(EDI); | 1910 __ popl(EDI); |
| 1909 __ jmp(failure); | 1911 __ jmp(failure); |
| 1910 } | 1912 } |
| 1911 | 1913 |
| 1912 | 1914 |
| 1913 // Arg0: OneByteString (receiver) | 1915 // Arg0: OneByteString (receiver) |
| 1914 // Arg1: Start index as Smi. | 1916 // Arg1: Start index as Smi. |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2091 Isolate::current_tag_offset()); | 2093 Isolate::current_tag_offset()); |
| 2092 // Set return value to Isolate::current_tag_. | 2094 // Set return value to Isolate::current_tag_. |
| 2093 __ movl(EAX, current_tag_addr); | 2095 __ movl(EAX, current_tag_addr); |
| 2094 __ ret(); | 2096 __ ret(); |
| 2095 } | 2097 } |
| 2096 | 2098 |
| 2097 #undef __ | 2099 #undef __ |
| 2098 } // namespace dart | 2100 } // namespace dart |
| 2099 | 2101 |
| 2100 #endif // defined TARGET_ARCH_IA32 | 2102 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |