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 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 // This snippet of inlined code uses the following registers: | 108 // This snippet of inlined code uses the following registers: |
109 // EAX, EBX | 109 // EAX, EBX |
110 // and the newly allocated object is returned in EAX. | 110 // and the newly allocated object is returned in EAX. |
111 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; | 111 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; |
112 const intptr_t kArrayOffset = 1 * kWordSize; | 112 const intptr_t kArrayOffset = 1 * kWordSize; |
113 Label fall_through; | 113 Label fall_through; |
114 | 114 |
115 // Try allocating in new space. | 115 // Try allocating in new space. |
116 const Class& cls = Class::Handle( | 116 const Class& cls = Class::Handle( |
117 Isolate::Current()->object_store()->growable_object_array_class()); | 117 Isolate::Current()->object_store()->growable_object_array_class()); |
118 __ TryAllocate(cls, &fall_through, Assembler::kNearJump, EAX, EBX); | 118 #if defined(DEBUG) |
| 119 static const bool kJumpLength = Assembler::kFarJump; |
| 120 #else |
| 121 static const bool kJumpLength = Assembler::kNearJump; |
| 122 #endif // DEBUG |
| 123 __ TryAllocate(cls, &fall_through, kJumpLength, EAX, EBX); |
119 | 124 |
120 // Store backing array object in growable array object. | 125 // Store backing array object in growable array object. |
121 __ movl(EBX, Address(ESP, kArrayOffset)); // data argument. | 126 __ movl(EBX, Address(ESP, kArrayOffset)); // data argument. |
122 // EAX is new, no barrier needed. | 127 // EAX is new, no barrier needed. |
123 __ StoreIntoObjectNoBarrier( | 128 __ InitializeFieldNoBarrier( |
124 EAX, | 129 EAX, |
125 FieldAddress(EAX, GrowableObjectArray::data_offset()), | 130 FieldAddress(EAX, GrowableObjectArray::data_offset()), |
126 EBX); | 131 EBX); |
127 | 132 |
128 // EAX: new growable array object start as a tagged pointer. | 133 // EAX: new growable array object start as a tagged pointer. |
129 // Store the type argument field in the growable array object. | 134 // Store the type argument field in the growable array object. |
130 __ movl(EBX, Address(ESP, kTypeArgumentsOffset)); // type argument. | 135 __ movl(EBX, Address(ESP, kTypeArgumentsOffset)); // type argument. |
131 __ StoreIntoObjectNoBarrier( | 136 __ InitializeFieldNoBarrier( |
132 EAX, | 137 EAX, |
133 FieldAddress(EAX, GrowableObjectArray::type_arguments_offset()), | 138 FieldAddress(EAX, GrowableObjectArray::type_arguments_offset()), |
134 EBX); | 139 EBX); |
135 | 140 |
136 __ ZeroSmiField(FieldAddress(EAX, GrowableObjectArray::length_offset())); | 141 __ ZeroInitSmiField(FieldAddress(EAX, GrowableObjectArray::length_offset())); |
137 __ ret(); // returns the newly allocated object in EAX. | 142 __ ret(); // returns the newly allocated object in EAX. |
138 | 143 |
139 __ Bind(&fall_through); | 144 __ Bind(&fall_through); |
140 } | 145 } |
141 | 146 |
142 | 147 |
143 // Access growable object array at specified index. | 148 // Access growable object array at specified index. |
144 // On stack: growable array (+2), index (+1), return-address (+0). | 149 // On stack: growable array (+2), index (+1), return-address (+0). |
145 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) { | 150 void Intrinsifier::GrowableArrayGetIndexed(Assembler* assembler) { |
146 Label fall_through; | 151 Label fall_through; |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 __ Bind(&done); \ | 326 __ Bind(&done); \ |
322 \ | 327 \ |
323 /* Get the class index and insert it into the tags. */ \ | 328 /* Get the class index and insert it into the tags. */ \ |
324 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cid))); \ | 329 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cid))); \ |
325 __ movl(FieldAddress(EAX, type_name::tags_offset()), EDI); /* Tags. */ \ | 330 __ movl(FieldAddress(EAX, type_name::tags_offset()), EDI); /* Tags. */ \ |
326 } \ | 331 } \ |
327 /* Set the length field. */ \ | 332 /* Set the length field. */ \ |
328 /* EAX: new object start as a tagged pointer. */ \ | 333 /* EAX: new object start as a tagged pointer. */ \ |
329 /* EBX: new object end address. */ \ | 334 /* EBX: new object end address. */ \ |
330 __ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */ \ | 335 __ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */ \ |
331 __ StoreIntoObjectNoBarrier(EAX, \ | 336 __ InitializeFieldNoBarrier(EAX, \ |
332 FieldAddress(EAX, type_name::length_offset()), \ | 337 FieldAddress(EAX, type_name::length_offset()), \ |
333 EDI); \ | 338 EDI); \ |
334 /* Initialize all array elements to 0. */ \ | 339 /* Initialize all array elements to 0. */ \ |
335 /* EAX: new object start as a tagged pointer. */ \ | 340 /* EAX: new object start as a tagged pointer. */ \ |
336 /* EBX: new object end address. */ \ | 341 /* EBX: new object end address. */ \ |
337 /* EDI: iterator which initially points to the start of the variable */ \ | 342 /* EDI: iterator which initially points to the start of the variable */ \ |
338 /* ECX: scratch register. */ \ | 343 /* ECX: scratch register. */ \ |
339 /* data area to be initialized. */ \ | 344 /* data area to be initialized. */ \ |
340 __ xorl(ECX, ECX); /* Zero. */ \ | 345 __ xorl(ECX, ECX); /* Zero. */ \ |
341 __ leal(EDI, FieldAddress(EAX, sizeof(Raw##type_name))); \ | 346 __ leal(EDI, FieldAddress(EAX, sizeof(Raw##type_name))); \ |
(...skipping 1519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1861 | 1866 |
1862 Isolate* isolate = Isolate::Current(); | 1867 Isolate* isolate = Isolate::Current(); |
1863 Heap* heap = isolate->heap(); | 1868 Heap* heap = isolate->heap(); |
1864 const intptr_t cid = kOneByteStringCid; | 1869 const intptr_t cid = kOneByteStringCid; |
1865 Heap::Space space = heap->SpaceForAllocation(cid); | 1870 Heap::Space space = heap->SpaceForAllocation(cid); |
1866 __ movl(EAX, Address::Absolute(heap->TopAddress(space))); | 1871 __ movl(EAX, Address::Absolute(heap->TopAddress(space))); |
1867 __ movl(EBX, EAX); | 1872 __ movl(EBX, EAX); |
1868 | 1873 |
1869 // EDI: allocation size. | 1874 // EDI: allocation size. |
1870 __ addl(EBX, EDI); | 1875 __ addl(EBX, EDI); |
1871 __ j(CARRY, &pop_and_fail, Assembler::kNearJump); | 1876 __ j(CARRY, &pop_and_fail); |
1872 | 1877 |
1873 // Check if the allocation fits into the remaining space. | 1878 // Check if the allocation fits into the remaining space. |
1874 // EAX: potential new object start. | 1879 // EAX: potential new object start. |
1875 // EBX: potential next object start. | 1880 // EBX: potential next object start. |
1876 // EDI: allocation size. | 1881 // EDI: allocation size. |
1877 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space))); | 1882 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space))); |
1878 __ j(ABOVE_EQUAL, &pop_and_fail, Assembler::kNearJump); | 1883 __ j(ABOVE_EQUAL, &pop_and_fail); |
1879 | 1884 |
1880 // Successfully allocated the object(s), now update top to point to | 1885 // Successfully allocated the object(s), now update top to point to |
1881 // next object start and initialize the object. | 1886 // next object start and initialize the object. |
1882 __ movl(Address::Absolute(heap->TopAddress(space)), EBX); | 1887 __ movl(Address::Absolute(heap->TopAddress(space)), EBX); |
1883 __ addl(EAX, Immediate(kHeapObjectTag)); | 1888 __ addl(EAX, Immediate(kHeapObjectTag)); |
1884 | 1889 |
1885 __ UpdateAllocationStatsWithSize(cid, EDI, kNoRegister, space); | 1890 __ UpdateAllocationStatsWithSize(cid, EDI, kNoRegister, space); |
1886 | 1891 |
1887 // Initialize the tags. | 1892 // Initialize the tags. |
1888 // EAX: new object start as a tagged pointer. | 1893 // EAX: new object start as a tagged pointer. |
(...skipping 10 matching lines...) Expand all Loading... |
1899 __ xorl(EDI, EDI); | 1904 __ xorl(EDI, EDI); |
1900 __ Bind(&done); | 1905 __ Bind(&done); |
1901 | 1906 |
1902 // Get the class index and insert it into the tags. | 1907 // Get the class index and insert it into the tags. |
1903 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cid))); | 1908 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cid))); |
1904 __ movl(FieldAddress(EAX, String::tags_offset()), EDI); // Tags. | 1909 __ movl(FieldAddress(EAX, String::tags_offset()), EDI); // Tags. |
1905 } | 1910 } |
1906 | 1911 |
1907 // Set the length field. | 1912 // Set the length field. |
1908 __ popl(EDI); | 1913 __ popl(EDI); |
1909 __ StoreIntoObjectNoBarrier(EAX, | 1914 __ InitializeFieldNoBarrier(EAX, |
1910 FieldAddress(EAX, String::length_offset()), | 1915 FieldAddress(EAX, String::length_offset()), |
1911 EDI); | 1916 EDI); |
1912 // Clear hash. | 1917 // Clear hash. |
1913 __ ZeroSmiField(FieldAddress(EAX, String::hash_offset())); | 1918 __ ZeroInitSmiField(FieldAddress(EAX, String::hash_offset())); |
1914 __ jmp(ok, Assembler::kNearJump); | 1919 __ jmp(ok, Assembler::kNearJump); |
1915 | 1920 |
1916 __ Bind(&pop_and_fail); | 1921 __ Bind(&pop_and_fail); |
1917 __ popl(EDI); | 1922 __ popl(EDI); |
1918 __ jmp(failure); | 1923 __ jmp(failure); |
1919 } | 1924 } |
1920 | 1925 |
1921 | 1926 |
1922 // Arg0: OneByteString (receiver) | 1927 // Arg0: OneByteString (receiver) |
1923 // Arg1: Start index as Smi. | 1928 // Arg1: Start index as Smi. |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2135 Isolate::current_tag_offset()); | 2140 Isolate::current_tag_offset()); |
2136 // Set return value to Isolate::current_tag_. | 2141 // Set return value to Isolate::current_tag_. |
2137 __ movl(EAX, current_tag_addr); | 2142 __ movl(EAX, current_tag_addr); |
2138 __ ret(); | 2143 __ ret(); |
2139 } | 2144 } |
2140 | 2145 |
2141 #undef __ | 2146 #undef __ |
2142 } // namespace dart | 2147 } // namespace dart |
2143 | 2148 |
2144 #endif // defined TARGET_ARCH_IA32 | 2149 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |