OLD | NEW |
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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
154 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. | 154 __ movl(EBX, Address(ESP, + 1 * kWordSize)); // Index. |
155 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. | 155 __ movl(EAX, Address(ESP, + 2 * kWordSize)); // Array. |
156 __ testl(EBX, Immediate(kSmiTagMask)); | 156 __ testl(EBX, Immediate(kSmiTagMask)); |
157 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 157 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
158 // Range check. | 158 // Range check. |
159 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); | 159 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); |
160 // Runtime throws exception. | 160 // Runtime throws exception. |
161 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 161 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
162 // Note that EBX is Smi, i.e, times 2. | 162 // Note that EBX is Smi, i.e, times 2. |
163 ASSERT(kSmiTagShift == 1); | 163 ASSERT(kSmiTagShift == 1); |
164 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray))); | 164 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset())); |
165 __ ret(); | 165 __ ret(); |
166 __ Bind(&fall_through); | 166 __ Bind(&fall_through); |
167 return false; | 167 return false; |
168 } | 168 } |
169 | 169 |
170 | 170 |
171 bool Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) { | 171 bool Intrinsifier::ImmutableArray_getIndexed(Assembler* assembler) { |
172 return Array_getIndexed(assembler); | 172 return Array_getIndexed(assembler); |
173 } | 173 } |
174 | 174 |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
231 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // Array. | 231 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // Array. |
232 // Range check. | 232 // Range check. |
233 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); | 233 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); |
234 // Runtime throws exception. | 234 // Runtime throws exception. |
235 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 235 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
236 // Note that EBX is Smi, i.e, times 2. | 236 // Note that EBX is Smi, i.e, times 2. |
237 ASSERT(kSmiTagShift == 1); | 237 ASSERT(kSmiTagShift == 1); |
238 // Destroy ECX as we will not continue in the function. | 238 // Destroy ECX as we will not continue in the function. |
239 __ movl(ECX, Address(ESP, + 1 * kWordSize)); // Value. | 239 __ movl(ECX, Address(ESP, + 1 * kWordSize)); // Value. |
240 __ StoreIntoObject(EAX, | 240 __ StoreIntoObject(EAX, |
241 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)), | 241 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()), |
242 ECX); | 242 ECX); |
243 // Caller is responsible of preserving the value if necessary. | 243 // Caller is responsible of preserving the value if necessary. |
244 __ ret(); | 244 __ ret(); |
245 __ Bind(&fall_through); | 245 __ Bind(&fall_through); |
246 return false; | 246 return false; |
247 } | 247 } |
248 | 248 |
249 | 249 |
250 // Allocate a GrowableObjectArray using the backing array specified. | 250 // Allocate a GrowableObjectArray using the backing array specified. |
251 // On stack: type argument (+2), data (+1), return-address (+0). | 251 // On stack: type argument (+2), data (+1), return-address (+0). |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
343 __ testl(EBX, Immediate(kSmiTagMask)); | 343 __ testl(EBX, Immediate(kSmiTagMask)); |
344 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 344 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
345 // Range check using _length field. | 345 // Range check using _length field. |
346 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); | 346 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); |
347 // Runtime throws exception. | 347 // Runtime throws exception. |
348 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 348 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
349 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. | 349 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. |
350 | 350 |
351 // Note that EBX is Smi, i.e, times 2. | 351 // Note that EBX is Smi, i.e, times 2. |
352 ASSERT(kSmiTagShift == 1); | 352 ASSERT(kSmiTagShift == 1); |
353 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray))); | 353 __ movl(EAX, FieldAddress(EAX, EBX, TIMES_2, Array::data_offset())); |
354 __ ret(); | 354 __ ret(); |
355 __ Bind(&fall_through); | 355 __ Bind(&fall_through); |
356 return false; | 356 return false; |
357 } | 357 } |
358 | 358 |
359 | 359 |
360 // Set value into growable object array at specified index. | 360 // Set value into growable object array at specified index. |
361 // On stack: growable array (+3), index (+2), value (+1), return-address (+0). | 361 // On stack: growable array (+3), index (+2), value (+1), return-address (+0). |
362 bool Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) { | 362 bool Intrinsifier::GrowableArray_setIndexed(Assembler* assembler) { |
363 if (FLAG_enable_type_checks) { | 363 if (FLAG_enable_type_checks) { |
364 return false; | 364 return false; |
365 } | 365 } |
366 Label fall_through; | 366 Label fall_through; |
367 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. | 367 __ movl(EBX, Address(ESP, + 2 * kWordSize)); // Index. |
368 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray. | 368 __ movl(EAX, Address(ESP, + 3 * kWordSize)); // GrowableArray. |
369 __ testl(EBX, Immediate(kSmiTagMask)); | 369 __ testl(EBX, Immediate(kSmiTagMask)); |
370 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. | 370 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi index. |
371 // Range check using _length field. | 371 // Range check using _length field. |
372 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); | 372 __ cmpl(EBX, FieldAddress(EAX, GrowableObjectArray::length_offset())); |
373 // Runtime throws exception. | 373 // Runtime throws exception. |
374 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); | 374 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump); |
375 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. | 375 __ movl(EAX, FieldAddress(EAX, GrowableObjectArray::data_offset())); // data. |
376 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value. | 376 __ movl(EDI, Address(ESP, + 1 * kWordSize)); // Value. |
377 // Note that EBX is Smi, i.e, times 2. | 377 // Note that EBX is Smi, i.e, times 2. |
378 ASSERT(kSmiTagShift == 1); | 378 ASSERT(kSmiTagShift == 1); |
379 __ StoreIntoObject(EAX, | 379 __ StoreIntoObject(EAX, |
380 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)), | 380 FieldAddress(EAX, EBX, TIMES_2, Array::data_offset()), |
381 EDI); | 381 EDI); |
382 __ ret(); | 382 __ ret(); |
383 __ Bind(&fall_through); | 383 __ Bind(&fall_through); |
384 return false; | 384 return false; |
385 } | 385 } |
386 | 386 |
387 | 387 |
388 // Set length of growable object array. | 388 // Set length of growable object array. |
389 // On stack: growable array (+2), length (+1), return-address (+0). | 389 // On stack: growable array (+2), length (+1), return-address (+0). |
390 bool Intrinsifier::GrowableArray_setLength(Assembler* assembler) { | 390 bool Intrinsifier::GrowableArray_setLength(Assembler* assembler) { |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
440 // EDI: data. | 440 // EDI: data. |
441 // Compare length with capacity. | 441 // Compare length with capacity. |
442 __ cmpl(EBX, FieldAddress(EDI, Array::length_offset())); | 442 __ cmpl(EBX, FieldAddress(EDI, Array::length_offset())); |
443 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Must grow data. | 443 __ j(EQUAL, &fall_through, Assembler::kNearJump); // Must grow data. |
444 const Immediate value_one = Immediate(reinterpret_cast<int32_t>(Smi::New(1))); | 444 const Immediate value_one = Immediate(reinterpret_cast<int32_t>(Smi::New(1))); |
445 // len = len + 1; | 445 // len = len + 1; |
446 __ addl(FieldAddress(EAX, GrowableObjectArray::length_offset()), value_one); | 446 __ addl(FieldAddress(EAX, GrowableObjectArray::length_offset()), value_one); |
447 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Value | 447 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Value |
448 ASSERT(kSmiTagShift == 1); | 448 ASSERT(kSmiTagShift == 1); |
449 __ StoreIntoObject(EDI, | 449 __ StoreIntoObject(EDI, |
450 FieldAddress(EDI, EBX, TIMES_2, sizeof(RawArray)), | 450 FieldAddress(EDI, EBX, TIMES_2, Array::data_offset()), |
451 EAX); | 451 EAX); |
452 const Immediate raw_null = | 452 const Immediate raw_null = |
453 Immediate(reinterpret_cast<int32_t>(Object::null())); | 453 Immediate(reinterpret_cast<int32_t>(Object::null())); |
454 __ movl(EAX, raw_null); | 454 __ movl(EAX, raw_null); |
455 __ ret(); | 455 __ ret(); |
456 __ Bind(&fall_through); | 456 __ Bind(&fall_through); |
457 return false; | 457 return false; |
458 } | 458 } |
459 | 459 |
460 | 460 |
(...skipping 1211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1672 __ Bind(&is_true); | 1672 __ Bind(&is_true); |
1673 __ LoadObject(EAX, Bool::True()); | 1673 __ LoadObject(EAX, Bool::True()); |
1674 __ ret(); | 1674 __ ret(); |
1675 return true; | 1675 return true; |
1676 } | 1676 } |
1677 | 1677 |
1678 #undef __ | 1678 #undef __ |
1679 } // namespace dart | 1679 } // namespace dart |
1680 | 1680 |
1681 #endif // defined TARGET_ARCH_IA32 | 1681 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |