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