| 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/code_generator.h" | 8 #include "vm/code_generator.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/object_store.h" | 10 #include "vm/object_store.h" |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 617 // EDX : Array length as Smi. | 617 // EDX : Array length as Smi. |
| 618 // ECX : array element type (either NULL or an instantiated type). | 618 // ECX : array element type (either NULL or an instantiated type). |
| 619 // Uses EAX, EBX, ECX, EDI as temporary registers. | 619 // Uses EAX, EBX, ECX, EDI as temporary registers. |
| 620 // NOTE: EDX cannot be clobbered here as the caller relies on it being saved. | 620 // NOTE: EDX cannot be clobbered here as the caller relies on it being saved. |
| 621 // The newly allocated object is returned in EAX. | 621 // The newly allocated object is returned in EAX. |
| 622 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { | 622 void StubCode::GenerateAllocateArrayStub(Assembler* assembler) { |
| 623 Label slow_case; | 623 Label slow_case; |
| 624 const Immediate raw_null = | 624 const Immediate raw_null = |
| 625 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 625 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 626 | 626 |
| 627 if (FLAG_inline_alloc) { | 627 if (0 && FLAG_inline_alloc) { |
| 628 // Compute the size to be allocated, it is based on the array length | 628 // Compute the size to be allocated, it is based on the array length |
| 629 // and it computed as: | 629 // and it computed as: |
| 630 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). | 630 // RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)). |
| 631 // Assert that length is a Smi. | 631 // Assert that length is a Smi. |
| 632 __ testl(EDX, Immediate(kSmiTagSize)); | 632 __ testl(EDX, Immediate(kSmiTagSize)); |
| 633 if (FLAG_use_slow_path) { | 633 if (FLAG_use_slow_path) { |
| 634 __ jmp(&slow_case); | 634 __ jmp(&slow_case); |
| 635 } else { | 635 } else { |
| 636 __ j(NOT_ZERO, &slow_case, Assembler::kNearJump); | 636 __ j(NOT_ZERO, &slow_case, Assembler::kNearJump); |
| 637 } | 637 } |
| (...skipping 333 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 971 | 971 |
| 972 // Called for inline allocation of contexts. | 972 // Called for inline allocation of contexts. |
| 973 // Input: | 973 // Input: |
| 974 // EDX: number of context variables. | 974 // EDX: number of context variables. |
| 975 // Output: | 975 // Output: |
| 976 // EAX: new allocated RawContext object. | 976 // EAX: new allocated RawContext object. |
| 977 // EBX and EDX are destroyed. | 977 // EBX and EDX are destroyed. |
| 978 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { | 978 void StubCode::GenerateAllocateContextStub(Assembler* assembler) { |
| 979 const Immediate raw_null = | 979 const Immediate raw_null = |
| 980 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 980 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 981 if (FLAG_inline_alloc) { | 981 if (0 && FLAG_inline_alloc) { |
| 982 const Class& context_class = Class::ZoneHandle(Object::context_class()); | 982 const Class& context_class = Class::ZoneHandle(Object::context_class()); |
| 983 Label slow_case; | 983 Label slow_case; |
| 984 Heap* heap = Isolate::Current()->heap(); | 984 Heap* heap = Isolate::Current()->heap(); |
| 985 // First compute the rounded instance size. | 985 // First compute the rounded instance size. |
| 986 // EDX: number of context variables. | 986 // EDX: number of context variables. |
| 987 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); | 987 intptr_t fixed_size = (sizeof(RawContext) + kObjectAlignment - 1); |
| 988 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); | 988 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); |
| 989 __ andl(EBX, Immediate(-kObjectAlignment)); | 989 __ andl(EBX, Immediate(-kObjectAlignment)); |
| 990 | 990 |
| 991 // Now allocate the object. | 991 // Now allocate the object. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 1021 // Calculate the size tag. | 1021 // Calculate the size tag. |
| 1022 // EAX: new object. | 1022 // EAX: new object. |
| 1023 // EDX: number of context variables. | 1023 // EDX: number of context variables. |
| 1024 { | 1024 { |
| 1025 Label size_tag_overflow, done; | 1025 Label size_tag_overflow, done; |
| 1026 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); | 1026 __ leal(EBX, Address(EDX, TIMES_4, fixed_size)); |
| 1027 __ andl(EBX, Immediate(-kObjectAlignment)); | 1027 __ andl(EBX, Immediate(-kObjectAlignment)); |
| 1028 __ cmpl(EBX, Immediate(RawObject::SizeTag::kMaxSizeTag)); | 1028 __ cmpl(EBX, Immediate(RawObject::SizeTag::kMaxSizeTag)); |
| 1029 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); | 1029 __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump); |
| 1030 __ shll(EBX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); | 1030 __ shll(EBX, Immediate(RawObject::kSizeTagBit - kObjectAlignmentLog2)); |
| 1031 __ movl(FieldAddress(EAX, Context::tags_offset()), EBX); // Tags. | |
| 1032 __ jmp(&done); | 1031 __ jmp(&done); |
| 1033 | 1032 |
| 1034 __ Bind(&size_tag_overflow); | 1033 __ Bind(&size_tag_overflow); |
| 1035 // Set overflow size tag value. | 1034 // Set overflow size tag value. |
| 1036 __ movl(FieldAddress(EAX, Context::tags_offset()), Immediate(0)); | 1035 __ movl(EBX, Immediate(0)); |
| 1036 |
| 1037 __ Bind(&done); | 1037 __ Bind(&done); |
| 1038 // EAX: new object. |
| 1039 // EDX: number of context variables. |
| 1040 // EBX: size and bit tags. |
| 1041 __ orl(EBX, |
| 1042 Immediate(RawObject::ClassTag::encode(context_class.index()))); |
| 1043 __ movl(FieldAddress(EAX, Context::tags_offset()), EBX); // Tags. |
| 1038 } | 1044 } |
| 1039 | 1045 |
| 1040 // Setup up number of context variables field. | 1046 // Setup up number of context variables field. |
| 1041 // EAX: new object. | 1047 // EAX: new object. |
| 1042 // EDX: number of context variables as integer value (not object). | 1048 // EDX: number of context variables as integer value (not object). |
| 1043 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); | 1049 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); |
| 1044 | 1050 |
| 1045 // Setup isolate field. | 1051 // Setup isolate field. |
| 1046 // Load Isolate pointer from Context structure into EBX. | 1052 // Load Isolate pointer from Context structure into EBX. |
| 1047 // EAX: new object. | 1053 // EAX: new object. |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1183 // EDI: new object type arguments. | 1189 // EDI: new object type arguments. |
| 1184 } | 1190 } |
| 1185 | 1191 |
| 1186 // Initialize the class field in the object. | 1192 // Initialize the class field in the object. |
| 1187 // EAX: new object start. | 1193 // EAX: new object start. |
| 1188 // EBX: next object start. | 1194 // EBX: next object start. |
| 1189 // EDI: new object type arguments (if is_cls_parameterized). | 1195 // EDI: new object type arguments (if is_cls_parameterized). |
| 1190 __ LoadObject(EDX, cls); // Load class of object to be allocated. | 1196 __ LoadObject(EDX, cls); // Load class of object to be allocated. |
| 1191 __ movl(Address(EAX, Instance::class_offset()), EDX); | 1197 __ movl(Address(EAX, Instance::class_offset()), EDX); |
| 1192 // Set the tags. | 1198 // Set the tags. |
| 1193 __ movl(Address(EAX, Instance::tags_offset()), | 1199 intptr_t tags = 0; |
| 1194 Immediate(RawObject::SizeTag::encode(instance_size))); | 1200 tags = RawObject::SizeTag::update(instance_size, tags); |
| 1201 ASSERT(cls.index() != kIllegalObjectKind); |
| 1202 tags = RawObject::ClassTag::update(cls.index(), tags); |
| 1203 __ movl(Address(EAX, Instance::tags_offset()), Immediate(tags)); |
| 1195 | 1204 |
| 1196 // Initialize the remaining words of the object. | 1205 // Initialize the remaining words of the object. |
| 1197 const Immediate raw_null = | 1206 const Immediate raw_null = |
| 1198 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1207 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1199 | 1208 |
| 1200 // EAX: new object start. | 1209 // EAX: new object start. |
| 1201 // EBX: next object start. | 1210 // EBX: next object start. |
| 1202 // EDX: class of the object to be allocated. | 1211 // EDX: class of the object to be allocated. |
| 1203 // First try inlining the initialization without a loop. | 1212 // First try inlining the initialization without a loop. |
| 1204 if (instance_size < (kInlineInstanceSize * kWordSize) && | 1213 if (instance_size < (kInlineInstanceSize * kWordSize) && |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1302 const bool is_implicit_static_closure = | 1311 const bool is_implicit_static_closure = |
| 1303 func.IsImplicitStaticClosureFunction(); | 1312 func.IsImplicitStaticClosureFunction(); |
| 1304 const bool is_implicit_instance_closure = | 1313 const bool is_implicit_instance_closure = |
| 1305 func.IsImplicitInstanceClosureFunction(); | 1314 func.IsImplicitInstanceClosureFunction(); |
| 1306 const Class& cls = Class::ZoneHandle(func.signature_class()); | 1315 const Class& cls = Class::ZoneHandle(func.signature_class()); |
| 1307 const bool has_type_arguments = cls.HasTypeArguments(); | 1316 const bool has_type_arguments = cls.HasTypeArguments(); |
| 1308 const intptr_t kTypeArgumentsOffset = 1 * kWordSize; | 1317 const intptr_t kTypeArgumentsOffset = 1 * kWordSize; |
| 1309 const intptr_t kReceiverOffset = (has_type_arguments ? 2 : 1) * kWordSize; | 1318 const intptr_t kReceiverOffset = (has_type_arguments ? 2 : 1) * kWordSize; |
| 1310 const intptr_t closure_size = Closure::InstanceSize(); | 1319 const intptr_t closure_size = Closure::InstanceSize(); |
| 1311 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. | 1320 const intptr_t context_size = Context::InstanceSize(1); // Captured receiver. |
| 1312 if (FLAG_inline_alloc && | 1321 if (0 && FLAG_inline_alloc && |
| 1313 PageSpace::IsPageAllocatableSize(closure_size + context_size)) { | 1322 PageSpace::IsPageAllocatableSize(closure_size + context_size)) { |
| 1314 Label slow_case; | 1323 Label slow_case; |
| 1315 Heap* heap = Isolate::Current()->heap(); | 1324 Heap* heap = Isolate::Current()->heap(); |
| 1316 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 1325 __ movl(EAX, Address::Absolute(heap->TopAddress())); |
| 1317 __ leal(EBX, Address(EAX, closure_size)); | 1326 __ leal(EBX, Address(EAX, closure_size)); |
| 1318 if (is_implicit_instance_closure) { | 1327 if (is_implicit_instance_closure) { |
| 1319 __ movl(ECX, EBX); // ECX: new context address. | 1328 __ movl(ECX, EBX); // ECX: new context address. |
| 1320 __ addl(EBX, Immediate(context_size)); | 1329 __ addl(EBX, Immediate(context_size)); |
| 1321 } | 1330 } |
| 1322 // Check if the allocation fits into the remaining space. | 1331 // Check if the allocation fits into the remaining space. |
| (...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1830 __ movl(ECX, FieldAddress(ECX, Type::type_class_offset())); | 1839 __ movl(ECX, FieldAddress(ECX, Type::type_class_offset())); |
| 1831 __ cmpl(EDX, ECX); | 1840 __ cmpl(EDX, ECX); |
| 1832 __ j(NOT_EQUAL, &super_loop, Assembler::kNearJump); | 1841 __ j(NOT_EQUAL, &super_loop, Assembler::kNearJump); |
| 1833 __ jmp(&found, Assembler::kNearJump); | 1842 __ jmp(&found, Assembler::kNearJump); |
| 1834 } | 1843 } |
| 1835 | 1844 |
| 1836 | 1845 |
| 1837 } // namespace dart | 1846 } // namespace dart |
| 1838 | 1847 |
| 1839 #endif // defined TARGET_ARCH_IA32 | 1848 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |