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

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

Issue 11410086: Use iterator, moveNext(), current. (Closed) Base URL: https://dart.googlecode.com/svn/experimental/lib_v2/dart
Patch Set: Address comments. Created 8 years, 1 month 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
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 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
241 __ StoreIntoObject(EAX, 241 __ StoreIntoObject(EAX,
242 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)), 242 FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray)),
243 ECX); 243 ECX);
244 // Caller is responsible of preserving the value if necessary. 244 // Caller is responsible of preserving the value if necessary.
245 __ ret(); 245 __ ret();
246 __ Bind(&fall_through); 246 __ Bind(&fall_through);
247 return false; 247 return false;
248 } 248 }
249 249
250 250
251 static intptr_t GetOffsetForField(const char* class_name_p,
252 const char* field_name_p) {
253 const String& class_name = String::Handle(Symbols::New(class_name_p));
254 const String& field_name = String::Handle(Symbols::New(field_name_p));
255 const Library& core_lib = Library::Handle(Library::CoreLibrary());
256 const Class& cls =
257 Class::Handle(core_lib.LookupClassAllowPrivate(class_name));
258 ASSERT(!cls.IsNull());
259 const Field& field = Field::ZoneHandle(cls.LookupInstanceField(field_name));
260 ASSERT(!field.IsNull());
261 return field.Offset();
262 }
263
264
265 // Allocate a GrowableObjectArray using the backing array specified. 251 // Allocate a GrowableObjectArray using the backing array specified.
266 // On stack: type argument (+2), data (+1), return-address (+0). 252 // On stack: type argument (+2), data (+1), return-address (+0).
267 bool Intrinsifier::GArray_Allocate(Assembler* assembler) { 253 bool Intrinsifier::GArray_Allocate(Assembler* assembler) {
268 // This snippet of inlined code uses the following registers: 254 // This snippet of inlined code uses the following registers:
269 // EAX, EBX 255 // EAX, EBX
270 // and the newly allocated object is returned in EAX. 256 // and the newly allocated object is returned in EAX.
271 const intptr_t kTypeArgumentsOffset = 2 * kWordSize; 257 const intptr_t kTypeArgumentsOffset = 2 * kWordSize;
272 const intptr_t kArrayOffset = 1 * kWordSize; 258 const intptr_t kArrayOffset = 1 * kWordSize;
273 Label fall_through; 259 Label fall_through;
274 260
(...skipping 1304 matching lines...) Expand 10 before | Expand all | Expand 10 after
1579 __ cmpl(EAX, Address(ESP, + 2 * kWordSize)); 1565 __ cmpl(EAX, Address(ESP, + 2 * kWordSize));
1580 __ j(EQUAL, &is_true, Assembler::kNearJump); 1566 __ j(EQUAL, &is_true, Assembler::kNearJump);
1581 __ LoadObject(EAX, bool_false); 1567 __ LoadObject(EAX, bool_false);
1582 __ ret(); 1568 __ ret();
1583 __ Bind(&is_true); 1569 __ Bind(&is_true);
1584 __ LoadObject(EAX, bool_true); 1570 __ LoadObject(EAX, bool_true);
1585 __ ret(); 1571 __ ret();
1586 return true; 1572 return true;
1587 } 1573 }
1588 1574
1589
1590 static const char* kFixedSizeArrayIteratorClassName = "_FixedSizeArrayIterator";
1591
1592
1593 // Class 'FixedSizeArrayIterator':
1594 // T next() {
1595 // return _array[_pos++];
1596 // }
1597 // Intrinsify: return _array[_pos++];
1598 // TODO(srdjan): Throw a 'StateError' exception if the iterator
1599 // has no more elements.
1600 bool Intrinsifier::FixedSizeArrayIterator_next(Assembler* assembler) {
1601 Label fall_through;
1602 intptr_t array_offset =
1603 GetOffsetForField(kFixedSizeArrayIteratorClassName, "_array");
1604 intptr_t pos_offset =
1605 GetOffsetForField(kFixedSizeArrayIteratorClassName, "_pos");
1606 ASSERT(array_offset >= 0 && pos_offset >= 0);
1607 // Receiver is not NULL.
1608 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Receiver.
1609 __ movl(EBX, FieldAddress(EAX, pos_offset)); // Field _pos.
1610 // '_pos' cannot be greater than array length and therefore is always Smi.
1611 #if defined(DEBUG)
1612 Label pos_ok;
1613 __ testl(EBX, Immediate(kSmiTagMask));
1614 __ j(ZERO, &pos_ok, Assembler::kNearJump);
1615 __ Stop("pos must be Smi");
1616 __ Bind(&pos_ok);
1617 #endif
1618 // Check that we are not trying to call 'next' when 'hasNext' is false.
1619 __ movl(EAX, FieldAddress(EAX, array_offset)); // Field _array.
1620 __ cmpl(EBX, FieldAddress(EAX, Array::length_offset())); // Range check.
1621 __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
1622
1623 // EBX is Smi, i.e, times 2.
1624 ASSERT(kSmiTagShift == 1);
1625 __ movl(EDI, FieldAddress(EAX, EBX, TIMES_2, sizeof(RawArray))); // Result.
1626 const Immediate value = Immediate(reinterpret_cast<int32_t>(Smi::New(1)));
1627 __ addl(EBX, value); // _pos++.
1628 __ j(OVERFLOW, &fall_through, Assembler::kNearJump);
1629 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Receiver.
1630 __ StoreIntoObjectNoBarrier(EAX,
1631 FieldAddress(EAX, pos_offset),
1632 EBX); // Store _pos.
1633 __ movl(EAX, EDI);
1634 __ ret();
1635 __ Bind(&fall_through);
1636 return false;
1637 }
1638
1639
1640 // Class 'FixedSizeArrayIterator':
1641 // bool get hasNext {
1642 // return _length > _pos;
1643 // }
1644 bool Intrinsifier::FixedSizeArrayIterator_getHasNext(Assembler* assembler) {
1645 Label fall_through, is_true;
1646 const Bool& bool_true = Bool::ZoneHandle(Bool::True());
1647 const Bool& bool_false = Bool::ZoneHandle(Bool::False());
1648 intptr_t length_offset =
1649 GetOffsetForField(kFixedSizeArrayIteratorClassName, "_length");
1650 intptr_t pos_offset =
1651 GetOffsetForField(kFixedSizeArrayIteratorClassName, "_pos");
1652 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // Receiver.
1653 __ movl(EBX, FieldAddress(EAX, length_offset)); // Field _length.
1654 __ movl(EAX, FieldAddress(EAX, pos_offset)); // Field _pos.
1655 __ movl(EDI, EAX);
1656 __ orl(EDI, EBX);
1657 __ testl(EDI, Immediate(kSmiTagMask));
1658 __ j(NOT_ZERO, &fall_through, Assembler::kNearJump); // Non-smi _length.
1659 __ cmpl(EBX, EAX); // _length > _pos.
1660 __ j(GREATER, &is_true, Assembler::kNearJump);
1661 __ LoadObject(EAX, bool_false);
1662 __ ret();
1663 __ Bind(&is_true);
1664 __ LoadObject(EAX, bool_true);
1665 __ ret();
1666 __ Bind(&fall_through);
1667 return false;
1668 }
1669
1670
1671 bool Intrinsifier::String_getHashCode(Assembler* assembler) { 1575 bool Intrinsifier::String_getHashCode(Assembler* assembler) {
1672 Label fall_through; 1576 Label fall_through;
1673 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object. 1577 __ movl(EAX, Address(ESP, + 1 * kWordSize)); // String object.
1674 __ movl(EAX, FieldAddress(EAX, String::hash_offset())); 1578 __ movl(EAX, FieldAddress(EAX, String::hash_offset()));
1675 __ cmpl(EAX, Immediate(0)); 1579 __ cmpl(EAX, Immediate(0));
1676 __ j(EQUAL, &fall_through, Assembler::kNearJump); 1580 __ j(EQUAL, &fall_through, Assembler::kNearJump);
1677 __ ret(); 1581 __ ret();
1678 __ Bind(&fall_through); 1582 __ Bind(&fall_through);
1679 // Hash not yet computed. 1583 // Hash not yet computed.
1680 return false; 1584 return false;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
1725 __ Bind(&is_true); 1629 __ Bind(&is_true);
1726 __ LoadObject(EAX, bool_true); 1630 __ LoadObject(EAX, bool_true);
1727 __ ret(); 1631 __ ret();
1728 return true; 1632 return true;
1729 } 1633 }
1730 1634
1731 #undef __ 1635 #undef __
1732 } // namespace dart 1636 } // namespace dart
1733 1637
1734 #endif // defined TARGET_ARCH_IA32 1638 #endif // defined TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698