OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 1102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1113 // The generated code is different if the class is parameterized. | 1113 // The generated code is different if the class is parameterized. |
1114 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; | 1114 const bool is_cls_parameterized = cls.NumTypeArguments() > 0; |
1115 ASSERT(!is_cls_parameterized || | 1115 ASSERT(!is_cls_parameterized || |
1116 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); | 1116 (cls.type_arguments_field_offset() != Class::kNoTypeArguments)); |
1117 // kInlineInstanceSize is a constant used as a threshold for determining | 1117 // kInlineInstanceSize is a constant used as a threshold for determining |
1118 // when the object initialization should be done as a loop or as | 1118 // when the object initialization should be done as a loop or as |
1119 // straight line code. | 1119 // straight line code. |
1120 const int kInlineInstanceSize = 12; // In words. | 1120 const int kInlineInstanceSize = 12; // In words. |
1121 const intptr_t instance_size = cls.instance_size(); | 1121 const intptr_t instance_size = cls.instance_size(); |
1122 ASSERT(instance_size > 0); | 1122 ASSERT(instance_size > 0); |
1123 Label slow_case_with_type_arguments; | 1123 if (is_cls_parameterized) { |
| 1124 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); |
| 1125 // EDX: instantiated type arguments. |
| 1126 } |
1124 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { | 1127 if (FLAG_inline_alloc && Heap::IsAllocatableInNewSpace(instance_size)) { |
1125 Label slow_case_reload_type_arguments; | 1128 Label slow_case; |
1126 if (is_cls_parameterized) { | |
1127 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); | |
1128 // EDX: instantiated type arguments. | |
1129 } | |
1130 // Allocate the object and update top to point to | 1129 // Allocate the object and update top to point to |
1131 // next object start and initialize the allocated object. | 1130 // next object start and initialize the allocated object. |
1132 // EDX: instantiated type arguments (if is_cls_parameterized). | 1131 // EDX: instantiated type arguments (if is_cls_parameterized). |
1133 Heap* heap = Isolate::Current()->heap(); | 1132 Heap* heap = Isolate::Current()->heap(); |
1134 __ movl(EAX, Address::Absolute(heap->TopAddress())); | 1133 __ movl(EAX, Address::Absolute(heap->TopAddress())); |
1135 __ leal(EBX, Address(EAX, instance_size)); | 1134 __ leal(EBX, Address(EAX, instance_size)); |
1136 // Check if the allocation fits into the remaining space. | 1135 // Check if the allocation fits into the remaining space. |
1137 // EAX: potential new object start. | 1136 // EAX: potential new object start. |
1138 // EBX: potential next object start. | 1137 // EBX: potential next object start. |
1139 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); | 1138 __ cmpl(EBX, Address::Absolute(heap->EndAddress())); |
1140 if (FLAG_use_slow_path) { | 1139 if (FLAG_use_slow_path) { |
1141 __ jmp(&slow_case_with_type_arguments); | 1140 __ jmp(&slow_case); |
1142 } else { | 1141 } else { |
1143 __ j(ABOVE_EQUAL, &slow_case_with_type_arguments); | 1142 __ j(ABOVE_EQUAL, &slow_case); |
1144 } | 1143 } |
1145 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 1144 __ movl(Address::Absolute(heap->TopAddress()), EBX); |
1146 __ UpdateAllocationStats(cls.id(), ECX); | 1145 __ UpdateAllocationStats(cls.id(), ECX); |
1147 | 1146 |
1148 // EAX: new object start. | 1147 // EAX: new object start. |
1149 // EBX: next object start. | 1148 // EBX: next object start. |
1150 // EDX: new object type arguments (if is_cls_parameterized). | 1149 // EDX: new object type arguments (if is_cls_parameterized). |
1151 // Set the tags. | 1150 // Set the tags. |
1152 uword tags = 0; | 1151 uword tags = 0; |
1153 tags = RawObject::SizeTag::update(instance_size, tags); | 1152 tags = RawObject::SizeTag::update(instance_size, tags); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1191 if (is_cls_parameterized) { | 1190 if (is_cls_parameterized) { |
1192 // EDX: new object type arguments. | 1191 // EDX: new object type arguments. |
1193 // Set the type arguments in the new object. | 1192 // Set the type arguments in the new object. |
1194 __ movl(Address(EAX, cls.type_arguments_field_offset()), EDX); | 1193 __ movl(Address(EAX, cls.type_arguments_field_offset()), EDX); |
1195 } | 1194 } |
1196 // Done allocating and initializing the instance. | 1195 // Done allocating and initializing the instance. |
1197 // EAX: new object. | 1196 // EAX: new object. |
1198 __ addl(EAX, Immediate(kHeapObjectTag)); | 1197 __ addl(EAX, Immediate(kHeapObjectTag)); |
1199 __ ret(); | 1198 __ ret(); |
1200 | 1199 |
1201 __ Bind(&slow_case_reload_type_arguments); | 1200 __ Bind(&slow_case); |
1202 } | 1201 } |
1203 if (is_cls_parameterized) { | |
1204 __ movl(EDX, Address(ESP, kObjectTypeArgumentsOffset)); | |
1205 } | |
1206 __ Bind(&slow_case_with_type_arguments); | |
1207 // If is_cls_parameterized: | 1202 // If is_cls_parameterized: |
1208 // EDX: new object type arguments. | 1203 // EDX: new object type arguments. |
1209 // Create a stub frame as we are pushing some objects on the stack before | 1204 // Create a stub frame as we are pushing some objects on the stack before |
1210 // calling into the runtime. | 1205 // calling into the runtime. |
1211 __ EnterStubFrame(); | 1206 __ EnterStubFrame(); |
1212 __ pushl(raw_null); // Setup space on stack for return value. | 1207 __ pushl(raw_null); // Setup space on stack for return value. |
1213 __ PushObject(cls); // Push class of object to be allocated. | 1208 __ PushObject(cls); // Push class of object to be allocated. |
1214 if (is_cls_parameterized) { | 1209 if (is_cls_parameterized) { |
1215 __ pushl(EDX); // Push type arguments of object to be allocated. | 1210 __ pushl(EDX); // Push type arguments of object to be allocated. |
1216 } else { | 1211 } else { |
(...skipping 904 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2121 const Register temp = ECX; | 2116 const Register temp = ECX; |
2122 __ movl(left, Address(ESP, 2 * kWordSize)); | 2117 __ movl(left, Address(ESP, 2 * kWordSize)); |
2123 __ movl(right, Address(ESP, 1 * kWordSize)); | 2118 __ movl(right, Address(ESP, 1 * kWordSize)); |
2124 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); | 2119 GenerateIdenticalWithNumberCheckStub(assembler, left, right, temp); |
2125 __ ret(); | 2120 __ ret(); |
2126 } | 2121 } |
2127 | 2122 |
2128 } // namespace dart | 2123 } // namespace dart |
2129 | 2124 |
2130 #endif // defined TARGET_ARCH_IA32 | 2125 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |