| OLD | NEW | 
|---|
| 1 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file | 1 // Copyright (c) 2011, 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 #include "vm/globals.h" | 5 #include "vm/globals.h" | 
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) | 
| 7 | 7 | 
| 8 #include "vm/assembler.h" | 8 #include "vm/assembler.h" | 
| 9 #include "vm/assembler_macros.h" | 9 #include "vm/assembler_macros.h" | 
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" | 
| (...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 702       __ cmpl(ECX, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 702       __ cmpl(ECX, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 
| 703       __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 703       __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 
| 704       __ shll(ECX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); | 704       __ shll(ECX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); | 
| 705       __ jmp(&done); | 705       __ jmp(&done); | 
| 706 | 706 | 
| 707       __ Bind(&size_tag_overflow); | 707       __ Bind(&size_tag_overflow); | 
| 708       __ movl(ECX, Immediate(0)); | 708       __ movl(ECX, Immediate(0)); | 
| 709       __ Bind(&done); | 709       __ Bind(&done); | 
| 710 | 710 | 
| 711       // Get the class index and insert it into the tags. | 711       // Get the class index and insert it into the tags. | 
| 712       __ orl(ECX, Immediate(RawObject::ClassIdTag::encode(kArray))); | 712       __ orl(ECX, Immediate(RawObject::ClassIdTag::encode(kArrayCid))); | 
| 713       __ movl(FieldAddress(EAX, Array::tags_offset()), ECX); | 713       __ movl(FieldAddress(EAX, Array::tags_offset()), ECX); | 
| 714     } | 714     } | 
| 715 | 715 | 
| 716     // Initialize all array elements to raw_null. | 716     // Initialize all array elements to raw_null. | 
| 717     // EAX: new object start as a tagged pointer. | 717     // EAX: new object start as a tagged pointer. | 
| 718     // EBX: new object end address. | 718     // EBX: new object end address. | 
| 719     // EDX: Array length as Smi. | 719     // EDX: Array length as Smi. | 
| 720     __ leal(ECX, FieldAddress(EAX, Array::data_offset())); | 720     __ leal(ECX, FieldAddress(EAX, Array::data_offset())); | 
| 721     // ECX: iterator which initially points to the start of the variable | 721     // ECX: iterator which initially points to the start of the variable | 
| 722     // data area to be initialized. | 722     // data area to be initialized. | 
| (...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1242       // EDI: new object type arguments. | 1242       // EDI: new object type arguments. | 
| 1243     } | 1243     } | 
| 1244 | 1244 | 
| 1245     // EAX: new object start. | 1245     // EAX: new object start. | 
| 1246     // EBX: next object start. | 1246     // EBX: next object start. | 
| 1247     // EDI: new object type arguments (if is_cls_parameterized). | 1247     // EDI: new object type arguments (if is_cls_parameterized). | 
| 1248     __ LoadObject(EDX, cls);  // Load class of object to be allocated. | 1248     __ LoadObject(EDX, cls);  // Load class of object to be allocated. | 
| 1249     // Set the tags. | 1249     // Set the tags. | 
| 1250     uword tags = 0; | 1250     uword tags = 0; | 
| 1251     tags = RawObject::SizeTag::update(instance_size, tags); | 1251     tags = RawObject::SizeTag::update(instance_size, tags); | 
| 1252     ASSERT(cls.id() != kIllegalObjectKind); | 1252     ASSERT(cls.id() != kIllegalCid); | 
| 1253     tags = RawObject::ClassIdTag::update(cls.id(), tags); | 1253     tags = RawObject::ClassIdTag::update(cls.id(), tags); | 
| 1254     __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); | 1254     __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); | 
| 1255 | 1255 | 
| 1256     // Initialize the remaining words of the object. | 1256     // Initialize the remaining words of the object. | 
| 1257     const Immediate raw_null = | 1257     const Immediate raw_null = | 
| 1258         Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1258         Immediate(reinterpret_cast<intptr_t>(Object::null())); | 
| 1259 | 1259 | 
| 1260     // EAX: new object start. | 1260     // EAX: new object start. | 
| 1261     // EBX: next object start. | 1261     // EBX: next object start. | 
| 1262     // EDX: class of the object to be allocated. | 1262     // EDX: class of the object to be allocated. | 
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1635   // EBX: points directly to the first ic data array element. | 1635   // EBX: points directly to the first ic data array element. | 
| 1636   Label loop, found; | 1636   Label loop, found; | 
| 1637   if (num_args == 1) { | 1637   if (num_args == 1) { | 
| 1638     __ call(&get_class_id_as_smi); | 1638     __ call(&get_class_id_as_smi); | 
| 1639     // EAX: receiver's class id Smi. | 1639     // EAX: receiver's class id Smi. | 
| 1640     __ Bind(&loop); | 1640     __ Bind(&loop); | 
| 1641     __ movl(EDI, Address(EBX, 0));  // Get class id (Smi) to check. | 1641     __ movl(EDI, Address(EBX, 0));  // Get class id (Smi) to check. | 
| 1642     __ cmpl(EAX, EDI);  // Class id match? | 1642     __ cmpl(EAX, EDI);  // Class id match? | 
| 1643     __ j(EQUAL, &found, Assembler::kNearJump); | 1643     __ j(EQUAL, &found, Assembler::kNearJump); | 
| 1644     __ addl(EBX, Immediate(kWordSize * 2));  // Next element (class + target). | 1644     __ addl(EBX, Immediate(kWordSize * 2));  // Next element (class + target). | 
| 1645     __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalObjectKind)));  // Done? | 1645     __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid)));  // Done? | 
| 1646     __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 1646     __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 
| 1647   } else if (num_args == 2) { | 1647   } else if (num_args == 2) { | 
| 1648     // EDI: class to check. | 1648     // EDI: class to check. | 
| 1649     Label no_match; | 1649     Label no_match; | 
| 1650     __ Bind(&loop); | 1650     __ Bind(&loop); | 
| 1651     // Get class id from IC data to check. | 1651     // Get class id from IC data to check. | 
| 1652     // Get receiver using argument descriptor in EDX. | 1652     // Get receiver using argument descriptor in EDX. | 
| 1653     __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 1653     __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 
| 1654     __ movl(EAX, Address(ESP, EAX, TIMES_2, 0));  // EAX (arg. count) is Smi. | 1654     __ movl(EAX, Address(ESP, EAX, TIMES_2, 0));  // EAX (arg. count) is Smi. | 
| 1655     __ call(&get_class_id_as_smi); | 1655     __ call(&get_class_id_as_smi); | 
| 1656     __ movl(EDI, Address(EBX, 0)); | 1656     __ movl(EDI, Address(EBX, 0)); | 
| 1657     __ cmpl(EAX, EDI);  // Class id match? | 1657     __ cmpl(EAX, EDI);  // Class id match? | 
| 1658     __ j(NOT_EQUAL, &no_match, Assembler::kNearJump); | 1658     __ j(NOT_EQUAL, &no_match, Assembler::kNearJump); | 
| 1659     // Check second class/argument. | 1659     // Check second class/argument. | 
| 1660     // Get class id from IC data to check. | 1660     // Get class id from IC data to check. | 
| 1661     // Get next argument. | 1661     // Get next argument. | 
| 1662     __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 1662     __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 
| 1663     __ movl(EAX, Address(ESP, EAX, TIMES_2, -kWordSize)); | 1663     __ movl(EAX, Address(ESP, EAX, TIMES_2, -kWordSize)); | 
| 1664     // EAX (argument count) is Smi. | 1664     // EAX (argument count) is Smi. | 
| 1665     __ call(&get_class_id_as_smi); | 1665     __ call(&get_class_id_as_smi); | 
| 1666     __ movl(EDI, Address(EBX, kWordSize)); | 1666     __ movl(EDI, Address(EBX, kWordSize)); | 
| 1667     __ cmpl(EAX, EDI);  // Class id match? | 1667     __ cmpl(EAX, EDI);  // Class id match? | 
| 1668     __ j(EQUAL, &found, Assembler::kNearJump); | 1668     __ j(EQUAL, &found, Assembler::kNearJump); | 
| 1669     __ Bind(&no_match); | 1669     __ Bind(&no_match); | 
| 1670     // Each test entry has (1 + num_args) array elements. | 1670     // Each test entry has (1 + num_args) array elements. | 
| 1671     __ addl(EBX, Immediate(kWordSize * (1 + num_args)));  // Next element. | 1671     __ addl(EBX, Immediate(kWordSize * (1 + num_args)));  // Next element. | 
| 1672     __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalObjectKind)));  // Done? | 1672     __ cmpl(EDI, Immediate(Smi::RawValue(kIllegalCid)));  // Done? | 
| 1673     __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 1673     __ j(NOT_EQUAL, &loop, Assembler::kNearJump); | 
| 1674   } | 1674   } | 
| 1675 | 1675 | 
| 1676   __ Bind(&ic_miss); | 1676   __ Bind(&ic_miss); | 
| 1677   // Compute address of arguments (first read number of arguments from argument | 1677   // Compute address of arguments (first read number of arguments from argument | 
| 1678   // descriptor array and then compute address on the stack). | 1678   // descriptor array and then compute address on the stack). | 
| 1679   __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 1679   __ movl(EAX, FieldAddress(EDX, Array::data_offset())); | 
| 1680   __ leal(EAX, Address(ESP, EAX, TIMES_2, 0));  // EAX is Smi. | 1680   __ leal(EAX, Address(ESP, EAX, TIMES_2, 0));  // EAX is Smi. | 
| 1681   // Create a stub frame as we are pushing some objects on the stack before | 1681   // Create a stub frame as we are pushing some objects on the stack before | 
| 1682   // calling into the runtime. | 1682   // calling into the runtime. | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1719   __ movl(EAX, FieldAddress(EAX, Function::code_offset())); | 1719   __ movl(EAX, FieldAddress(EAX, Function::code_offset())); | 
| 1720   __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); | 1720   __ movl(EAX, FieldAddress(EAX, Code::instructions_offset())); | 
| 1721   __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 1721   __ addl(EAX, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); | 
| 1722   __ jmp(EAX); | 1722   __ jmp(EAX); | 
| 1723 | 1723 | 
| 1724   __ Bind(&get_class_id_as_smi); | 1724   __ Bind(&get_class_id_as_smi); | 
| 1725   Label not_smi; | 1725   Label not_smi; | 
| 1726   // Test if Smi -> load Smi class for comparison. | 1726   // Test if Smi -> load Smi class for comparison. | 
| 1727   __ testl(EAX, Immediate(kSmiTagMask)); | 1727   __ testl(EAX, Immediate(kSmiTagMask)); | 
| 1728   __ j(NOT_ZERO, ¬_smi, Assembler::kNearJump); | 1728   __ j(NOT_ZERO, ¬_smi, Assembler::kNearJump); | 
| 1729   __ movl(EAX, Immediate(Smi::RawValue(kSmi))); | 1729   __ movl(EAX, Immediate(Smi::RawValue(kSmiCid))); | 
| 1730   __ ret(); | 1730   __ ret(); | 
| 1731 | 1731 | 
| 1732   __ Bind(¬_smi); | 1732   __ Bind(¬_smi); | 
| 1733   __ LoadClassId(EAX, EAX); | 1733   __ LoadClassId(EAX, EAX); | 
| 1734   __ SmiTag(EAX); | 1734   __ SmiTag(EAX); | 
| 1735   __ ret(); | 1735   __ ret(); | 
| 1736 } | 1736 } | 
| 1737 | 1737 | 
| 1738 | 1738 | 
| 1739 // Use inline cache data array to invoke the target or continue in inline | 1739 // Use inline cache data array to invoke the target or continue in inline | 
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1974   __ movl(EAX, Address(ESP, 4 * kWordSize));  // Load error object. | 1974   __ movl(EAX, Address(ESP, 4 * kWordSize));  // Load error object. | 
| 1975   __ movl(EBP, Address(ESP, 3 * kWordSize));  // Load target frame_pointer. | 1975   __ movl(EBP, Address(ESP, 3 * kWordSize));  // Load target frame_pointer. | 
| 1976   __ movl(EBX, Address(ESP, 1 * kWordSize));  // Load target PC into EBX. | 1976   __ movl(EBX, Address(ESP, 1 * kWordSize));  // Load target PC into EBX. | 
| 1977   __ movl(ESP, Address(ESP, 2 * kWordSize));  // Load target stack_pointer. | 1977   __ movl(ESP, Address(ESP, 2 * kWordSize));  // Load target stack_pointer. | 
| 1978   __ jmp(EBX);  // Jump to the exception handler code. | 1978   __ jmp(EBX);  // Jump to the exception handler code. | 
| 1979 } | 1979 } | 
| 1980 | 1980 | 
| 1981 }  // namespace dart | 1981 }  // namespace dart | 
| 1982 | 1982 | 
| 1983 #endif  // defined TARGET_ARCH_IA32 | 1983 #endif  // defined TARGET_ARCH_IA32 | 
| OLD | NEW | 
|---|