Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: runtime/vm/intrinsifier_ia32.cc

Issue 1263513002: VM: Load allocation-top and -end via Thread. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: fixed cc tests Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 Immediate(reinterpret_cast<int32_t>(Object::null())); 179 Immediate(reinterpret_cast<int32_t>(Object::null()));
180 __ movl(EAX, raw_null); 180 __ movl(EAX, raw_null);
181 __ ret(); 181 __ ret();
182 __ Bind(&fall_through); 182 __ Bind(&fall_through);
183 } 183 }
184 184
185 185
186 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_factor) \ 186 #define TYPED_ARRAY_ALLOCATION(type_name, cid, max_len, scale_factor) \
187 Label fall_through; \ 187 Label fall_through; \
188 const intptr_t kArrayLengthStackOffset = 1 * kWordSize; \ 188 const intptr_t kArrayLengthStackOffset = 1 * kWordSize; \
189 __ MaybeTraceAllocation(cid, EDI, &fall_through, false); \ 189 __ MaybeTraceAllocation(cid, EDI, &fall_through, false, \
190 /* inline_isolate = */ false); \
190 __ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */ \ 191 __ movl(EDI, Address(ESP, kArrayLengthStackOffset)); /* Array length. */ \
191 /* Check that length is a positive Smi. */ \ 192 /* Check that length is a positive Smi. */ \
192 /* EDI: requested array length argument. */ \ 193 /* EDI: requested array length argument. */ \
193 __ testl(EDI, Immediate(kSmiTagMask)); \ 194 __ testl(EDI, Immediate(kSmiTagMask)); \
194 __ j(NOT_ZERO, &fall_through); \ 195 __ j(NOT_ZERO, &fall_through); \
195 __ cmpl(EDI, Immediate(0)); \ 196 __ cmpl(EDI, Immediate(0)); \
196 __ j(LESS, &fall_through); \ 197 __ j(LESS, &fall_through); \
197 __ SmiUntag(EDI); \ 198 __ SmiUntag(EDI); \
198 /* Check for maximum allowed length. */ \ 199 /* Check for maximum allowed length. */ \
199 /* EDI: untagged array length. */ \ 200 /* EDI: untagged array length. */ \
200 __ cmpl(EDI, Immediate(max_len)); \ 201 __ cmpl(EDI, Immediate(max_len)); \
201 __ j(GREATER, &fall_through); \ 202 __ j(GREATER, &fall_through); \
202 /* Special case for scaling by 16. */ \ 203 /* Special case for scaling by 16. */ \
203 if (scale_factor == TIMES_16) { \ 204 if (scale_factor == TIMES_16) { \
204 /* double length of array. */ \ 205 /* double length of array. */ \
205 __ addl(EDI, EDI); \ 206 __ addl(EDI, EDI); \
206 /* only scale by 8. */ \ 207 /* only scale by 8. */ \
207 scale_factor = TIMES_8; \ 208 scale_factor = TIMES_8; \
208 } \ 209 } \
209 const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \ 210 const intptr_t fixed_size = sizeof(Raw##type_name) + kObjectAlignment - 1; \
210 __ leal(EDI, Address(EDI, scale_factor, fixed_size)); \ 211 __ leal(EDI, Address(EDI, scale_factor, fixed_size)); \
211 __ andl(EDI, Immediate(-kObjectAlignment)); \ 212 __ andl(EDI, Immediate(-kObjectAlignment)); \
212 Heap* heap = Isolate::Current()->heap(); \ 213 Heap::Space space = Heap::SpaceForAllocation(cid); \
213 Heap::Space space = heap->SpaceForAllocation(cid); \ 214 __ movl(ECX, Address(THR, Thread::heap_offset())); \
214 __ movl(EAX, Address::Absolute(heap->TopAddress(space))); \ 215 __ movl(EAX, Address(ECX, Heap::TopOffset(space))); \
215 __ movl(EBX, EAX); \ 216 __ movl(EBX, EAX); \
216 \ 217 \
217 /* EDI: allocation size. */ \ 218 /* EDI: allocation size. */ \
218 __ addl(EBX, EDI); \ 219 __ addl(EBX, EDI); \
219 __ j(CARRY, &fall_through); \ 220 __ j(CARRY, &fall_through); \
220 \ 221 \
221 /* Check if the allocation fits into the remaining space. */ \ 222 /* Check if the allocation fits into the remaining space. */ \
222 /* EAX: potential new object start. */ \ 223 /* EAX: potential new object start. */ \
223 /* EBX: potential next object start. */ \ 224 /* EBX: potential next object start. */ \
224 /* EDI: allocation size. */ \ 225 /* EDI: allocation size. */ \
225 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space))); \ 226 /* ECX: heap. */ \
227 __ cmpl(EBX, Address(ECX, Heap::EndOffset(space))); \
226 __ j(ABOVE_EQUAL, &fall_through); \ 228 __ j(ABOVE_EQUAL, &fall_through); \
227 \ 229 \
228 /* Successfully allocated the object(s), now update top to point to */ \ 230 /* Successfully allocated the object(s), now update top to point to */ \
229 /* next object start and initialize the object. */ \ 231 /* next object start and initialize the object. */ \
230 __ movl(Address::Absolute(heap->TopAddress(space)), EBX); \ 232 __ movl(Address(ECX, Heap::TopOffset(space)), EBX); \
231 __ addl(EAX, Immediate(kHeapObjectTag)); \ 233 __ addl(EAX, Immediate(kHeapObjectTag)); \
232 __ UpdateAllocationStatsWithSize(cid, EDI, kNoRegister, space); \ 234 __ UpdateAllocationStatsWithSize(cid, EDI, ECX, space, \
235 /* inline_isolate = */ false); \
233 \ 236 \
234 /* Initialize the tags. */ \ 237 /* Initialize the tags. */ \
235 /* EAX: new object start as a tagged pointer. */ \ 238 /* EAX: new object start as a tagged pointer. */ \
236 /* EBX: new object end address. */ \ 239 /* EBX: new object end address. */ \
237 /* EDI: allocation size. */ \ 240 /* EDI: allocation size. */ \
238 { \ 241 { \
239 Label size_tag_overflow, done; \ 242 Label size_tag_overflow, done; \
240 __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); \ 243 __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); \
241 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); \ 244 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); \
242 __ shll(EDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); \ 245 __ shll(EDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); \
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 __ shll(EBX, ECX); 584 __ shll(EBX, ECX);
582 __ xorl(EDI, EDI); 585 __ xorl(EDI, EDI);
583 __ shldl(EDI, EAX, ECX); 586 __ shldl(EDI, EAX, ECX);
584 // Result in EDI (high) and EBX (low). 587 // Result in EDI (high) and EBX (low).
585 const Class& mint_class = Class::Handle( 588 const Class& mint_class = Class::Handle(
586 Isolate::Current()->object_store()->mint_class()); 589 Isolate::Current()->object_store()->mint_class());
587 __ TryAllocate(mint_class, 590 __ TryAllocate(mint_class,
588 &fall_through, 591 &fall_through,
589 Assembler::kNearJump, 592 Assembler::kNearJump,
590 EAX, // Result register. 593 EAX, // Result register.
591 kNoRegister); 594 ECX); // temp
592 // EBX and EDI are not objects but integer values. 595 // EBX and EDI are not objects but integer values.
593 __ movl(FieldAddress(EAX, Mint::value_offset()), EBX); 596 __ movl(FieldAddress(EAX, Mint::value_offset()), EBX);
594 __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI); 597 __ movl(FieldAddress(EAX, Mint::value_offset() + kWordSize), EDI);
595 __ ret(); 598 __ ret();
596 __ Bind(&fall_through); 599 __ Bind(&fall_through);
597 } 600 }
598 601
599 602
600 static void Push64SmiOrMint(Assembler* assembler, 603 static void Push64SmiOrMint(Assembler* assembler,
601 Register reg, 604 Register reg,
(...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after
1862 } 1865 }
1863 1866
1864 1867
1865 // Allocates one-byte string of length 'end - start'. The content is not 1868 // Allocates one-byte string of length 'end - start'. The content is not
1866 // initialized. 'length-reg' contains tagged length. 1869 // initialized. 'length-reg' contains tagged length.
1867 // Returns new string as tagged pointer in EAX. 1870 // Returns new string as tagged pointer in EAX.
1868 static void TryAllocateOnebyteString(Assembler* assembler, 1871 static void TryAllocateOnebyteString(Assembler* assembler,
1869 Label* ok, 1872 Label* ok,
1870 Label* failure, 1873 Label* failure,
1871 Register length_reg) { 1874 Register length_reg) {
1872 __ MaybeTraceAllocation(kOneByteStringCid, EAX, failure, false); 1875 __ MaybeTraceAllocation(kOneByteStringCid, EAX, failure, false,
1876 /* inline_isolate = */ false);
1873 if (length_reg != EDI) { 1877 if (length_reg != EDI) {
1874 __ movl(EDI, length_reg); 1878 __ movl(EDI, length_reg);
1875 } 1879 }
1876 Label pop_and_fail; 1880 Label pop_and_fail;
1877 __ pushl(EDI); // Preserve length. 1881 __ pushl(EDI); // Preserve length.
1878 __ SmiUntag(EDI); 1882 __ SmiUntag(EDI);
1879 const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1; 1883 const intptr_t fixed_size = sizeof(RawString) + kObjectAlignment - 1;
1880 __ leal(EDI, Address(EDI, TIMES_1, fixed_size)); // EDI is untagged. 1884 __ leal(EDI, Address(EDI, TIMES_1, fixed_size)); // EDI is untagged.
1881 __ andl(EDI, Immediate(-kObjectAlignment)); 1885 __ andl(EDI, Immediate(-kObjectAlignment));
1882 1886
1883 Isolate* isolate = Isolate::Current();
1884 Heap* heap = isolate->heap();
1885 const intptr_t cid = kOneByteStringCid; 1887 const intptr_t cid = kOneByteStringCid;
1886 Heap::Space space = heap->SpaceForAllocation(cid); 1888 Heap::Space space = Heap::SpaceForAllocation(cid);
1887 __ movl(EAX, Address::Absolute(heap->TopAddress(space))); 1889 __ movl(ECX, Address(THR, Thread::heap_offset()));
1890 __ movl(EAX, Address(ECX, Heap::TopOffset(space)));
1888 __ movl(EBX, EAX); 1891 __ movl(EBX, EAX);
1889 1892
1890 // EDI: allocation size. 1893 // EDI: allocation size.
1891 __ addl(EBX, EDI); 1894 __ addl(EBX, EDI);
1892 __ j(CARRY, &pop_and_fail); 1895 __ j(CARRY, &pop_and_fail);
1893 1896
1894 // Check if the allocation fits into the remaining space. 1897 // Check if the allocation fits into the remaining space.
1895 // EAX: potential new object start. 1898 // EAX: potential new object start.
1896 // EBX: potential next object start. 1899 // EBX: potential next object start.
1897 // EDI: allocation size. 1900 // EDI: allocation size.
1898 __ cmpl(EBX, Address::Absolute(heap->EndAddress(space))); 1901 // ECX: heap.
1902 __ cmpl(EBX, Address(ECX, Heap::EndOffset(space)));
1899 __ j(ABOVE_EQUAL, &pop_and_fail); 1903 __ j(ABOVE_EQUAL, &pop_and_fail);
1900 1904
1901 // Successfully allocated the object(s), now update top to point to 1905 // Successfully allocated the object(s), now update top to point to
1902 // next object start and initialize the object. 1906 // next object start and initialize the object.
1903 __ movl(Address::Absolute(heap->TopAddress(space)), EBX); 1907 __ movl(Address(ECX, Heap::TopOffset(space)), EBX);
1904 __ addl(EAX, Immediate(kHeapObjectTag)); 1908 __ addl(EAX, Immediate(kHeapObjectTag));
1905 1909
1906 __ UpdateAllocationStatsWithSize(cid, EDI, kNoRegister, space); 1910 __ UpdateAllocationStatsWithSize(cid, EDI, ECX, space,
1911 /* inline_isolate = */ false);
1907 1912
1908 // Initialize the tags. 1913 // Initialize the tags.
1909 // EAX: new object start as a tagged pointer. 1914 // EAX: new object start as a tagged pointer.
1910 // EBX: new object end address. 1915 // EBX: new object end address.
1911 // EDI: allocation size. 1916 // EDI: allocation size.
1912 { 1917 {
1913 Label size_tag_overflow, done; 1918 Label size_tag_overflow, done;
1914 __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag)); 1919 __ cmpl(EDI, Immediate(RawObject::SizeTag::kMaxSizeTag));
1915 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); 1920 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
1916 __ shll(EDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2)); 1921 __ shll(EDI, Immediate(RawObject::kSizeTagPos - kObjectAlignmentLog2));
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
2142 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) { 2147 void Intrinsifier::Profiler_getCurrentTag(Assembler* assembler) {
2143 __ LoadIsolate(EAX); 2148 __ LoadIsolate(EAX);
2144 __ movl(EAX, Address(EAX, Isolate::current_tag_offset())); 2149 __ movl(EAX, Address(EAX, Isolate::current_tag_offset()));
2145 __ ret(); 2150 __ ret();
2146 } 2151 }
2147 2152
2148 #undef __ 2153 #undef __
2149 } // namespace dart 2154 } // namespace dart
2150 2155
2151 #endif // defined TARGET_ARCH_IA32 2156 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698