| 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/ic_data.h" | 10 #include "vm/ic_data.h" |
| (...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 __ movl(FieldAddress(EAX, Array::type_arguments_offset()), ECX); | 687 __ movl(FieldAddress(EAX, Array::type_arguments_offset()), ECX); |
| 688 | 688 |
| 689 // Set the length field. | 689 // Set the length field. |
| 690 __ movl(FieldAddress(EAX, Array::length_offset()), EDX); | 690 __ movl(FieldAddress(EAX, Array::length_offset()), EDX); |
| 691 | 691 |
| 692 // Store class value for array. | 692 // Store class value for array. |
| 693 __ movl(ECX, FieldAddress(CTX, Context::isolate_offset())); | 693 __ movl(ECX, FieldAddress(CTX, Context::isolate_offset())); |
| 694 __ movl(ECX, Address(ECX, Isolate::object_store_offset())); | 694 __ movl(ECX, Address(ECX, Isolate::object_store_offset())); |
| 695 __ movl(ECX, Address(ECX, ObjectStore::array_class_offset())); | 695 __ movl(ECX, Address(ECX, ObjectStore::array_class_offset())); |
| 696 __ movl(FieldAddress(EAX, Array::class_offset()), ECX); | 696 __ movl(FieldAddress(EAX, Array::class_offset()), ECX); |
| 697 __ movl(FieldAddress(EAX, Array::tags_offset()), Immediate(0)); // Tags. |
| 697 | 698 |
| 698 // Initialize all array elements to raw_null. | 699 // Initialize all array elements to raw_null. |
| 699 // EAX: new object start as a tagged pointer. | 700 // EAX: new object start as a tagged pointer. |
| 700 // EBX: new object end address. | 701 // EBX: new object end address. |
| 701 // ECX: iterator which initially points to the start of the variable | 702 // ECX: iterator which initially points to the start of the variable |
| 702 // data area to be initialized. | 703 // data area to be initialized. |
| 703 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); | 704 __ leal(ECX, FieldAddress(EAX, Array::data_offset())); |
| 704 Label done; | 705 Label done; |
| 705 Label init_loop; | 706 Label init_loop; |
| 706 __ Bind(&init_loop); | 707 __ Bind(&init_loop); |
| (...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 987 // EBX: next object start. | 988 // EBX: next object start. |
| 988 // EDX: number of context variables. | 989 // EDX: number of context variables. |
| 989 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 990 __ movl(Address::Absolute(heap->TopAddress()), EBX); |
| 990 __ addl(EAX, Immediate(kHeapObjectTag)); | 991 __ addl(EAX, Immediate(kHeapObjectTag)); |
| 991 | 992 |
| 992 // Initialize the class field in the context object. | 993 // Initialize the class field in the context object. |
| 993 // EAX: new object. | 994 // EAX: new object. |
| 994 // EDX: number of context variables. | 995 // EDX: number of context variables. |
| 995 __ LoadObject(EBX, context_class); // Load up class field of context. | 996 __ LoadObject(EBX, context_class); // Load up class field of context. |
| 996 __ movl(FieldAddress(EAX, Context::class_offset()), EBX); | 997 __ movl(FieldAddress(EAX, Context::class_offset()), EBX); |
| 998 __ movl(FieldAddress(EAX, Context::tags_offset()), Immediate(0)); // Tags. |
| 997 | 999 |
| 998 // Setup up number of context variables field. | 1000 // Setup up number of context variables field. |
| 999 // EAX: new object. | 1001 // EAX: new object. |
| 1000 // EDX: number of context variables. | 1002 // EDX: number of context variables. |
| 1001 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); | 1003 __ movl(FieldAddress(EAX, Context::num_variables_offset()), EDX); |
| 1002 | 1004 |
| 1003 // Setup isolate field. | 1005 // Setup isolate field. |
| 1004 // Load Isolate pointer from Context structure into EBX. | 1006 // Load Isolate pointer from Context structure into EBX. |
| 1005 // EAX: new object. | 1007 // EAX: new object. |
| 1006 // EDX: number of context variables. | 1008 // EDX: number of context variables. |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1120 __ movl(Address(ECX, | 1122 __ movl(Address(ECX, |
| 1121 InstantiatedTypeArguments::uninstantiated_type_arguments_offset()), | 1123 InstantiatedTypeArguments::uninstantiated_type_arguments_offset()), |
| 1122 EDI); | 1124 EDI); |
| 1123 __ movl(EDX, Address(ESP, kInstantiatorTypeArgumentsOffset)); | 1125 __ movl(EDX, Address(ESP, kInstantiatorTypeArgumentsOffset)); |
| 1124 __ movl(Address(ECX, | 1126 __ movl(Address(ECX, |
| 1125 InstantiatedTypeArguments::instantiator_type_arguments_offset()), | 1127 InstantiatedTypeArguments::instantiator_type_arguments_offset()), |
| 1126 EDX); | 1128 EDX); |
| 1127 __ LoadObject(EDX, | 1129 __ LoadObject(EDX, |
| 1128 Class::ZoneHandle(Object::instantiated_type_arguments_class())); | 1130 Class::ZoneHandle(Object::instantiated_type_arguments_class())); |
| 1129 __ movl(Address(ECX, Instance::class_offset()), EDX); // Set its class. | 1131 __ movl(Address(ECX, Instance::class_offset()), EDX); // Set its class. |
| 1132 __ movl(Address(ECX, Instance::tags_offset()), Immediate(0)); // Tags. |
| 1130 // Set the new InstantiatedTypeArguments object (ECX) as the type | 1133 // Set the new InstantiatedTypeArguments object (ECX) as the type |
| 1131 // arguments (EDI) of the new object (EAX). | 1134 // arguments (EDI) of the new object (EAX). |
| 1132 __ movl(EDI, ECX); | 1135 __ movl(EDI, ECX); |
| 1133 __ addl(EDI, Immediate(kHeapObjectTag)); | 1136 __ addl(EDI, Immediate(kHeapObjectTag)); |
| 1134 // Set EBX to new object end. | 1137 // Set EBX to new object end. |
| 1135 __ movl(EBX, ECX); | 1138 __ movl(EBX, ECX); |
| 1136 __ Bind(&type_arguments_ready); | 1139 __ Bind(&type_arguments_ready); |
| 1137 // EAX: new object. | 1140 // EAX: new object. |
| 1138 // EDI: new object type arguments. | 1141 // EDI: new object type arguments. |
| 1139 } | 1142 } |
| 1140 | 1143 |
| 1141 // Initialize the class field in the object. | 1144 // Initialize the class field in the object. |
| 1142 // EAX: new object start. | 1145 // EAX: new object start. |
| 1143 // EBX: next object start. | 1146 // EBX: next object start. |
| 1144 // EDI: new object type arguments (if is_cls_parameterized). | 1147 // EDI: new object type arguments (if is_cls_parameterized). |
| 1145 __ LoadObject(EDX, cls); // Load class of object to be allocated. | 1148 __ LoadObject(EDX, cls); // Load class of object to be allocated. |
| 1146 __ movl(Address(EAX, Instance::class_offset()), EDX); | 1149 __ movl(Address(EAX, Instance::class_offset()), EDX); |
| 1150 __ movl(Address(EAX, Instance::tags_offset()), Immediate(0)); // Tags. |
| 1147 | 1151 |
| 1148 // Initialize the remaining words of the object. | 1152 // Initialize the remaining words of the object. |
| 1149 const Immediate raw_null = | 1153 const Immediate raw_null = |
| 1150 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 1154 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 1151 | 1155 |
| 1152 // EAX: new object start. | 1156 // EAX: new object start. |
| 1153 // EBX: next object start. | 1157 // EBX: next object start. |
| 1154 // EDX: class of the object to be allocated. | 1158 // EDX: class of the object to be allocated. |
| 1155 // First try inlining the initialization without a loop. | 1159 // First try inlining the initialization without a loop. |
| 1156 if (instance_size < (kInlineInstanceSize * kWordSize) && | 1160 if (instance_size < (kInlineInstanceSize * kWordSize) && |
| 1157 cls.num_native_fields() == 0) { | 1161 cls.num_native_fields() == 0) { |
| 1158 // Check if the object contains any non-header fields. | 1162 // Check if the object contains any non-header fields. |
| 1159 // Small objects are initialized using a consecutive set of writes. | 1163 // Small objects are initialized using a consecutive set of writes. |
| 1160 for (intptr_t current_offset = 1 * kWordSize; | 1164 for (intptr_t current_offset = sizeof(RawObject); |
| 1161 current_offset < instance_size; | 1165 current_offset < instance_size; |
| 1162 current_offset += kWordSize) { | 1166 current_offset += kWordSize) { |
| 1163 __ movl(Address(EAX, current_offset), raw_null); | 1167 __ movl(Address(EAX, current_offset), raw_null); |
| 1164 } | 1168 } |
| 1165 } else { | 1169 } else { |
| 1166 __ leal(ECX, Address(EAX, 1 * kWordSize)); | 1170 __ leal(ECX, Address(EAX, sizeof(RawObject))); |
| 1167 // Loop until the whole object is initialized. | 1171 // Loop until the whole object is initialized. |
| 1168 Label init_loop; | 1172 Label init_loop; |
| 1169 if (cls.num_native_fields() > 0) { | 1173 if (cls.num_native_fields() > 0) { |
| 1170 // Initialize native fields. | 1174 // Initialize native fields. |
| 1171 // EAX: new object. | 1175 // EAX: new object. |
| 1172 // EBX: next object start. | 1176 // EBX: next object start. |
| 1173 // EDX: class of the object to be allocated. | 1177 // EDX: class of the object to be allocated. |
| 1174 // ECX: next word to be initialized. | 1178 // ECX: next word to be initialized. |
| 1175 intptr_t offset = Class::num_native_fields_offset() - kHeapObjectTag; | 1179 intptr_t offset = Class::num_native_fields_offset() - kHeapObjectTag; |
| 1176 __ movl(EDX, Address(EDX, offset)); | 1180 __ movl(EDX, Address(EDX, offset)); |
| 1177 __ leal(EDX, Address(EAX, EDX, TIMES_4, 0)); | 1181 __ leal(EDX, Address(EAX, EDX, TIMES_4, sizeof(RawObject))); |
| 1178 | 1182 |
| 1179 // EDX: start of dart fields. | 1183 // EDX: start of dart fields. |
| 1180 // ECX: next word to be initialized. | 1184 // ECX: next word to be initialized. |
| 1181 Label init_native_loop; | 1185 Label init_native_loop; |
| 1182 __ Bind(&init_native_loop); | 1186 __ Bind(&init_native_loop); |
| 1183 __ cmpl(ECX, EDX); | 1187 __ cmpl(ECX, EDX); |
| 1184 __ j(ABOVE_EQUAL, &init_loop, Assembler::kNearJump); | 1188 __ j(ABOVE_EQUAL, &init_loop, Assembler::kNearJump); |
| 1185 __ movl(Address(ECX, 0), Immediate(0)); | 1189 __ movl(Address(ECX, 0), Immediate(0)); |
| 1186 __ addl(ECX, Immediate(kWordSize)); | 1190 __ addl(ECX, Immediate(kWordSize)); |
| 1187 __ jmp(&init_native_loop, Assembler::kNearJump); | 1191 __ jmp(&init_native_loop, Assembler::kNearJump); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1285 | 1289 |
| 1286 // Successfully allocated the object, now update top to point to | 1290 // Successfully allocated the object, now update top to point to |
| 1287 // next object start and initialize the object. | 1291 // next object start and initialize the object. |
| 1288 __ movl(Address::Absolute(heap->TopAddress()), EBX); | 1292 __ movl(Address::Absolute(heap->TopAddress()), EBX); |
| 1289 | 1293 |
| 1290 // Initialize the class field in the object. | 1294 // Initialize the class field in the object. |
| 1291 // EAX: new closure object. | 1295 // EAX: new closure object. |
| 1292 // ECX: new context object (only if is_implicit_closure). | 1296 // ECX: new context object (only if is_implicit_closure). |
| 1293 __ LoadObject(EDX, cls); // Load signature class of closure. | 1297 __ LoadObject(EDX, cls); // Load signature class of closure. |
| 1294 __ movl(Address(EAX, Closure::class_offset()), EDX); | 1298 __ movl(Address(EAX, Closure::class_offset()), EDX); |
| 1299 __ movl(Address(EAX, Closure::tags_offset()), Immediate(0)); // Tags. |
| 1295 | 1300 |
| 1296 // Initialize the function field in the object. | 1301 // Initialize the function field in the object. |
| 1297 // EAX: new closure object. | 1302 // EAX: new closure object. |
| 1298 // ECX: new context object (only if is_implicit_closure). | 1303 // ECX: new context object (only if is_implicit_closure). |
| 1299 // EBX: next object start. | 1304 // EBX: next object start. |
| 1300 __ LoadObject(EDX, func); // Load function of closure to be allocated. | 1305 __ LoadObject(EDX, func); // Load function of closure to be allocated. |
| 1301 __ movl(Address(EAX, Closure::function_offset()), EDX); | 1306 __ movl(Address(EAX, Closure::function_offset()), EDX); |
| 1302 | 1307 |
| 1303 // Setup the context for this closure. | 1308 // Setup the context for this closure. |
| 1304 if (is_implicit_static_closure) { | 1309 if (is_implicit_static_closure) { |
| 1305 ObjectStore* object_store = Isolate::Current()->object_store(); | 1310 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 1306 ASSERT(object_store != NULL); | 1311 ASSERT(object_store != NULL); |
| 1307 const Context& empty_context = | 1312 const Context& empty_context = |
| 1308 Context::ZoneHandle(object_store->empty_context()); | 1313 Context::ZoneHandle(object_store->empty_context()); |
| 1309 __ LoadObject(EDX, empty_context); | 1314 __ LoadObject(EDX, empty_context); |
| 1310 __ movl(Address(EAX, Closure::context_offset()), EDX); | 1315 __ movl(Address(EAX, Closure::context_offset()), EDX); |
| 1311 } else if (is_implicit_instance_closure) { | 1316 } else if (is_implicit_instance_closure) { |
| 1312 // Initialize the new context capturing the receiver. | 1317 // Initialize the new context capturing the receiver. |
| 1313 | 1318 |
| 1314 // Set the class field to the Context class. | 1319 // Set the class field to the Context class. |
| 1315 __ LoadObject(EBX, Class::ZoneHandle(Object::context_class())); | 1320 __ LoadObject(EBX, Class::ZoneHandle(Object::context_class())); |
| 1316 __ movl(Address(ECX, Context::class_offset()), EBX); | 1321 __ movl(Address(ECX, Context::class_offset()), EBX); |
| 1322 __ movl(Address(ECX, Context::tags_offset()), Immediate(0)); // Tags. |
| 1317 | 1323 |
| 1318 // Set number of variables field to 1 (for captured receiver). | 1324 // Set number of variables field to 1 (for captured receiver). |
| 1319 __ movl(Address(ECX, Context::num_variables_offset()), Immediate(1)); | 1325 __ movl(Address(ECX, Context::num_variables_offset()), Immediate(1)); |
| 1320 | 1326 |
| 1321 // Set isolate field to isolate of current context. | 1327 // Set isolate field to isolate of current context. |
| 1322 __ movl(EDX, FieldAddress(CTX, Context::isolate_offset())); | 1328 __ movl(EDX, FieldAddress(CTX, Context::isolate_offset())); |
| 1323 __ movl(Address(ECX, Context::isolate_offset()), EDX); | 1329 __ movl(Address(ECX, Context::isolate_offset()), EDX); |
| 1324 | 1330 |
| 1325 // Set the parent field to null. | 1331 // Set the parent field to null. |
| 1326 __ movl(Address(ECX, Context::parent_offset()), raw_null); | 1332 __ movl(Address(ECX, Context::parent_offset()), raw_null); |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1578 __ popl(EDX); | 1584 __ popl(EDX); |
| 1579 __ popl(ECX); | 1585 __ popl(ECX); |
| 1580 __ LeaveFrame(); | 1586 __ LeaveFrame(); |
| 1581 // Now call the dynamic function. | 1587 // Now call the dynamic function. |
| 1582 __ jmp(&StubCode::InlineCacheLabel()); | 1588 __ jmp(&StubCode::InlineCacheLabel()); |
| 1583 } | 1589 } |
| 1584 | 1590 |
| 1585 } // namespace dart | 1591 } // namespace dart |
| 1586 | 1592 |
| 1587 #endif // defined TARGET_ARCH_IA32 | 1593 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |