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

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

Issue 10536067: Generate code for store buffer updates in open-coded object field stores. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: correct handling of null Created 8 years, 6 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/stub_code_ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 23 matching lines...) Expand all
34 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; 34 const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
35 const intptr_t kArrayLengthOffset = 1 * kWordSize; 35 const intptr_t kArrayLengthOffset = 1 * kWordSize;
36 Label fall_through; 36 Label fall_through;
37 37
38 // Compute the size to be allocated, it is based on the array length 38 // Compute the size to be allocated, it is based on the array length
39 // and it computed as: 39 // and it computed as:
40 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). 40 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
41 __ movl(EDI, Address(ESP, kArrayLengthOffset)); // Array Length. 41 __ movl(EDI, Address(ESP, kArrayLengthOffset)); // Array Length.
42 // Assert that length is a Smi. 42 // Assert that length is a Smi.
43 __ testl(EDI, Immediate(kSmiTagSize)); 43 __ testl(EDI, Immediate(kSmiTagSize));
44 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); 44 __ j(NOT_ZERO, &fall_through);
45 __ cmpl(EDI, Immediate(0)); 45 __ cmpl(EDI, Immediate(0));
46 __ j(LESS, &fall_through, Assembler::kNearJump); 46 __ j(LESS, &fall_through);
47 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1; 47 intptr_t fixed_size = sizeof(RawArray) + kObjectAlignment - 1;
48 __ leal(EDI, Address(EDI, TIMES_2, fixed_size)); // EDI is a Smi. 48 __ leal(EDI, Address(EDI, TIMES_2, fixed_size)); // EDI is a Smi.
49 ASSERT(kSmiTagShift == 1); 49 ASSERT(kSmiTagShift == 1);
50 __ andl(EDI, Immediate(-kObjectAlignment)); 50 __ andl(EDI, Immediate(-kObjectAlignment));
51 51
52 Isolate* isolate = Isolate::Current(); 52 Isolate* isolate = Isolate::Current();
53 Heap* heap = isolate->heap(); 53 Heap* heap = isolate->heap();
54 54
55 // EDI: allocation size. 55 // EDI: allocation size.
56 __ movl(EAX, Address::Absolute(heap->TopAddress())); 56 __ movl(EAX, Address::Absolute(heap->TopAddress()));
57 __ leal(EBX, Address(EAX, EDI, TIMES_1, 0)); 57 __ leal(EBX, Address(EAX, EDI, TIMES_1, 0));
58 58
59 // Check if the allocation fits into the remaining space. 59 // Check if the allocation fits into the remaining space.
60 // EAX: potential new object start. 60 // EAX: potential new object start.
61 // EBX: potential next object start. 61 // EBX: potential next object start.
62 // EDI: allocation size. 62 // EDI: allocation size.
63 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); 63 __ cmpl(EBX, Address::Absolute(heap->EndAddress()));
64 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 64 __ j(ABOVE_EQUAL, &fall_through);
65 65
66 // Successfully allocated the object(s), now update top to point to 66 // Successfully allocated the object(s), now update top to point to
67 // next object start and initialize the object. 67 // next object start and initialize the object.
68 __ movl(Address::Absolute(heap->TopAddress()), EBX); 68 __ movl(Address::Absolute(heap->TopAddress()), EBX);
69 __ addl(EAX, Immediate(kHeapObjectTag)); 69 __ addl(EAX, Immediate(kHeapObjectTag));
70 70
71 // Initialize the tags. 71 // Initialize the tags.
72 // EAX: new object start as a tagged pointer. 72 // EAX: new object start as a tagged pointer.
73 // EBX: new object end address. 73 // EBX: new object end address.
74 // EDI: allocation size. 74 // EDI: allocation size.
(...skipping 11 matching lines...) Expand all
86 // Get the class index and insert it into the tags. 86 // Get the class index and insert it into the tags.
87 const Class& cls = Class::Handle(isolate->object_store()->array_class()); 87 const Class& cls = Class::Handle(isolate->object_store()->array_class());
88 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cls.id()))); 88 __ orl(EDI, Immediate(RawObject::ClassIdTag::encode(cls.id())));
89 __ movl(FieldAddress(EAX, Array::tags_offset()), EDI); // Tags. 89 __ movl(FieldAddress(EAX, Array::tags_offset()), EDI); // Tags.
90 } 90 }
91 91
92 // EAX: new object start as a tagged pointer. 92 // EAX: new object start as a tagged pointer.
93 // EBX: new object end address. 93 // EBX: new object end address.
94 // Store the type argument field. 94 // Store the type argument field.
95 __ movl(EDI, Address(ESP, kTypeArgumentsOffset)); // type argument. 95 __ movl(EDI, Address(ESP, kTypeArgumentsOffset)); // type argument.
96 __ StoreIntoObject(EAX, 96 __ StoreIntoObjectNoBarrier(EAX,
97 FieldAddress(EAX, Array::type_arguments_offset()), 97 FieldAddress(EAX, Array::type_arguments_offset()),
98 EDI); 98 EDI);
99 99
100 // Set the length field. 100 // Set the length field.
101 __ movl(EDI, Address(ESP, kArrayLengthOffset)); // Array Length. 101 __ movl(EDI, Address(ESP, kArrayLengthOffset)); // Array Length.
102 __ StoreIntoObject(EAX, FieldAddress(EAX, Array::length_offset()), EDI); 102 __ StoreIntoObjectNoBarrier(EAX,
103 FieldAddress(EAX, Array::length_offset()),
104 EDI);
103 105
104 // Initialize all array elements to raw_null. 106 // Initialize all array elements to raw_null.
105 // EAX: new object start as a tagged pointer. 107 // EAX: new object start as a tagged pointer.
106 // EBX: new object end address. 108 // EBX: new object end address.
107 // EDI: iterator which initially points to the start of the variable 109 // EDI: iterator which initially points to the start of the variable
108 // data area to be initialized. 110 // data area to be initialized.
109 const Immediate raw_null = 111 const Immediate raw_null =
110 Immediate(reinterpret_cast<intptr_t>(Object::null())); 112 Immediate(reinterpret_cast<intptr_t>(Object::null()));
111 __ leal(EDI, FieldAddress(EAX, sizeof(RawArray))); 113 __ leal(EDI, FieldAddress(EAX, sizeof(RawArray)));
112 Label done; 114 Label done;
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 295
294 // Store backing array object in growable array object. 296 // Store backing array object in growable array object.
295 __ movl(EBX, Address(ESP, kArrayOffset)); // data argument. 297 __ movl(EBX, Address(ESP, kArrayOffset)); // data argument.
296 __ StoreIntoObject(EAX, 298 __ StoreIntoObject(EAX,
297 FieldAddress(EAX, GrowableObjectArray::data_offset()), 299 FieldAddress(EAX, GrowableObjectArray::data_offset()),
298 EBX); 300 EBX);
299 301
300 // EAX: new growable array object start as a tagged pointer. 302 // EAX: new growable array object start as a tagged pointer.
301 // Store the type argument field in the growable array object. 303 // Store the type argument field in the growable array object.
302 __ movl(EBX, Address(ESP, kTypeArgumentsOffset)); // type argument. 304 __ movl(EBX, Address(ESP, kTypeArgumentsOffset)); // type argument.
303 __ StoreIntoObject(EAX, 305 __ StoreIntoObjectNoBarrier(
304 FieldAddress(EAX, 306 EAX,
305 GrowableObjectArray::type_arguments_offset()), 307 FieldAddress(EAX, GrowableObjectArray::type_arguments_offset()),
306 EBX); 308 EBX);
307 309
308 // Set the length field in the growable array object to 0. 310 // Set the length field in the growable array object to 0.
309 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()), 311 __ movl(FieldAddress(EAX, GrowableObjectArray::length_offset()),
310 Immediate(0)); 312 Immediate(0));
311 __ ret(); // returns the newly allocated object in EAX. 313 __ ret(); // returns the newly allocated object in EAX.
312 314
313 __ Bind(&fall_through); 315 __ Bind(&fall_through);
314 return false; 316 return false;
315 } 317 }
316 318
(...skipping 931 matching lines...) Expand 10 before | Expand all | Expand 10 after
1248 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); // Range check. 1250 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); // Range check.
1249 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); 1251 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
1250 1252
1251 // EBX is Smi, i.e, times 2. 1253 // EBX is Smi, i.e, times 2.
1252 ASSERT(kSmiTagShift == 1); 1254 ASSERT(kSmiTagShift == 1);
1253 __ movl(EDI, FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray))); // Result. 1255 __ movl(EDI, FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray))); // Result.
1254 const Immediate value = Immediate(reinterpret_cast<int32_t>(Smi::New(1))); 1256 const Immediate value = Immediate(reinterpret_cast<int32_t>(Smi::New(1)));
1255 __ addl(EBX, value); // _pos++. 1257 __ addl(EBX, value); // _pos++.
1256 __ j(OVERFLOW, &fall_through, Assembler::kNearJump); 1258 __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
1257 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Receiver. 1259 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Receiver.
1258 __ StoreIntoObject(EAX, FieldAddress(EAX, pos_offset), EBX); // Store _pos. 1260 __ StoreIntoObjectNoBarrier(EAX,
1261 FieldAddress(EAX, pos_offset),
1262 EBX); // Store _pos.
1259 __ movl(EAX, EDI); 1263 __ movl(EAX, EDI);
1260 __ ret(); 1264 __ ret();
1261 __ Bind(&fall_through); 1265 __ Bind(&fall_through);
1262 return false; 1266 return false;
1263 } 1267 }
1264 1268
1265 1269
1266 // Class 'FixedSizeArrayIterator': 1270 // Class 'FixedSizeArrayIterator':
1267 // bool hasNext() { 1271 // bool hasNext() {
1268 // return _length > _pos; 1272 // return _length > _pos;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
1351 __ Bind(&is_true); 1355 __ Bind(&is_true);
1352 __ LoadObject(EAX, bool_true); 1356 __ LoadObject(EAX, bool_true);
1353 __ ret(); 1357 __ ret();
1354 return true; 1358 return true;
1355 } 1359 }
1356 1360
1357 #undef __ 1361 #undef __
1358 } // namespace dart 1362 } // namespace dart
1359 1363
1360 #endif // defined TARGET_ARCH_IA32 1364 #endif // defined TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « runtime/vm/code_generator_ia32.cc ('k') | runtime/vm/stub_code_ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698