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 |